program solvgv; { -> 96 } { pascal program to perform simultaneous solution by gauss-jordan elimination } { with multiple constant vectors } const maxr = 7; maxc = 7; type ary2s = array[1..maxr,1..maxc] of real; var dummy : char; a,y : ary2s; n,nvec : integer; first, error : boolean; determ : real; external procedure cls; external procedure revon; external procedure revoff; procedure get_data(var a: ary2s; var y: ary2s; var n,nvec: integer); { get values for n,nvec and arrays a,y } var i,j : integer; begin if not first then cls else first:=false; writeln; repeat write('How many equations? '); readln(n) until n1 then begin write('How many constant vectors? '); readln(nvec); for i:=1 to n do begin for j:=1 to n do begin write(j:3,': '); read(a[i,j]); if (j mod n+nvec)=0 then writeln end; if nvec>0 then begin for j:=1 to nvec do begin write(' C:'); read(y[i,j]) end; readln end end; { i-loop } writeln; write(' Matrix'); if nvec>0 then write(' Constants'); writeln; for i:=1 to n do begin for j:=1 to n do write(a[i,j]:7:4,' '); for j:=1 to nvec do write(':',y[i,j]:7:4); writeln end; { i-loop } writeln end { if n>1 } end; { procedure get_data } procedure write_data; { print out answers } var i,j : integer; begin if nvec>0 then begin writeln('Solution '); for i:=1 to n do begin for j:=1 to nvec do write(y[i,j]:9:5); writeln end end { if } else begin writeln(' Inverse'); for i:=1 to n do begin for j:=1 to n do write(a[i,j]:9:5); writeln end; writeln; write('Determinant is ',determ:10:5) end; { else } writeln end; { write_data } procedure gausjv (var b : ary2s; { square matrix of coefficients } var w : ary2s; { constant vector matrix } var determ : real; { the determinant } ncol : integer; { order of matrix } nv : integer; { number of constants } var error : boolean); { true if matrix is singular } { Gauss Jordan matrix inversion and solution } { B(n,n) coefficients matrix becomes inverse } { W(n,m) constant vector(s) become solution vector } { determ is the determinant } { error=1 if singular } { INDEX(n,3) } { NV is the number of vectors } label 99; var index : array[1..maxc,1..3] of integer; i,j,k,l, irow,icol, n,l1 : integer; pivot,hold, sum,ab, t,big : real; procedure swap(var a,b: real); var hold : real; begin hold:=a; a:=b; b:=hold end; { procedure swap } procedure gausj2; label 98; var i,j,k,l,l1 : integer; procedure gausj3; var l : integer; begin { procedure gausj3 } { 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 } end; { gausj3 } begin { procedure gausj2 } { actual start of gaussj } error:=false; n:=ncol; for i:=1 to n do index[i,3]:=0; determ:=1.0; for i:=1 to n do begin { search for the 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(chr(7),'ERROR: matrix is 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 { if } end; { j-loop } index[icol,3]:=index[icol,3]+1; index[i,1]:=irow; index[i,2]:=icol; gausj3; { further subdivision of gaussj } { 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; 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 { for l1 } end; { i-loop } 98: end; { gausj2 } begin { GAUS-JORDAN main program } gausj2; { first half of gaussj } 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(chr(7),'ERROR: matrix is singular'); error:=true; goto 99 { abort } end; 99: end; { procedure gaussj } begin { main program } first:=true; cls; writeln; revon; writeln('Simultaneous solution by Gauss-Jordan'); writeln('Multiple constant vectors, or matrix inverse'); revoff; repeat get_data(a,y,n,nvec); if n>1 then begin gausjv(a,y,determ,n,nvec,error); if not error then write_data; read(dummy) end until n<2 end.