// calculates the inverse of the matrix M outputs to M_1 // int inverse( GLU_complex M_1[ NCNC ] , const GLU_complex M[ NCNC ] ) { #if (defined HAVE_LAPACKE_H) const int n = NC , lda = NC ; int ipiv[ NC + 1 ] ; memcpy( M_1 , M , NCNC * sizeof( GLU_complex ) ) ; int info = LAPACKE_zgetrf( LAPACK_ROW_MAJOR , n , n , M_1 , lda , ipiv ) ; info = LAPACKE_zgetri( LAPACK_ROW_MAJOR , n , M_1 , lda, ipiv ) ; return info ; #elif (defined CLASSICAL_ADJOINT_INV) // define the adjunct // GLU_complex adjunct[ NCNC ] GLUalign ; register GLU_complex deter = cofactor_transpose( adjunct , M ) ; // here we worry about numerical stability // if( cabs( deter ) < NC * PREC_TOL ) { fprintf( stderr , "[INVERSE] Matrix is singular !!! " "deter=%1.14e %1.14e \n" , creal( deter ) , cimag( deter ) ) ; write_matrix( M ) ; return GLU_FAILURE ; } // obtain inverse of M from 1/( detM )*adj( M ) // size_t i ; deter = 1.0 / deter ; for( i = 0 ; i < NCNC ; i++ ) { M_1[i] = adjunct[i] * deter ; } return GLU_SUCCESS ; #else #if NC == 2 // use the identity, should warn for singular matrices const double complex INV_detM = 1.0 / ( det( M ) ) ; M_1[ 0 ] = M[ 3 ] * INV_detM ; M_1[ 1 ] = -M[ 1 ] * INV_detM ; M_1[ 2 ] = -M[ 2 ] * INV_detM ; M_1[ 3 ] = M[ 0 ] * INV_detM ; return GLU_SUCCESS ; #else return gauss_jordan( M_1 , M ) ; #endif #endif }
LinearEquation* run_gaussj(LinearEquation *leq) { gauss_jordan(leq->A, leq->n, leq->b, leq->x); return leq; }