#include "NumMeth.h" // ge - Function to perform Gaussian elimination to solve A*x = b // using scaled column pivoting // Inputs // A - Matrix A (N by N) // b - Vector b (N by 1) // Outputs // x - Vector x (N by 1) // determ - Determinant of matrix A (return value) double ge(Matrix A, Matrix b, Matrix& x) { int N = A.nRow(); assert( N == A.nCol() && N == b.nRow() && N == x.nRow() ); int i, j, k; Matrix scale(N); // Scale factor int *index; index = new int [N+1]; // Row index list //* Set scale factor, scale(i) = max( |A(i,j)| ), for each row for( i=1; i<=N; i++ ) { index[i] = i; // Initialize row index list double scaleMax = 0.0; for( j=1; j<=N; j++ ) scaleMax = (scaleMax > fabs(A(i,j))) ? scaleMax : fabs(A(i,j)); scale(i) = scaleMax; } //* Loop over rows k = 1, ..., (N-1) int signDet = 1; for( k=1; k<=(N-1); k++ ) { //* Select pivot row from max( |A(j,k)/s(j)| ) double ratiomax = 0.0; int jPivot = k; for( i=k; i<=N; i++ ) { double ratio = fabs(A(index[i],k))/scale(index[i]); if( ratio > ratiomax ) { jPivot = i; ratiomax = ratio; } } //* Perform pivoting using row index list int indexJ = index[k]; if( jPivot != k ) { // Pivot indexJ = index[jPivot]; index[jPivot] = index[k]; // Swap index jPivot and k index[k] = indexJ; signDet *= -1; // Flip sign of determinant } //* Perform forward elimination for( i=k+1; i<=N; i++ ) { double coeff = A(index[i],k)/A(indexJ,k); for( j=k+1; j<=N; j++ ) A(index[i],j) -= coeff*A(indexJ,j); A(index[i],k) = coeff; b(index[i]) -= A(index[i],k)*b(indexJ); } } //* Compute determinant as product of diagonal elements double determ = signDet; // Sign of determinant for( i=1; i<=N; i++ ) determ *= A(index[i],i); //* Perform backsubstitution x(N) = b(index[N])/A(index[N],N); for( i=N-1; i>=1; i-- ) { double sum = b(index[i]); for( j=i+1; j<=N; j++ ) sum -= A(index[i],j)*x(j); x(i) = sum/A(index[i],i); } delete [] index; // Release allocated memory return( determ ); }