/* simeq_plus.c */ #include "simeq_plus.h" #include #include #include #include #undef abs #define abs(a) ((a)<0.0?(-(a)):(a)) void simeq(int n, double A[], double Y[], double X[]) { /* PURPOSE : SOLVE THE LINEAR SYSTEM OF EQUATIONS WITH REAL */ /* COEFFICIENTS [A] * |X| = |Y| */ /* */ /* INPUT : THE NUMBER OF EQUATIONS n */ /* THE REAL MATRIX A should be A[i][j] but A[i*n+j] */ /* THE REAL VECTOR Y */ /* OUTPUT : THE REAL VECTOR X */ /* */ /* METHOD : GAUSS-JORDAN ELIMINATION USING MAXIMUM ELEMENT */ /* FOR PIVOT. */ /* */ /* USAGE : simeq(n,A,X,Y); */ /* */ /* */ /* WRITTEN BY : JON SQUIRE , 28 MAY 1983 */ /* ORIGONAL DEC 1959 for IBM 650, TRANSLATED TO OTHER LANGUAGES */ /* e.g. FORTRAN converted to Ada converted to C */ double *B; /* [n][n+1] WORKING MATRIX */ int *ROW; /* ROW INTERCHANGE INDICIES */ int HOLD , I_PIVOT; /* PIVOT INDICIES */ double PIVOT; /* PIVOT ELEMENT VALUE */ double ABS_PIVOT; int i,j,k,m; B = (double *)calloc((n+1)*(n+1), sizeof(double)); ROW = (int *)calloc(n, sizeof(int)); m = n+1; /* BUILD WORKING DATA STRUCTURE */ for(i=0; i ABS_PIVOT){ I_PIVOT = i; PIVOT = B[ROW[i]*m+k]; ABS_PIVOT = abs ( PIVOT ); } } /* HAVE PIVOT, INTERCHANGE ROW POINTERS */ HOLD = ROW[k]; ROW[k] = ROW[I_PIVOT]; ROW[I_PIVOT] = HOLD; /* CHECK FOR NEAR SINGULAR */ if( ABS_PIVOT < 1.0E-25 ){ for(j=k+1; j ABS_PIVOT ){ I_PIVOT = i; PIVOT = B[ROW[i]*n+k]; ABS_PIVOT = abs(PIVOT); } } /* HAVE PIVOT, INTERCHANGE ROW POINTERS */ if(I_PIVOT != k){ HOLD = ROW[k]; ROW[k] = ROW[I_PIVOT]; ROW[I_PIVOT] = HOLD; D = - D; } /* CHECK FOR NEAR SINGULAR */ if(ABS_PIVOT < 1.0E-25){ free(B); free(ROW); return 0.0; } else { D = D * PIVOT; /* REDUCE ABOUT PIVOT */ for(j=k+1; j ABS_PIVOT ){ I_PIVOT = i ; J_PIVOT = j ; PIVOT = AA[ROW[i]*n+COL[j]] ; } } } if(abs(PIVOT) < 1.0E-25){ free(ROW); free(COL); free(TEMP); printf("MATRIX is SINGULAR !!! \n"); return; } HOLD = ROW[k]; ROW[k]= ROW[I_PIVOT]; ROW[I_PIVOT] = HOLD ; HOLD = COL[k]; COL[k]= COL[J_PIVOT]; COL[J_PIVOT] = HOLD ; /* REDUCE ABOUT PIVOT */ AA[ROW[k]*n+COL[k]] = 1.0 / PIVOT ; for (j=0; j