DEMO1-87.PAS 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. program HilbDemo87;
  2. {
  3. TURBO-87 DEMONSTRATION PROGRAM Version 1.00A
  4. This program demonstrates the increased speed and precision
  5. of the TURBO-87 compiler:
  6. --------------------------------------------------
  7. From: Pascal Programs for Scientists and Engineers
  8. Alan R. Miller, Sybex
  9. n x n inverse hilbert matrix
  10. solution is 1 1 1 1 1
  11. double precision version
  12. --------------------------------------------------
  13. The program performs simultaneous solution by Gauss-Jordan
  14. elimination.
  15. INSTRUCTIONS
  16. 1. Compile the program using the TURBO-87.COM compiler.
  17. 2. Type Ctrl-C to interrupt the program.
  18. }
  19. CONST
  20. maxr = 10;
  21. maxc = 10;
  22. TYPE
  23. ary = ARRAY[1..maxr] OF real;
  24. arys = ARRAY[1..maxc] OF real;
  25. ary2s = ARRAY[1..maxr, 1..maxc] OF real;
  26. VAR
  27. y : arys;
  28. coef : arys;
  29. a, b : ary2s;
  30. n, m, i, j : integer;
  31. error : boolean;
  32. PROCEDURE gaussj
  33. (VAR b : ary2s; (* square matrix of coefficients *)
  34. y : arys; (* constant vector *)
  35. VAR coef : arys; (* solution vector *)
  36. ncol : integer; (* order of matrix *)
  37. VAR error: boolean); (* true if matrix singular *)
  38. (* Gauss Jordan matrix inversion and solution *)
  39. (* Adapted from McCormick *)
  40. (* Feb 8, 81 *)
  41. (* B(N,N) coefficient matrix, becomes inverse *)
  42. (* Y(N) original constant vector *)
  43. (* W(N,M) constant vector(s) become solution vector *)
  44. (* DETERM is the determinant *)
  45. (* ERROR = 1 if singular *)
  46. (* INDEX(N,3) *)
  47. (* NV is number of constant vectors *)
  48. LABEL
  49. 99,98;
  50. VAR
  51. w : ARRAY[1..maxc, 1..maxc] OF real;
  52. index: ARRAY[1..maxc, 1..3] OF integer;
  53. i, j, k, l, nv, irow, icol, n, l1 : integer;
  54. determ, pivot, hold, sum, t, ab, big: real;
  55. PROCEDURE swap(VAR a, b: real);
  56. VAR
  57. hold: real;
  58. BEGIN (* swap *)
  59. hold := a;
  60. a := b;
  61. b := hold
  62. END (* procedure swap *);
  63. BEGIN (* Gauss-Jordan main program *)
  64. error := false;
  65. nv := 1 (* single constant vector *);
  66. n := ncol;
  67. FOR i := 1 TO n DO
  68. BEGIN
  69. w[i, 1] := y[i] (* copy constant vector *);
  70. index[i, 3] := 0
  71. END;
  72. determ := 1.0;
  73. FOR i := 1 TO n DO
  74. BEGIN
  75. (* search for largest element *)
  76. big := 0.0;
  77. FOR j := 1 TO n DO
  78. BEGIN
  79. IF index[j, 3] <> 1 THEN
  80. BEGIN
  81. FOR k := 1 TO n DO
  82. BEGIN
  83. IF index[k, 3] > 1 THEN
  84. BEGIN
  85. writeln(' ERROR: matrix singular');
  86. error := true;
  87. GOTO 98 (* abort *)
  88. END;
  89. IF index[k, 3] < 1 THEN
  90. IF abs(b[j, k]) > big THEN
  91. BEGIN
  92. irow := j;
  93. icol := k;
  94. big := abs(b[j, k])
  95. END
  96. END (* k loop *)
  97. END
  98. END (* j loop *);
  99. index[icol, 3] := index[icol, 3] + 1;
  100. index[i, 1] := irow;
  101. index[i, 2] := icol;
  102. (* interchange rows to put pivot on diagonal *)
  103. IF irow <> icol THEN
  104. BEGIN
  105. determ := - determ;
  106. FOR l := 1 TO n DO
  107. swap(b[irow, l], b[icol, l]);
  108. IF nv > 0 THEN
  109. FOR l := 1 TO nv DO
  110. swap(w[irow, l], w[icol, l])
  111. END; (* if irow <> icol *)
  112. (* divide pivot row by pivot column *)
  113. pivot := b[icol, icol];
  114. determ := determ * pivot;
  115. b[icol, icol] := 1.0;
  116. FOR l := 1 TO n DO
  117. b[icol, l] := b[icol, l] / pivot;
  118. IF nv > 0 THEN
  119. FOR l := 1 TO nv DO
  120. w[icol, l] := w[icol, l] / pivot;
  121. (* reduce nonpivot rows *)
  122. FOR l1 := 1 TO n DO
  123. BEGIN
  124. IF l1 <> icol THEN
  125. BEGIN
  126. t := b[l1, icol];
  127. b[l1, icol] := 0.0;
  128. FOR l := 1 TO n DO
  129. b[l1, l] := b[l1, l] - b[icol, l] * t;
  130. IF nv > 0 THEN
  131. FOR l := 1 TO nv DO
  132. w[l1, l] := w[l1, l] - w[icol, l] * t;
  133. END (* IF l1 <> icol *)
  134. END
  135. END (* i loop *);
  136. 98:
  137. IF error THEN GOTO 99;
  138. (* interchange columns *)
  139. FOR i := 1 TO n DO
  140. BEGIN
  141. l := n - i + 1;
  142. IF index[l, 1] <> index[l, 2] THEN
  143. BEGIN
  144. irow := index[l, 1];
  145. icol := index[l, 2];
  146. FOR k := 1 TO n DO
  147. swap(b[k, irow], b[k, icol])
  148. END (* if index *)
  149. END (* i loop *);
  150. FOR k := 1 TO n DO
  151. IF index[k, 3] <> 1 THEN
  152. BEGIN
  153. writeln(' ERROR: matrix singular');
  154. error := true;
  155. GOTO 99 (* abort *)
  156. END;
  157. FOR i := 1 TO n DO
  158. coef[i] := w[i, 1];
  159. 99:
  160. END (* procedure gaussj *);
  161. PROCEDURE get_data(VAR a : ary2s;
  162. VAR y : arys;
  163. VAR n, m : integer);
  164. (* setup n-by-n hilbert matrix *)
  165. VAR
  166. i, j : integer;
  167. BEGIN
  168. FOR i := 1 TO n DO
  169. BEGIN
  170. a[n,i] := 1.0/(n + i - 1);
  171. a[i,n] := a[n,i]
  172. END;
  173. a[n,n] := 1.0/(2*n -1);
  174. FOR i := 1 TO n DO
  175. BEGIN
  176. y[i] := 0.0;
  177. FOR j := 1 TO n DO
  178. y[i] := y[i] + a[i,j]
  179. END;
  180. writeln;
  181. IF n < 7 THEN
  182. BEGIN
  183. FOR i:= 1 TO n DO
  184. BEGIN
  185. FOR j:= 1 TO m DO
  186. write( a[i,j] :7:5, ' ');
  187. writeln( ' : ', y[i] :7:5)
  188. END;
  189. writeln
  190. END (* if n<7 *)
  191. END (* procedure get_data *);
  192. PROCEDURE write_data;
  193. (* print out the answers *)
  194. VAR
  195. i : integer;
  196. BEGIN
  197. FOR i := 1 TO m DO
  198. write( coef[i] :13:9);
  199. writeln;
  200. END (* write_data *);
  201. BEGIN (* main program *)
  202. a[1,1] := 1.0;
  203. n := 2;
  204. m := n;
  205. REPEAT
  206. get_data (a, y, n, m);
  207. FOR i := 1 TO n DO
  208. FOR j := 1 TO n DO
  209. b[i,j] := a[i,j] (* setup work array *);
  210. gaussj (b, y, coef, n, error);
  211. IF not error THEN write_data;
  212. n := n+1;
  213. m := n
  214. UNTIL n > maxr;
  215. END.
  216.