home *** CD-ROM | disk | FTP | other *** search
-
- (*---------------------------------------------------------------*)
- (* 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.