| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 | /*CC     ..................................................................CC        SUBROUTINE GELSCC        PURPOSEC           TO SOLVE A SYSTEM OF SIMULTANEOUS LINEAR EQUATIONS WITHC           SYMMETRIC COEFFICIENT MATRIX UPPER TRIANGULAR PART OF WHICHC           IS ASSUMED TO BE STORED COLUMNWISE.CC        USAGEC           CALL GELS(R,A,M,N,EPS,IER,AUX)CC        DESCRIPTION OF PARAMETERSC           R      - M BY N RIGHT HAND SIDE MATRIX.  (DESTROYED)C                    ON RETURN R CONTAINS THE SOLUTION OF THE EQUATIONS.C           A      - UPPER TRIANGULAR PART OF THE SYMMETRICC                    M BY M COEFFICIENT MATRIX.  (DESTROYED)C           M      - THE NUMBER OF EQUATIONS IN THE SYSTEM.C           N      - THE NUMBER OF RIGHT HAND SIDE VECTORS.C           EPS    - AN INPUT CONSTANT WHICH IS USED AS RELATIVEC                    TOLERANCE FOR TEST ON LOSS OF SIGNIFICANCE.C           IER    - RESULTING ERROR PARAMETER CODED AS FOLLOWSC                    IER=0  - NO ERROR,C                    IER=-1 - NO RESULT BECAUSE OF M LESS THAN 1 ORC                             PIVOT ELEMENT AT ANY ELIMINATION STEPC                             EQUAL TO 0,C                    IER=K  - WARNING DUE TO POSSIBLE LOSS OF SIGNIFI-C                             CANCE INDICATED AT ELIMINATION STEP K+1,C                             WHERE PIVOT ELEMENT WAS LESS THAN ORC                             EQUAL TO THE INTERNAL TOLERANCE EPS TIMESC                             ABSOLUTELY GREATEST MAIN DIAGONALC                             ELEMENT OF MATRIX A.C           AUX    - AN AUXILIARY STORAGE ARRAY WITH DIMENSION M-1.CC        REMARKSC           UPPER TRIANGULAR PART OF MATRIX A IS ASSUMED TO BE STOREDC           COLUMNWISE IN M*(M+1)/2 SUCCESSIVE STORAGE LOCATIONS, RIGHTC           HAND SIDE MATRIX R COLUMNWISE IN N*M SUCCESSIVE STORAGEC           LOCATIONS. ON RETURN SOLUTION MATRIX R IS STORED COLUMNWISEC           TOO.C           THE PROCEDURE GIVES RESULTS IF THE NUMBER OF EQUATIONS M ISC           GREATER THAN 0 AND PIVOT ELEMENTS AT ALL ELIMINATION STEPSC           ARE DIFFERENT FROM 0. HOWEVER WARNING IER=K - IF GIVEN -C           INDICATES POSSIBLE LOSS OF SIGNIFICANCE. IN CASE OF A WELLC           SCALED MATRIX A AND APPROPRIATE TOLERANCE EPS, IER=K MAY BEC           INTERPRETED THAT MATRIX A HAS THE RANK K. NO WARNING ISC           GIVEN IN CASE M=1.C           ERROR PARAMETER IER=-1 DOES NOT NECESSARILY MEAN THATC           MATRIX A IS SINGULAR, AS ONLY MAIN DIAGONAL ELEMENTSC           ARE USED AS PIVOT ELEMENTS. POSSIBLY SUBROUTINE GELG (WHICHC           WORKS WITH TOTAL PIVOTING) WOULD BE ABLE TO FIND A SOLUTION.CC        SUBROUTINES AND FUNCTION SUBPROGRAMS REQUIREDC           NONECC        METHODC           SOLUTION IS DONE BY MEANS OF GAUSS-ELIMINATION WITHC           PIVOTING IN MAIN DIAGONAL, IN ORDER TO PRESERVEC           SYMMETRY IN REMAINING COEFFICIENT MATRICES.CC     ..................................................................C*/#include <stdio.h>#define fabsl(x) ( (x) < 0.0L ? -(x) : (x) )int gels( A, R, M, EPS, AUX )long double A[],R[];int M;long double EPS;long double AUX[];{int I, J, K, L, IER;int II, LL, LLD, LR, LT, LST, LLST, LEND;long double tb, piv, tol, pivi;IER = 0;if( M <= 0 )	{fatal:	IER = -1;	goto done;	}/* SEARCH FOR GREATEST MAIN DIAGONAL ELEMENT *//*  Diagonal elements are at A(i,i) = 0, 2, 5, 9, 14, ... *  A(i,j) = A( i(i-1)/2 + j - 1 ) */piv = 0.0L;I = 0;J = 0;L = 0;for( K=1; K<=M; K++ )	{	L += K;	tb = fabsl( A[L-1] );	if( tb > piv )		{		piv = tb;		I = L;		J = K;		}	}tol = EPS * piv;/*C     MAIN DIAGONAL ELEMENT A(I)=A(J,J) IS FIRST PIVOT ELEMENT.C     PIV CONTAINS THE ABSOLUTE VALUE OF A(I).*//*     START ELIMINATION LOOP */LST = 0;LEND = M - 1;for( K=1; K<=M; K++ )	{/*     TEST ON USEFULNESS OF SYMMETRIC ALGORITHM */	if( piv <= 0.0L )	  {	    printf( "gels: piv <= 0 at K = %d\n", K );	    goto fatal;	  }	if( IER == 0 )		{		if( piv <= tol )			{			IER = K;/*			goto done;*/			}		}	LT = J - K;	LST += K;/*  PIVOT ROW REDUCTION AND ROW INTERCHANGE IN RIGHT HAND SIDE R */	pivi = 1.0L / A[I-1];	L = K;	LL = L + LT;	tb = pivi * R[LL-1];	R[LL-1] = R[L-1];	R[L-1] = tb;/* IS ELIMINATION TERMINATED */	if( K >= M )		break;/*C     ROW AND COLUMN INTERCHANGE AND PIVOT ROW REDUCTION IN MATRIX A.C     ELEMENTS OF PIVOT COLUMN ARE SAVED IN AUXILIARY VECTOR AUX.*/	LR = LST + (LT*(K+J-1))/2;	LL = LR;	L=LST;	for( II=K; II<=LEND; II++ )		{		L += II;		LL += 1;		if( L == LR )			{			A[LL-1] = A[LST-1];			tb = A[L-1];			goto lab13;			}		if( L > LR )			LL = L + LT;		tb = A[LL-1];		A[LL-1] = A[L-1];lab13:		AUX[II-1] = tb;		A[L-1] = pivi * tb;		}/* SAVE COLUMN INTERCHANGE INFORMATION */	A[LST-1] = LT;/* ELEMENT REDUCTION AND SEARCH FOR NEXT PIVOT */	piv = 0.0L;	LLST = LST;	LT = 0;	for( II=K; II<=LEND; II++ )		{		pivi = -AUX[II-1];		LL = LLST;		LT += 1;		for( LLD=II; LLD<=LEND; LLD++ )			{			LL += LLD;			L = LL + LT;			A[L-1] += pivi * A[LL-1];			}		LLST += II;		LR = LLST + LT;		tb =fabsl( A[LR-1] );		if( tb > piv )			{			piv = tb;			I = LR;			J = II + 1;			}		LR = K;		LL = LR + LT;		R[LL-1] += pivi * R[LR-1];		}	}/* END OF ELIMINATION LOOP *//* BACK SUBSTITUTION AND BACK INTERCHANGE */if( LEND <= 0 )	{	printf( "gels: LEND = %d\n", LEND );	if( LEND < 0 )		goto fatal;	goto done;	}II = M;for( I=2; I<=M; I++ )	{	LST -= II;	II -= 1;	L = A[LST-1] + 0.5L;	J = II;	tb = R[J-1];	LL = J;	K = LST;	for( LT=II; LT<=LEND; LT++ )		{		LL += 1;		K += LT;		tb -= A[K-1] * R[LL-1];		}	K = J + L;	R[J-1] = R[K-1];	R[K-1] = tb;	}done:if( IER )	printf( "gels error %d!\n", IER );return( IER );}
 |