247 lines
6.0 KiB
Plaintext
247 lines
6.0 KiB
Plaintext
|
program HilbDemo87;
|
|||
|
{
|
|||
|
TURBO-87 DEMONSTRATION PROGRAM Version 1.00A
|
|||
|
|
|||
|
This program demonstrates the increased speed and precision
|
|||
|
of the TURBO-87 compiler:
|
|||
|
|
|||
|
--------------------------------------------------
|
|||
|
From: Pascal Programs for Scientists and Engineers
|
|||
|
|
|||
|
Alan R. Miller, Sybex
|
|||
|
n x n inverse hilbert matrix
|
|||
|
solution is 1 1 1 1 1
|
|||
|
double precision version
|
|||
|
--------------------------------------------------
|
|||
|
|
|||
|
The program performs simultaneous solution by Gauss-Jordan
|
|||
|
elimination.
|
|||
|
|
|||
|
INSTRUCTIONS
|
|||
|
1. Compile the program using the TURBO-87.COM compiler.
|
|||
|
2. Type Ctrl-C to interrupt the program.
|
|||
|
}
|
|||
|
|
|||
|
CONST
|
|||
|
maxr = 10;
|
|||
|
maxc = 10;
|
|||
|
|
|||
|
TYPE
|
|||
|
ary = ARRAY[1..maxr] OF real;
|
|||
|
arys = ARRAY[1..maxc] OF real;
|
|||
|
ary2s = ARRAY[1..maxr, 1..maxc] OF real;
|
|||
|
|
|||
|
VAR
|
|||
|
y : arys;
|
|||
|
coef : arys;
|
|||
|
a, b : ary2s;
|
|||
|
n, m, i, j : integer;
|
|||
|
error : boolean;
|
|||
|
|
|||
|
PROCEDURE gaussj
|
|||
|
(VAR b : ary2s; (* square matrix of coefficients *)
|
|||
|
y : arys; (* constant vector *)
|
|||
|
VAR coef : arys; (* solution vector *)
|
|||
|
ncol : integer; (* order of matrix *)
|
|||
|
VAR error: boolean); (* true if matrix singular *)
|
|||
|
|
|||
|
(* Gauss Jordan matrix inversion and solution *)
|
|||
|
(* Adapted from McCormick *)
|
|||
|
(* Feb 8, 81 *)
|
|||
|
(* B(N,N) coefficient matrix, becomes inverse *)
|
|||
|
(* Y(N) original constant vector *)
|
|||
|
(* W(N,M) constant vector(s) become solution vector *)
|
|||
|
(* DETERM is the determinant *)
|
|||
|
(* ERROR = 1 if singular *)
|
|||
|
(* INDEX(N,3) *)
|
|||
|
(* NV is number of constant vectors *)
|
|||
|
|
|||
|
LABEL
|
|||
|
99,98;
|
|||
|
|
|||
|
VAR
|
|||
|
w : ARRAY[1..maxc, 1..maxc] OF real;
|
|||
|
index: ARRAY[1..maxc, 1..3] OF integer;
|
|||
|
i, j, k, l, nv, irow, icol, n, l1 : integer;
|
|||
|
determ, pivot, hold, sum, t, ab, big: real;
|
|||
|
|
|||
|
PROCEDURE swap(VAR a, b: real);
|
|||
|
|
|||
|
VAR
|
|||
|
hold: real;
|
|||
|
|
|||
|
BEGIN (* swap *)
|
|||
|
hold := a;
|
|||
|
a := b;
|
|||
|
b := hold
|
|||
|
END (* procedure swap *);
|
|||
|
|
|||
|
|
|||
|
BEGIN (* Gauss-Jordan main program *)
|
|||
|
error := false;
|
|||
|
nv := 1 (* single constant vector *);
|
|||
|
n := ncol;
|
|||
|
FOR i := 1 TO n DO
|
|||
|
BEGIN
|
|||
|
w[i, 1] := y[i] (* copy constant vector *);
|
|||
|
index[i, 3] := 0
|
|||
|
END;
|
|||
|
determ := 1.0;
|
|||
|
FOR i := 1 TO n DO
|
|||
|
BEGIN
|
|||
|
(* search for largest element *)
|
|||
|
big := 0.0;
|
|||
|
FOR j := 1 TO n DO
|
|||
|
BEGIN
|
|||
|
IF index[j, 3] <> 1 THEN
|
|||
|
BEGIN
|
|||
|
FOR k := 1 TO n DO
|
|||
|
BEGIN
|
|||
|
IF index[k, 3] > 1 THEN
|
|||
|
BEGIN
|
|||
|
writeln(' ERROR: matrix singular');
|
|||
|
error := true;
|
|||
|
GOTO 98 (* abort *)
|
|||
|
END;
|
|||
|
IF index[k, 3] < 1 THEN
|
|||
|
IF abs(b[j, k]) > big THEN
|
|||
|
BEGIN
|
|||
|
irow := j;
|
|||
|
icol := k;
|
|||
|
big := abs(b[j, k])
|
|||
|
END
|
|||
|
END (* k loop *)
|
|||
|
END
|
|||
|
END (* j loop *);
|
|||
|
index[icol, 3] := index[icol, 3] + 1;
|
|||
|
index[i, 1] := irow;
|
|||
|
index[i, 2] := icol;
|
|||
|
|
|||
|
(* interchange rows to put pivot on diagonal *)
|
|||
|
IF irow <> icol THEN
|
|||
|
BEGIN
|
|||
|
determ := - determ;
|
|||
|
FOR l := 1 TO n DO
|
|||
|
swap(b[irow, l], b[icol, l]);
|
|||
|
IF nv > 0 THEN
|
|||
|
FOR l := 1 TO nv DO
|
|||
|
swap(w[irow, l], w[icol, l])
|
|||
|
END; (* if irow <> icol *)
|
|||
|
|
|||
|
(* divide pivot row by pivot column *)
|
|||
|
pivot := b[icol, icol];
|
|||
|
determ := determ * pivot;
|
|||
|
b[icol, icol] := 1.0;
|
|||
|
FOR l := 1 TO n DO
|
|||
|
b[icol, l] := b[icol, l] / pivot;
|
|||
|
IF nv > 0 THEN
|
|||
|
FOR l := 1 TO nv DO
|
|||
|
w[icol, l] := w[icol, l] / pivot;
|
|||
|
(* reduce nonpivot rows *)
|
|||
|
FOR l1 := 1 TO n DO
|
|||
|
BEGIN
|
|||
|
IF l1 <> icol THEN
|
|||
|
BEGIN
|
|||
|
t := b[l1, icol];
|
|||
|
b[l1, icol] := 0.0;
|
|||
|
FOR l := 1 TO n DO
|
|||
|
b[l1, l] := b[l1, l] - b[icol, l] * t;
|
|||
|
IF nv > 0 THEN
|
|||
|
FOR l := 1 TO nv DO
|
|||
|
w[l1, l] := w[l1, l] - w[icol, l] * t;
|
|||
|
END (* IF l1 <> icol *)
|
|||
|
END
|
|||
|
END (* i loop *);
|
|||
|
98:
|
|||
|
|
|||
|
IF error THEN GOTO 99;
|
|||
|
(* interchange columns *)
|
|||
|
FOR i := 1 TO n DO
|
|||
|
BEGIN
|
|||
|
l := n - i + 1;
|
|||
|
IF index[l, 1] <> index[l, 2] THEN
|
|||
|
BEGIN
|
|||
|
irow := index[l, 1];
|
|||
|
icol := index[l, 2];
|
|||
|
FOR k := 1 TO n DO
|
|||
|
swap(b[k, irow], b[k, icol])
|
|||
|
END (* if index *)
|
|||
|
END (* i loop *);
|
|||
|
FOR k := 1 TO n DO
|
|||
|
IF index[k, 3] <> 1 THEN
|
|||
|
BEGIN
|
|||
|
writeln(' ERROR: matrix singular');
|
|||
|
error := true;
|
|||
|
GOTO 99 (* abort *)
|
|||
|
END;
|
|||
|
FOR i := 1 TO n DO
|
|||
|
coef[i] := w[i, 1];
|
|||
|
99:
|
|||
|
END (* procedure gaussj *);
|
|||
|
|
|||
|
|
|||
|
PROCEDURE get_data(VAR a : ary2s;
|
|||
|
VAR y : arys;
|
|||
|
VAR n, m : integer);
|
|||
|
|
|||
|
(* setup n-by-n hilbert matrix *)
|
|||
|
|
|||
|
VAR
|
|||
|
i, j : integer;
|
|||
|
|
|||
|
BEGIN
|
|||
|
FOR i := 1 TO n DO
|
|||
|
BEGIN
|
|||
|
a[n,i] := 1.0/(n + i - 1);
|
|||
|
a[i,n] := a[n,i]
|
|||
|
END;
|
|||
|
a[n,n] := 1.0/(2*n -1);
|
|||
|
FOR i := 1 TO n DO
|
|||
|
BEGIN
|
|||
|
y[i] := 0.0;
|
|||
|
FOR j := 1 TO n DO
|
|||
|
y[i] := y[i] + a[i,j]
|
|||
|
END;
|
|||
|
writeln;
|
|||
|
IF n < 7 THEN
|
|||
|
BEGIN
|
|||
|
FOR i:= 1 TO n DO
|
|||
|
BEGIN
|
|||
|
FOR j:= 1 TO m DO
|
|||
|
write( a[i,j] :7:5, ' ');
|
|||
|
writeln( ' : ', y[i] :7:5)
|
|||
|
END;
|
|||
|
writeln
|
|||
|
END (* if n<7 *)
|
|||
|
END (* procedure get_data *);
|
|||
|
|
|||
|
PROCEDURE write_data;
|
|||
|
|
|||
|
(* print out the answers *)
|
|||
|
|
|||
|
VAR
|
|||
|
i : integer;
|
|||
|
|
|||
|
BEGIN
|
|||
|
FOR i := 1 TO m DO
|
|||
|
write( coef[i] :13:9);
|
|||
|
writeln;
|
|||
|
END (* write_data *);
|
|||
|
|
|||
|
|
|||
|
BEGIN (* main program *)
|
|||
|
a[1,1] := 1.0;
|
|||
|
n := 2;
|
|||
|
m := n;
|
|||
|
REPEAT
|
|||
|
get_data (a, y, n, m);
|
|||
|
FOR i := 1 TO n DO
|
|||
|
FOR j := 1 TO n DO
|
|||
|
b[i,j] := a[i,j] (* setup work array *);
|
|||
|
gaussj (b, y, coef, n, error);
|
|||
|
IF not error THEN write_data;
|
|||
|
n := n+1;
|
|||
|
m := n
|
|||
|
UNTIL n > maxr;
|
|||
|
END.
|
|||
|
|