|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 6144 (0x1800) Types: TextFile Names: »HILB.PAS«
└─⟦5e4548e7d⟧ Bits:30005778 Turbo Pascal v.3.01A (CP/M-86) └─ ⟦this⟧ »HILB.PAS«
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. «eof»