Home Manual Reference Source Test Repository

src/gaussjordan.js


export function __gaussjordan__ ( iszero, zero, isub, mul, div, swap ) {


	/**
	 * A is a m * (n + 1) matrix.
	 * Column n is the independent term column.
	 *
	 * @param  {matrix} A equations system
	 * @param  {const length} m number of equations
	 * @param  {const length} n number of variables
	 */
	var gaussjordan = function ( A, m, n ) {

		var r, c, j, k, Ar, Aj, f, t, iterations, rank, pivot;

		// for each row r
		// zero column c for all other rows
		// the pivot used is A[r][c]

		// If at the end of the procedure a line is composed
		// of zeroes except for the independent term
		// then the system is not solvable. The index of such
		// a line is at least the rank of the matrix

		iterations = Math.min( m, n );

		r = 0;

		columns : for ( c = 0 ; c < iterations ; ++c ) {

			Ar = A[r];
			pivot = Ar[c];

			// if we have a zero in A[r][c]
			// we need to swap row r with row
			// j such that A[j][c] is not zero
			// if this is not possible then we
			// decrease the rank of the matrix
			// and continue with the next
			// column

			if ( iszero( pivot ) ) {

				j = r;

				do {

					++j;

					if ( j === m ) {
						continue columns;
					}

				} while ( iszero( A[j][c] ) );

				swap( A, r, j );

				Ar = A[r];
				pivot = Ar[c];

			}

			for ( j = 0 ; j < r ; ++j ) {

				Aj = A[j];

				f = div( Aj[c], pivot );

				Aj[c] = zero();

				for ( k = c + 1 ; k <= n ; ++k ) {

					t = mul( f, Ar[k] );

					Aj[k] = isub( Aj[k], t );

				}

			}

			for ( j = r + 1 ; j < m ; ++j ) {

				Aj = A[j];

				f = div( Aj[c], pivot );

				Aj[c] = zero();

				for ( k = c + 1 ; k <= n ; ++k ) {

					t = mul( f, Ar[k] );

					Aj[k] = isub( Aj[k], t );

				}

			}

			++r;

		}

		return r;

	};

	return gaussjordan;

}