home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
1988
/
02
/
nonlin.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1987-11-23
|
6KB
|
249 lines
(*---------------------------------------------------------------*)
(* NONLIN.PAS *)
(* Loesung eines nichtlinearen Gleichungssystems *)
(* (C) Prof.Dr.R.Rettig-Zinke & PASCAL INTERNATIONAL *)
(*---------------------------------------------------------------*)
PROGRAM Nonlin;
CONST max = 10; (* max >= n + 1 !!! *)
TYPE vektor = ARRAY[1..max] OF REAL;
matrix = ARRAY[1..max,1..max] OF REAL;
VAR x, f, dx : vektor;
a : matrix;
i, j, k,
m, m1, n,
iter, maxiter : INTEGER;
schranke, sdiff, sneu : REAL;
abl : BOOLEAN;
PROCEDURE Funktionen;
(****************************************************************
hier: Gleichungssystem eingeben !!!
****************************************************************)
BEGIN
f[1] := x[1]+x[2] - x[1]*x[3] + 0.5 *x[3] - 1.5;
f[2] := x[1]*x[2] + x[1]*x[1] - x[3]*x[3] + 6;
f[3] := Sqrt(x[1]*x[1]*x[1]) + x[2]*x[2] + x[3]*x[3] - 14;
END;
PROCEDURE Ableitungen;
VAR xh,fh : vektor;
dj : REAL;
BEGIN
(***************************************************************
hier: evtl. 1. Ableitungen als Differentialquotienten
eingeben !!!
***************************************************************)
IF abl THEN BEGIN
a[1,1] := 1-x[3];
a[1,2] := 1;
a[1,3] := -x[1]+0.5;
a[2,1] := x[2]+2*x[1];
a[2,2] := x[1];
a[2,3] := -2*x[3];
a[3,1] := 1.5*Sqrt(x[1]);
a[3,2] := 2*x[2];
a[3,3] := 2*x[3];
END
(***************************************************************
1. Ableitungen als Differenzenquotienten
(werden IN der Prozedur berechnet !!!)
***************************************************************)
ELSE BEGIN
FOR j := 1 TO m DO
xh[j] := x[j];
Funktionen;
FOR i := 1 TO n DO
fh[i] := f[i];
FOR j := 1 TO m DO BEGIN
dj := ABS(x[j] / 1E4) + 1E-08;
x[j] := x[j] + dj;
Funktionen;
FOR i := 1 TO n DO
a[i,j] := f[i];
x[j] := xh[j];
END;
FOR j := 1 TO m DO BEGIN
dj := ABS(x[j] / 1E4) + 1E-08;
x[j] := x[j] - dj;
Funktionen;
FOR i := 1 TO n DO
a[i,j] := (a[i,j] - f[i]) / 2 / dj;
x[j] := xh[j];
END;
FOR j := 1 TO m DO
x[j] := xh[j];
FOR i := 1 TO n DO
f[i] := fh[i];
END;
END;
PROCEDURE Householder;
VAR d : vektor;
sigma, s,
sum, beta : REAL;
ok : BOOLEAN;
BEGIN
ok := FALSE;
j := 1;
WHILE (j <= m) AND NOT (ok) DO BEGIN
sigma := 0;
FOR i := j TO n DO
sigma := sigma + Sqr( a[i,j] );
IF sigma <> 0 THEN BEGIN
IF a[j,j] < 0 THEN BEGIN
s := Sqrt(sigma);
d[j] := s;
END
ELSE BEGIN
s := - Sqrt(sigma);
d[j] := s;
END;
beta := 1 / (s * a[j,j] - sigma);
a[j,j] := a[j,j] - s;
FOR k := j+1 TO m1 DO BEGIN
sum := 0;
FOR i := j TO n DO
sum := sum + a[i,j] * a[i,k];
sum := beta * sum;
FOR i := j TO n DO
a[i,k] := a[i,k] + a[i,j] * sum;
END;
END
ELSE BEGIN
WriteLn;
WriteLn ('Singulaere Matrix !');
WriteLn;
ok := TRUE;
Halt;
END;
j := Succ(j);
END;
FOR j := m DOWNTO 1 DO BEGIN
dx[j] := a[j,m1];
FOR i := m DOWNTO j+1 DO
dx[j] := dx[j] - a[j,i] * dx[i];
dx[j] := dx[j] / d[j];
END;
END;
PROCEDURE ErweitereMatrix;
BEGIN
FOR i := 1 TO n DO
a[i,m1] := f[i];
END;
PROCEDURE NeueWerte;
VAR sum : REAL;
BEGIN
FOR j := 1 TO m DO
x[j] := x[j] - dx[j];
END;
PROCEDURE Konvergenz;
VAR salt : REAL;
BEGIN
salt := sneu;
sneu := 0;
FOR i := 1 TO n DO
FOR j := 1 TO m DO
sneu := sneu + Sqr(a[i,j]);
sneu := Sqrt(sneu);
sdiff := ABS(sneu - salt);
END;
PROCEDURE Bild;
BEGIN
ClrScr;
Write ('iter Schranke');
FOR j := 1 TO m DO
Write (' x(',j,')');
WriteLn;
WriteLn;
END;
PROCEDURE Ausdruck;
BEGIN
Write (iter:4, sdiff:12:6);
FOR j := 1 TO m DO
Write (x[j]:12:6);
WriteLn;
END;
PROCEDURE Ergebnis;
BEGIN
WriteLn;
Write ('Bitte beliebige Taste druecken ... ');
REPEAT UNTIL KeyPressed;
ClrScr;
WriteLn ('Anzahl der Iterationen = ', iter);
WriteLn;
WriteLn (' j x(j) dx(j)');
WriteLn;
FOR j := 1 TO m DO
WriteLn (j:3, x[j]:12:6, dx[j]:12:6);
WriteLn; WriteLn;
WriteLn (' i f(i)');
WriteLn;
FOR i := 1 TO n DO
WriteLn (i:3, f[i]:12:6);
WriteLn;
WriteLn ('Letzte Differenz: ',sdiff:12:6);
WriteLn;
END;
PROCEDURE Anfangswerte;
BEGIN
n := 3;
m := 3;
x[1] := 15;
x[2] := 10;
x[3] := 5;
maxiter := 20;
schranke := 1E-6;
abl := FALSE;
END;
BEGIN (* Hauptprogramm *)
Anfangswerte;
m1 := m + 1;
iter := 0;
sneu := 0;
sdiff := schranke;
Bild;
Ausdruck;
WriteLn;
REPEAT
iter := Succ(iter);
Funktionen;
Ableitungen;
Konvergenz;
ErweitereMatrix;
Householder;
Ausdruck;
NeueWerte;
UNTIL (iter = maxiter) OR
(sdiff < schranke);
Ergebnis;
END.