home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
turbo4
/
hilb.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1987-12-08
|
6KB
|
236 lines
program Hilb;
{
Dieses Programm demonstriert die hohe Geschwindigkeit und
Genauigkeit der Real-Arithmetik von Turbo Pascal.
--------------------------------------------------
Entnommen aus: Pascal Programs for Scientists and Engineers
Alan R. Miller, Sybex
n x n Inverse Hilbert-Matrix
Lösung: 1 1 1 1 1
--------------------------------------------------
Die Matrix wird über das Gauss-Jordansche Eliminationsverfahren
vereinfacht und simultan gelöst.
1. Setzen Sie den Compiler-Schalter O/C/Numeric processing auf "Software",
bevor Sie das Programm compilieren und starten.
2. Wenn Ihr Computer mit einen numerischen Corprozessor ausgerüstet ist:
Compilieren Sie das Programm mit O/C/Numeric processing.. "Hardware"
ein zweites Mal und vergleichen Sie Geschwindigkeit und Genauigkeit.
}
const
maxr = 10;
maxc = 10;
type
{$IFOPT N+} { Wenn ein 80x87 installiert ist: }
real = extended; { Verwendung des Formats Extended }
{$ENDIF}
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; { Matrix mit den Quadraten der Koeffizienten }
y : arys; { Konstanten-Vektor (zur Inversion) }
var coef : arys; { Lösungsvektor (Koeffizienten) }
ncol : integer; { Ordnung der Matrix (Spaltenzahl) }
var error: boolean); { TRUE, wenn die Matrix singulär ist }
{ Gauss-Jordansche Inversion und Lösung, nach McCormick (8-FEB-81)
B(N,N) ist die Koeffizienten-Matrix und wird invertiert
Y(N) ist der originale Konstante Vektor
W(N,M) besitzt konstante Vektoren und wird zur Lösung
Determ ist die Determinante der Matrix
Error bekommt den Wert TRUE bei singulären Matrizen
nv ist die Anzahl der konstanten Vektoren
}
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
hold := a; a := b; b := hold
end; { swap }
begin { gaussj }
error := false;
nv := 1; { Anzahl konstanter Vektoren }
n := ncol;
for i := 1 to n do
begin
w[i, 1] := y[i]; { Kopie des konstanten Vektors }
index[i, 3] := 0
end;
determ := 1.0;
for i := 1 to n do
begin
{ Suche nach dem größten Element ("Drehpunkt") }
big := 0.0;
for j := 1 to n do
if index[j, 3] <> 1 then
for k := 1 to n do
begin
if index[k, 3] > 1 then
begin
writeln(' FEHLER: Matrix ist singulär');
error := true;
exit;
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; { for k }
index[icol, 3] := index[icol, 3] + 1;
index[i, 1] := irow;
index[i, 2] := icol;
{ Austausch der Reihen -> größtes Element auf die Diagonale }
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 }
{ "Drehpunkt"-Reihe durch größtes Element dividieren }
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;
{ Reduktion der restlichen Reihen }
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 }
end
end { i loop };
if error then exit;
{ Austausch der Spalten }
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(' FEHLER: Matrix ist singulär');
error := true;
exit;
end;
for i := 1 to n do
coef[i] := w[i, 1];
end; { gaussj }
procedure get_data(var a : ary2s;
var y : arys;
var n, m : integer);
{ erzeugt die Originalmatrix }
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 write_data;
{ Ausgabe der Lösungen }
var
i : integer;
begin
for i := 1 to m do
write( coef[i] :13:9);
writeln;
end;
begin { Hauptprogramm }
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] { Arbeits-Array initialisieren };
gaussj (b, y, coef, n, error);
if not error then write_data;
n := n+1;
m := n
until n > maxr;
end.