home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / PASCAL / PAS_ENG.ZIP / SOLVGV.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1985-04-03  |  5.4 KB  |  273 lines

  1. program solvgv;        { -> 96 }
  2. { pascal program to perform simultaneous solution by gauss-jordan elimination }
  3. { with multiple constant vectors }
  4.  
  5. const    maxr    = 7;
  6.     maxc    = 7;
  7.  
  8. type    ary2s    = array[1..maxr,1..maxc] of real;
  9.  
  10. var    dummy    : char;
  11.     a,y    : ary2s;
  12.     n,nvec    : integer;
  13.     first,
  14.     error    : boolean;
  15.     determ    : real;
  16.  
  17. external procedure cls;
  18. external procedure revon;
  19. external procedure revoff;
  20.  
  21. procedure get_data(var a: ary2s;
  22.            var y: ary2s;
  23.            var n,nvec: integer);
  24. { get values for n,nvec and arrays a,y }
  25.  
  26. var    i,j    : integer;
  27.  
  28. begin
  29.   if not first then cls else first:=false;
  30.   writeln;
  31.   repeat
  32.     write('How many equations? ');
  33.     readln(n)
  34.   until n<maxr;
  35.   if n>1 then
  36.     begin
  37.       write('How many constant vectors? ');
  38.       readln(nvec);
  39.       for i:=1 to n do
  40.     begin
  41.       for j:=1 to n do
  42.         begin
  43.           write(j:3,': ');
  44.           read(a[i,j]);
  45.           if (j mod n+nvec)=0 then writeln
  46.         end;
  47.         if nvec>0 then
  48.       begin
  49.         for j:=1 to nvec do
  50.           begin
  51.         write('        C:');
  52.         read(y[i,j])
  53.           end;
  54.         readln
  55.       end
  56.      end;        { i-loop }
  57.  
  58.   writeln;
  59.   write('      Matrix');
  60.   if nvec>0 then write('      Constants');
  61.   writeln;
  62.   for i:=1 to n do
  63.     begin
  64.       for j:=1 to n do
  65.     write(a[i,j]:7:4,' ');
  66.       for j:=1 to nvec do
  67.     write(':',y[i,j]:7:4);
  68.       writeln
  69.   end;            { i-loop }
  70.   writeln
  71.   end        { if n>1 }
  72.  end;    { procedure get_data }
  73.  
  74. procedure write_data;
  75.     { print out answers }
  76.  
  77. var    i,j    : integer;
  78.  
  79. begin
  80.   if nvec>0 then
  81.     begin
  82.       writeln('Solution ');
  83.       for i:=1 to n do
  84.     begin
  85.       for j:=1 to nvec do
  86.         write(y[i,j]:9:5);
  87.       writeln
  88.     end
  89.   end    { if }
  90.  else
  91.   begin
  92.     writeln('      Inverse');
  93.     for i:=1 to n do
  94.       begin
  95.     for j:=1 to n do
  96.       write(a[i,j]:9:5);
  97.     writeln
  98.       end;
  99.     writeln;
  100.     write('Determinant is ',determ:10:5)
  101.   end;        { else }
  102.  writeln
  103. end;    { write_data }
  104.  
  105.  
  106. procedure gausjv
  107.     (var    b    : ary2s;    { square matrix of coefficients }
  108.      var    w    : ary2s;    { constant vector matrix }
  109.      var    determ    : real;        { the determinant }
  110.         ncol    : integer;    { order of matrix }
  111.         nv    : integer;    { number of constants }
  112.     var    error    : boolean);    { true if matrix is singular }
  113.  
  114. { Gauss Jordan matrix inversion and solution }
  115. {  B(n,n) coefficients matrix becomes inverse }
  116. {  W(n,m) constant vector(s) become solution vector }
  117. {  determ is the determinant }
  118. {  error=1 if singular }
  119. {  INDEX(n,3) }
  120. {  NV is the number of vectors }
  121.  
  122. label 99;
  123.  
  124. var
  125.     index    : array[1..maxc,1..3] of integer;
  126.     i,j,k,l,
  127.     irow,icol,
  128.     n,l1    : integer;
  129.     pivot,hold,
  130.     sum,ab,
  131.     t,big    : real;
  132.  
  133. procedure swap(var a,b: real);
  134. var    hold    : real;
  135.  
  136. begin
  137.     hold:=a;
  138.     a:=b;
  139.     b:=hold
  140. end;    { procedure swap }
  141.  
  142.  
  143. procedure gausj2;
  144.   label 98;
  145.   var    i,j,k,l,l1    : integer;
  146.  
  147.  
  148. procedure gausj3;
  149.  
  150. var    l    : integer;
  151.  
  152. begin        { procedure gausj3 }
  153.     { interchange rows to put pivot on diagonal }
  154.   if irow<>icol then
  155.     begin
  156.       determ:=-determ;
  157.       for l:=1 to n do
  158.     swap(b[irow,l],b[icol,l]);
  159.       if nv>0 then
  160.     for l:=1 to nv do
  161.       swap(w[irow,l],w[icol,l])
  162.    end    { if irow<>icol }
  163. end;    { gausj3 }
  164.  
  165. begin        { procedure gausj2 }
  166.     { actual start of gaussj }
  167.   error:=false;
  168.   n:=ncol;
  169.   for i:=1 to n do
  170.     index[i,3]:=0;
  171.   determ:=1.0;
  172.   for i:=1 to n do
  173.     begin
  174.     { search for the largest element }
  175.     big:=0.0;
  176.     for j:=1 to n do
  177.       begin
  178.     if index[j,3]<>1 then
  179.       begin
  180.         for k:=1 to n do
  181.          begin
  182.          if index[k,3]>1 then
  183.           begin
  184.         writeln(chr(7),'ERROR: matrix is singular');
  185.         error:=true;
  186.         goto 98        { abort }
  187.           end;
  188.     if index[k,3]<1 then
  189.       if abs(b[j,k])>big then
  190.         begin
  191.           irow:=j;
  192.           icol:=k;
  193.           big:=abs(B[j,k])
  194.          end
  195.        end        { k-loop }
  196.         end        { if }
  197.     end;    { j-loop }
  198.   index[icol,3]:=index[icol,3]+1;
  199.   index[i,1]:=irow;
  200.   index[i,2]:=icol;
  201.     gausj3;        { further subdivision of gaussj }
  202.             { divide pivot row by pivot column }
  203.   pivot:=b[icol,icol];
  204.   determ:=determ*pivot;
  205.   b[icol,icol]:=1.0;
  206.   for l:=1 to n do
  207.     b[icol,l]:=b[icol,l]/pivot;
  208.   if nv>0 then
  209.     for l:=1 to nv do
  210.       w[icol,l]:=w[icol,l]/pivot;
  211.   { reduce nonpivot rows }
  212.   for l1:=1 to n do
  213.     begin
  214.       if l1<>icol then
  215.     begin
  216.       t:=b[l1,icol];
  217.       b[l1,icol]:=0;
  218.       for l:=1 to n do
  219.         b[l1,l]:=b[l1,l]-b[icol,l]*t;
  220.       if nv>0 then
  221.         for l:=1 to nv do
  222.           w[l1,l]:=w[l1,l]-w[icol,l]*t
  223.       end    { if l1<>icol }
  224.    end        { for l1 }
  225.   end;    { i-loop }
  226. 98:
  227. end;        { gausj2 }
  228.  
  229. begin        { GAUS-JORDAN main program }
  230.   gausj2;    { first half of gaussj }
  231.   if error then goto 99;
  232.   { interchange columns }
  233.   for i:=1 to n do
  234.     begin
  235.       l:=n-i+1;
  236.       if index[l,1]<>index[l,2] then
  237.     begin
  238.       irow:=index[l,1];
  239.       icol:=index[l,2];
  240.       for k:=1 to n do
  241.         swap(b[k,irow],b[k,icol])
  242.     end    { if index }
  243.   end;        { i-loop }
  244. for k:=1 to n do
  245.   if index[k,3]<>1 then
  246.     begin
  247.       writeln(chr(7),'ERROR: matrix is singular');
  248.       error:=true;
  249.       goto 99    { abort }
  250.     end;
  251. 99:
  252. end;        { procedure gaussj }
  253.  
  254.  
  255. begin    { main program }
  256.   first:=true;
  257.   cls;
  258.   writeln;
  259.   revon;
  260.   writeln('Simultaneous solution by Gauss-Jordan');
  261.   writeln('Multiple constant vectors, or matrix inverse');
  262.   revoff;
  263.   repeat
  264.     get_data(a,y,n,nvec);
  265.     if n>1 then
  266.       begin
  267.     gausjv(a,y,determ,n,nvec,error);
  268.     if not error then write_data;
  269.     read(dummy)
  270.     end
  271.   until n<2
  272. end.
  273.