Forward Substitution (Row-major)

// import visualization libraries {
const { Array2DTracer, Layout, LogTracer, Tracer, VerticalLayout, HorizonLayout } = require( 'algorithm-visualizer' );
// }

// define tracer variables {
const matrixTracer = new Array2DTracer( 'L x = b (row-major)' );
const logTracer = new LogTracer( 'Console' );
Layout.setRoot( new VerticalLayout( [ matrixTracer, logTracer ] ) );
// }

const random_range = 3;
const N = 8;
// initialization {
const matrix = [];
for ( let i = 0; i < N; ++i )
{
    matrix.push( [] );
    for ( let j = 0; j <= i; ++j ) matrix[ i ].push( Math.random() * ( 2 * random_range ) - random_range );
    for ( let j = i + 1; j < N; ++j ) matrix[ i ].push( 0 );
    while ( Math.abs( matrix[ i ][ i ] ) < 1e-6 ) matrix[ i ][ i ] = Math.random() * ( 2 * random_range ) - random_range;
    matrix[ i ].push( 'x[' + i + ']:' );
    matrix[ i ].push( 'x' + i );
    matrix[ i ].push( 'b[' + i + ']:' );
    matrix[ i ].push( Math.random() * ( 2 * random_range ) - random_range );
}
// }

// visualization {
matrixTracer.set( matrix );
Tracer.delay();
// }

for ( let i = 0; i < N; ++i )
{
    matrix[ i ][ N + 1 ] = matrix[ i ][ N + 3 ];
    // visualization {
    logTracer.println( 'Dealing with Row ' + i );
    let formula = 'x[' + i + '] = ( b[' + i + ']';
    logTracer.println( formula );
    matrixTracer.select( i, N + 3 );
    matrixTracer.patch( i, N + 1, matrix[ i ][ N + 1 ] );
    Tracer.delay();
    matrixTracer.deselect( i, N + 3 );
    matrixTracer.depatch( i, N + 1 );
    // }
    for ( let j = 0; j < i; ++j )
    {
        matrix[ i ][ N + 1 ] -= matrix[ i ][ j ] * matrix[ j ][ N + 1 ];
        // visualization {
        formula += ' - L[' + i + '][' + j + '] x[' + j + ']';
        logTracer.println( formula );
        matrixTracer.select( i, j );
        matrixTracer.select( j, N + 1 );
        matrixTracer.patch( i, N + 1, matrix[ i ][ N + 1 ] );
        Tracer.delay();
        matrixTracer.deselect( i, j );
        matrixTracer.deselect( j, N + 1 );
        matrixTracer.depatch( i, N + 1 );
        // }
    }
    matrix[ i ][ N + 1 ] /= matrix[ i ][ i ];
    // visualization {
    formula += ' ) / L[' + i + '][' + i + ']';
    logTracer.println( formula );
    matrixTracer.select( i, i );
    matrixTracer.patch( i, N + 1, matrix[ i ][ N + 1 ] );
    logTracer.println( 'x[' + i + '] = ' + matrix[ i ][ N + 1 ] );
    Tracer.delay();
    matrixTracer.deselect( i, i );
    matrixTracer.depatch( i, N + 1 );
    // }
}