gelsl.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. C
  3. C ..................................................................
  4. C
  5. C SUBROUTINE GELS
  6. C
  7. C PURPOSE
  8. C TO SOLVE A SYSTEM OF SIMULTANEOUS LINEAR EQUATIONS WITH
  9. C SYMMETRIC COEFFICIENT MATRIX UPPER TRIANGULAR PART OF WHICH
  10. C IS ASSUMED TO BE STORED COLUMNWISE.
  11. C
  12. C USAGE
  13. C CALL GELS(R,A,M,N,EPS,IER,AUX)
  14. C
  15. C DESCRIPTION OF PARAMETERS
  16. C R - M BY N RIGHT HAND SIDE MATRIX. (DESTROYED)
  17. C ON RETURN R CONTAINS THE SOLUTION OF THE EQUATIONS.
  18. C A - UPPER TRIANGULAR PART OF THE SYMMETRIC
  19. C M BY M COEFFICIENT MATRIX. (DESTROYED)
  20. C M - THE NUMBER OF EQUATIONS IN THE SYSTEM.
  21. C N - THE NUMBER OF RIGHT HAND SIDE VECTORS.
  22. C EPS - AN INPUT CONSTANT WHICH IS USED AS RELATIVE
  23. C TOLERANCE FOR TEST ON LOSS OF SIGNIFICANCE.
  24. C IER - RESULTING ERROR PARAMETER CODED AS FOLLOWS
  25. C IER=0 - NO ERROR,
  26. C IER=-1 - NO RESULT BECAUSE OF M LESS THAN 1 OR
  27. C PIVOT ELEMENT AT ANY ELIMINATION STEP
  28. C EQUAL TO 0,
  29. C IER=K - WARNING DUE TO POSSIBLE LOSS OF SIGNIFI-
  30. C CANCE INDICATED AT ELIMINATION STEP K+1,
  31. C WHERE PIVOT ELEMENT WAS LESS THAN OR
  32. C EQUAL TO THE INTERNAL TOLERANCE EPS TIMES
  33. C ABSOLUTELY GREATEST MAIN DIAGONAL
  34. C ELEMENT OF MATRIX A.
  35. C AUX - AN AUXILIARY STORAGE ARRAY WITH DIMENSION M-1.
  36. C
  37. C REMARKS
  38. C UPPER TRIANGULAR PART OF MATRIX A IS ASSUMED TO BE STORED
  39. C COLUMNWISE IN M*(M+1)/2 SUCCESSIVE STORAGE LOCATIONS, RIGHT
  40. C HAND SIDE MATRIX R COLUMNWISE IN N*M SUCCESSIVE STORAGE
  41. C LOCATIONS. ON RETURN SOLUTION MATRIX R IS STORED COLUMNWISE
  42. C TOO.
  43. C THE PROCEDURE GIVES RESULTS IF THE NUMBER OF EQUATIONS M IS
  44. C GREATER THAN 0 AND PIVOT ELEMENTS AT ALL ELIMINATION STEPS
  45. C ARE DIFFERENT FROM 0. HOWEVER WARNING IER=K - IF GIVEN -
  46. C INDICATES POSSIBLE LOSS OF SIGNIFICANCE. IN CASE OF A WELL
  47. C SCALED MATRIX A AND APPROPRIATE TOLERANCE EPS, IER=K MAY BE
  48. C INTERPRETED THAT MATRIX A HAS THE RANK K. NO WARNING IS
  49. C GIVEN IN CASE M=1.
  50. C ERROR PARAMETER IER=-1 DOES NOT NECESSARILY MEAN THAT
  51. C MATRIX A IS SINGULAR, AS ONLY MAIN DIAGONAL ELEMENTS
  52. C ARE USED AS PIVOT ELEMENTS. POSSIBLY SUBROUTINE GELG (WHICH
  53. C WORKS WITH TOTAL PIVOTING) WOULD BE ABLE TO FIND A SOLUTION.
  54. C
  55. C SUBROUTINES AND FUNCTION SUBPROGRAMS REQUIRED
  56. C NONE
  57. C
  58. C METHOD
  59. C SOLUTION IS DONE BY MEANS OF GAUSS-ELIMINATION WITH
  60. C PIVOTING IN MAIN DIAGONAL, IN ORDER TO PRESERVE
  61. C SYMMETRY IN REMAINING COEFFICIENT MATRICES.
  62. C
  63. C ..................................................................
  64. C
  65. */
  66. #include <stdio.h>
  67. #define fabsl(x) ( (x) < 0.0L ? -(x) : (x) )
  68. int gels( A, R, M, EPS, AUX )
  69. long double A[],R[];
  70. int M;
  71. long double EPS;
  72. long double AUX[];
  73. {
  74. int I, J, K, L, IER;
  75. int II, LL, LLD, LR, LT, LST, LLST, LEND;
  76. long double tb, piv, tol, pivi;
  77. IER = 0;
  78. if( M <= 0 )
  79. {
  80. fatal:
  81. IER = -1;
  82. goto done;
  83. }
  84. /* SEARCH FOR GREATEST MAIN DIAGONAL ELEMENT */
  85. /* Diagonal elements are at A(i,i) = 0, 2, 5, 9, 14, ...
  86. * A(i,j) = A( i(i-1)/2 + j - 1 )
  87. */
  88. piv = 0.0L;
  89. I = 0;
  90. J = 0;
  91. L = 0;
  92. for( K=1; K<=M; K++ )
  93. {
  94. L += K;
  95. tb = fabsl( A[L-1] );
  96. if( tb > piv )
  97. {
  98. piv = tb;
  99. I = L;
  100. J = K;
  101. }
  102. }
  103. tol = EPS * piv;
  104. /*
  105. C MAIN DIAGONAL ELEMENT A(I)=A(J,J) IS FIRST PIVOT ELEMENT.
  106. C PIV CONTAINS THE ABSOLUTE VALUE OF A(I).
  107. */
  108. /* START ELIMINATION LOOP */
  109. LST = 0;
  110. LEND = M - 1;
  111. for( K=1; K<=M; K++ )
  112. {
  113. /* TEST ON USEFULNESS OF SYMMETRIC ALGORITHM */
  114. if( piv <= 0.0L )
  115. {
  116. printf( "gels: piv <= 0 at K = %d\n", K );
  117. goto fatal;
  118. }
  119. if( IER == 0 )
  120. {
  121. if( piv <= tol )
  122. {
  123. IER = K;
  124. /*
  125. goto done;
  126. */
  127. }
  128. }
  129. LT = J - K;
  130. LST += K;
  131. /* PIVOT ROW REDUCTION AND ROW INTERCHANGE IN RIGHT HAND SIDE R */
  132. pivi = 1.0L / A[I-1];
  133. L = K;
  134. LL = L + LT;
  135. tb = pivi * R[LL-1];
  136. R[LL-1] = R[L-1];
  137. R[L-1] = tb;
  138. /* IS ELIMINATION TERMINATED */
  139. if( K >= M )
  140. break;
  141. /*
  142. C ROW AND COLUMN INTERCHANGE AND PIVOT ROW REDUCTION IN MATRIX A.
  143. C ELEMENTS OF PIVOT COLUMN ARE SAVED IN AUXILIARY VECTOR AUX.
  144. */
  145. LR = LST + (LT*(K+J-1))/2;
  146. LL = LR;
  147. L=LST;
  148. for( II=K; II<=LEND; II++ )
  149. {
  150. L += II;
  151. LL += 1;
  152. if( L == LR )
  153. {
  154. A[LL-1] = A[LST-1];
  155. tb = A[L-1];
  156. goto lab13;
  157. }
  158. if( L > LR )
  159. LL = L + LT;
  160. tb = A[LL-1];
  161. A[LL-1] = A[L-1];
  162. lab13:
  163. AUX[II-1] = tb;
  164. A[L-1] = pivi * tb;
  165. }
  166. /* SAVE COLUMN INTERCHANGE INFORMATION */
  167. A[LST-1] = LT;
  168. /* ELEMENT REDUCTION AND SEARCH FOR NEXT PIVOT */
  169. piv = 0.0L;
  170. LLST = LST;
  171. LT = 0;
  172. for( II=K; II<=LEND; II++ )
  173. {
  174. pivi = -AUX[II-1];
  175. LL = LLST;
  176. LT += 1;
  177. for( LLD=II; LLD<=LEND; LLD++ )
  178. {
  179. LL += LLD;
  180. L = LL + LT;
  181. A[L-1] += pivi * A[LL-1];
  182. }
  183. LLST += II;
  184. LR = LLST + LT;
  185. tb =fabsl( A[LR-1] );
  186. if( tb > piv )
  187. {
  188. piv = tb;
  189. I = LR;
  190. J = II + 1;
  191. }
  192. LR = K;
  193. LL = LR + LT;
  194. R[LL-1] += pivi * R[LR-1];
  195. }
  196. }
  197. /* END OF ELIMINATION LOOP */
  198. /* BACK SUBSTITUTION AND BACK INTERCHANGE */
  199. if( LEND <= 0 )
  200. {
  201. printf( "gels: LEND = %d\n", LEND );
  202. if( LEND < 0 )
  203. goto fatal;
  204. goto done;
  205. }
  206. II = M;
  207. for( I=2; I<=M; I++ )
  208. {
  209. LST -= II;
  210. II -= 1;
  211. L = A[LST-1] + 0.5L;
  212. J = II;
  213. tb = R[J-1];
  214. LL = J;
  215. K = LST;
  216. for( LT=II; LT<=LEND; LT++ )
  217. {
  218. LL += 1;
  219. K += LT;
  220. tb -= A[K-1] * R[LL-1];
  221. }
  222. K = J + L;
  223. R[J-1] = R[K-1];
  224. R[K-1] = tb;
  225. }
  226. done:
  227. if( IER )
  228. printf( "gels error %d!\n", IER );
  229. return( IER );
  230. }