/* mpf_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 #include "mpf_tsimeq.h" /* 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 : mpf_tsimeq(np,n,A,Y,X); A not modified */ /* mpf_tsimeqb(np,n,B,X) B=A with Y last column, */ /* 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 and multiple precision */ #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 mpf_t * 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; mpf_t T; id = (long int)threadID; mpf_init(T); 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; i0) { I_PIVOT = i; mpf_set(PIVOT, B[ROW[i]*m+k]); mpf_abs(ABS_PIVOT, PIVOT); } } /* HAVE PIVOT, INTERCHANGE ROW POINTERS */ HOLD = ROW[k]; ROW[k] = ROW[I_PIVOT]; ROW[I_PIVOT] = HOLD; /* CHECK FOR NEAR SINGULAR */ if(mpf_cmp(small, ABS_PIVOT)>0 ) { for(j=k+1; j