/* tsimeq.c solve simultaneous equations AX=Y threaded version */ /* Linux with glibc: * _REENTRANT to grab thread-safe libraries * _POSIX_SOURCE to get POSIX semantics */ #ifdef __linux__ # define _REENTRANT # define _POSIX_SOURCE # define _P __P #endif #include #include #include #undef abs #define abs(x) (((x)<0.0)?(-(x)):(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 : tsimeq(np,n,A,Y,X); A not modified */ /* tsimeqb(np,n,B,X) B=A with Y last column, changed*/ /* np is number of worker threads */ /* */ /* 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, Java, parallel */ /* modified to have simeqb */ #include "tsimeq.h" static int NP = 0; /* number of workers, not include master */ static int nb = 0; /* count to NP+1 to include master */ static pthread_cond_t go; static pthread_mutex_t bar; static double * BB; /* B global */ static int nn, mm; /* n, n+1 global */ static int *srow; /* NP+1 starting row for each thread */ static int *ROW; /* ROW INTERCHANGE INDICIES */ void barrier(void) { fflush(stdout); pthread_mutex_lock(&bar); nb++; if(nb == NP+1) /* includes master allowing release */ { nb = 0; pthread_cond_broadcast(&go); } else { pthread_cond_wait(&go, &bar); } pthread_mutex_unlock(&bar); } /* end barrier */ void * parallel(void * threadID) { long int id; int i, j, k; id = (long int)threadID; for(k=0; kn) NP=n; srow = (int *)malloc((NP+1)*sizeof(int)); /* starting row for each thread */ // set up row range for each thread part = n/NP; remain = n-part*NP; srow[0]=0; for(i=1; 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-64 ) { for(j=k+1; j