123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- {
- $Id$
- This file is part of the Numlib package.
- Copyright (c) 1986-2000 by
- Kees van Ginneken, Wil Kortsmit and Loek van Reij of the
- Computational centre of the Eindhoven University of Technology
- FPC port Code by Marco van de Voort ([email protected])
- documentation by Michael van Canneyt ([email protected])
- Unknown unit. There doesn't exist any documentation for it, it isn't
- commented, and I don't recognize the algortism directly.
- I added some comments, since suffixes of the procedures seem to indicate
- some features of the matrixtype (from unit SLE)
- So probably Some pivot matrix?
- This code was probably internal in older libs, and only exported
- in later versions.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- Unit dsl;
- interface
- {$I DIRECT.INC}
- uses typ;
- {Gen=generic, matrix without special or unknown ordering}
- Procedure dslgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt;
- Var b, x: ArbFloat; Var term: ArbInt);
- {"tridiagonal matrix"}
- Procedure dslgtr(n: ArbInt; Var l1, d1, u1, u2: ArbFloat;
- Var p: boolean; Var b, x: ArbFloat; Var term: ArbInt);
- {Symmetrical matrix}
- Procedure dslgsy(n, rwidth: ArbInt; Var alt: ArbFloat; Var p: ArbInt;
- Var q: boolean; Var b, x: ArbFloat; Var term: ArbInt);
- {Symmetrical positive definitive matrix}
- Procedure dslgpd(n, rwidth: ArbInt; Var al, b, x: ArbFloat;
- Var term: ArbInt);
- {Generic "band" matrix}
- Procedure dslgba(n, lb, rb, rwa: ArbInt; Var au: ArbFloat; rwl: ArbInt;
- Var l: ArbFloat; Var p: ArbInt; Var b, x: ArbFloat;
- Var term: ArbInt);
- {Positive definite bandmatrix}
- Procedure dslgpb(n, lb, rwidth: ArbInt; Var al, b, x: ArbFloat;
- Var term: ArbInt);
- {Special tridiagonal matrix}
- Procedure dsldtr(n:ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
- implementation
- Procedure dslgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt;
- Var b, x: ArbFloat; Var term: ArbInt);
- Var
- success : boolean;
- indk, j, k, indexpivot, kmin1 : ArbInt;
- h, pivot, s : ArbFloat;
- pp : ^arint1;
- palu, pb, px : ^arfloat1;
- Begin
- If (n<1) Or (rwidth<1) Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- pp := @p;
- palu := @alu;
- pb := @b;
- px := @x;
- move(pb^, px^, n*sizeof(ArbFloat));
- For k:=1 To n Do
- Begin
- indexpivot := pp^[k];
- If indexpivot <> k Then
- Begin
- h := px^[k];
- px^[k] := px^[indexpivot];
- px^[indexpivot] := h
- End {indexpivot <> k}
- End; {k}
- For k:=2 To n Do
- Begin
- s := px^[k];
- kmin1 := k-1;
- For j:=1 To kmin1 Do
- s := s-palu^[(k-1)*rwidth+j]*px^[j];
- px^[k] := s
- End; {k}
- success := true;
- k := n+1;
- while (k>1) and success Do
- Begin
- k := k-1;
- indk := (k-1)*rwidth;
- pivot := palu^[indk+k];
- If pivot=0 Then
- success := false
- Else
- Begin
- s := px^[k];
- For j:=k+1 To n Do
- s := s-palu^[indk+j]*px^[j];
- px^[k] := s/pivot
- End {pivot <> 0}
- End; {k}
- If success Then
- term := 1
- Else
- term := 2
- End; {dslgen}
- Procedure dslgtr(n: ArbInt; Var l1, d1, u1, u2: ArbFloat;
- Var p: boolean; Var b, x: ArbFloat; Var term: ArbInt);
- Var
- i, j, nmin1 : ArbInt;
- h, di : ArbFloat;
- success : boolean;
- pd1, pu1, pu2, pb, px : ^arfloat1;
- pl1 : ^arfloat2;
- pp : ^arbool1;
- Begin
- If n<1 Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- pl1 := @l1; pd1 := @d1; pu1 := @u1; pu2 := @u2; pb := @b; px := @x;
- pp := @p;
- move(pb^, px^, n*sizeof(ArbFloat));
- success := true;
- i := 0;
- while (i<>n) and success Do
- Begin
- i := i+1;
- success := pd1^[i]<>0
- End; {i}
- If success Then
- Begin
- nmin1 := n-1;
- j := 1;
- while j <> n Do
- Begin
- i := j;
- j := j+1;
- If pp^[i] Then
- Begin
- h := px^[i];
- px^[i] := px^[j];
- px^[j] := h-pl1^[j]*px^[i]
- End {pp^[i]}
- Else
- px^[j] := px^[j]-pl1^[j]*px^[i]
- End; {j}
- di := pd1^[n];
- px^[n] := px^[n]/di;
- If n > 1 Then
- Begin
- di := pd1^[nmin1];
- px^[nmin1] := (px^[nmin1]-pu1^[nmin1]*px^[n])/di
- End; {n > 1}
- For i:=n-2 Downto 1 Do
- Begin
- di := pd1^[i];
- px^[i] := (px^[i]-pu1^[i]*px^[i+1]-pu2^[i]*px^[i+2])/di
- End {i}
- End; {success}
- If success Then
- term := 1
- Else
- term := 2
- End; {dslgtr}
- Procedure dslgsy(n, rwidth: ArbInt; Var alt: ArbFloat; Var p: ArbInt;
- Var q: boolean; Var b, x: ArbFloat; Var term: ArbInt);
- Var
- i, indexpivot, imin1, j, jmin1, iplus1, imin2, ns, ii : ArbInt;
- success, regular : boolean;
- h, ct, di : ArbFloat;
- palt, pb, px, y, l, d, u, v : ^arfloat1;
- pp : ^arint1;
- pq : ^arbool1;
- Begin
- If (n<1) Or (rwidth<1) Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- palt := @alt;
- pp := @p;
- pq := @q;
- pb := @b;
- px := @x;
- ns := n*sizeof(ArbFloat);
- getmem(l, ns);
- getmem(d, ns);
- getmem(u, ns);
- getmem(v, ns);
- getmem(y, ns);
- move(pb^, y^, ns);
- success := true;
- i := 0;
- ii := 1;
- while (i<>n) and success Do
- Begin
- i := i+1;
- success := palt^[ii]<>0;
- ii := ii+rwidth+1
- End; {i}
- If success Then
- Begin
- For i:=1 To n Do
- Begin
- indexpivot := pp^[i];
- If indexpivot <> i Then
- Begin
- h := y^[i];
- y^[i] := y^[indexpivot];
- y^[indexpivot] := h
- End {indexpivot <> i}
- End; {i}
- i := 0;
- while i<n Do
- Begin
- imin1 := i;
- i := i+1;
- j := 1;
- h := y^[i];
- while j<imin1 Do
- Begin
- jmin1 := j;
- j := j+1;
- h := h-palt^[(i-1)*rwidth+jmin1]*y^[j]
- End; {j}
- y^[i] := h
- End; {i}
- d^[1] := palt^[1];
- di := d^[1];
- If n>1 Then
- Begin
- l^[1] := palt^[rwidth+1];
- d^[2] := palt^[rwidth+2];
- di := d^[2];
- u^[1] := palt^[2]
- End; {n>1}
- imin1 := 1;
- i := 2;
- while i<n Do
- Begin
- imin2 := imin1;
- imin1 := i;
- i := i+1;
- ii := (i-1)*rwidth;
- l^[imin1] := palt^[ii+imin1];
- d^[i] := palt^[ii+i];
- di := d^[i];
- u^[imin1] := palt^[ii-rwidth+i];
- v^[imin2] := palt^[ii-2*rwidth+i]
- End; {i}
- dslgtr(n, l^[1], d^[1], u^[1], v^[1], pq^[1], y^[1], px^[1], term);
- i := n+1;
- imin1 := n;
- while i>2 Do
- Begin
- iplus1 := i;
- i := imin1;
- imin1 := imin1-1;
- h := px^[i];
- For j:=iplus1 To n Do
- h := h-palt^[(j-1)*rwidth+imin1]*px^[j];
- px^[i] := h
- End; {i}
- For i:=n Downto 1 Do
- Begin
- indexpivot := pp^[i];
- If indexpivot <> i Then
- Begin
- h := px^[i];
- px^[i] := px^[indexpivot];
- px^[indexpivot] := h
- End {indexpivot <> i}
- End {i}
- End; {success}
- If success Then
- term := 1
- Else
- term := 2;
- freemem(l, ns);
- freemem(d, ns);
- freemem(u, ns);
- freemem(v, ns);
- freemem(y, ns)
- End; {dslgsy}
- Procedure dslgpd(n, rwidth: ArbInt; Var al, b, x: ArbFloat;
- Var term: ArbInt);
- Var
- ii, imin1, i, j : ArbInt;
- h, lii : ArbFloat;
- success : boolean;
- pal, pb, px : ^arfloat1;
- Begin
- If (n<1) Or (rwidth<1) Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- pal := @al;
- pb := @b;
- px := @x;
- move(pb^, px^, n*sizeof(ArbFloat));
- success := true;
- i := 0;
- ii := 1;
- while (i<>n) and success Do
- Begin
- i := i+1;
- success := pal^[ii]<>0;
- ii := ii+rwidth+1
- End; {i}
- If success Then
- Begin
- For i:=1 To n Do
- Begin
- ii := (i-1)*rwidth;
- h := px^[i];
- imin1 := i-1;
- For j:=1 To imin1 Do
- h := h-pal^[ii+j]*px^[j];
- lii := pal^[ii+i];
- px^[i] := h/lii
- End; {i}
- For i:=n Downto 1 Do
- Begin
- h := px^[i];
- For j:=i+1 To n Do
- h := h-pal^[(j-1)*rwidth+i]*px^[j];
- px^[i] := h/pal^[(i-1)*rwidth+i]
- End {i}
- End; {success}
- If success Then
- term := 1
- Else
- term := 2
- End; {dslgpd}
- Procedure dslgba(n, lb, rb, rwa: ArbInt; Var au: ArbFloat; rwl: ArbInt;
- Var l: ArbFloat; Var p: ArbInt; Var b, x: ArbFloat;
- Var term: ArbInt);
- Var
- i, j, k, ipivot, ubi, ubj : ArbInt;
- h, pivot : ArbFloat;
- pau, pl, px, pb : ^arfloat1;
- pp : ^arint1;
- Begin
- If (n<1) Or (lb<0) Or (rb<0) Or (lb>n-1)
- Or (rb>n-1) Or (rwa<1) Or (rwl<0) Then
- Begin
- term := 3;
- exit
- End; {term=3}
- pau := @au;
- pl := @l;
- pb := @b;
- px := @x;
- pp := @p;
- move(pb^, px^, n*sizeof(ArbFloat));
- ubi := lb;
- For k:=1 To n Do
- Begin
- ipivot := pp^[k];
- If ipivot <> k Then
- Begin
- h := px^[k];
- px^[k] := px^[ipivot];
- px^[ipivot] := h
- End; {ipivot <> k}
- If ubi<n Then
- ubi := ubi+1;
- For i:=k+1 To ubi Do
- px^[i] := px^[i]-px^[k]*pl^[(k-1)*rwl+i-k]
- End; {k}
- ubj := 0;
- i := n;
- term := 1;
- while (i >= 1) and (term=1) Do
- Begin
- If ubj<rb+lb+1 Then
- ubj := ubj+1;
- h := px^[i];
- For j:=2 To ubj Do
- h := h-pau^[(i-1)*rwa+j]*px^[i+j-1];
- pivot := pau^[(i-1)*rwa+1];
- If pivot=0 Then
- term := 2
- Else
- px^[i] := h/pivot;
- i := i-1
- End {i}
- End; {dslgba}
- Procedure dslgpb(n, lb, rwidth: ArbInt; Var al, b, x: ArbFloat;
- Var term: ArbInt);
- Var
- ll, ii, llmin1, p, i, q, k : ArbInt;
- h, hh, alim : ArbFloat;
- pal, pb, px : ^arfloat1;
- Begin
- If (lb<0) Or (lb>n-1) Or (n<1) Or (rwidth<1) Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- pal := @al;
- pb := @b;
- px := @x;
- move(pb^, px^, n*sizeof(ArbFloat));
- ll := lb+1;
- llmin1 := ll-1;
- p := ll+1;
- term := 1;
- i := 1;
- while (i <= n) and (term=1) Do
- Begin
- ii := (i-1)*rwidth;
- If p>1 Then
- p := p-1;
- h := px^[i];
- q := i;
- For k:=llmin1 Downto p Do
- Begin
- q := q-1;
- h := h-pal^[ii+k]*px^[q]
- End; {k}
- alim := pal^[ii+ll];
- If alim=0 Then
- term := 2
- Else
- px^[i] := h/alim;
- i := i+1
- End; {i}
- If term=1 Then
- Begin
- p := ll+1;
- For i:=n Downto 1 Do
- Begin
- If p>1 Then
- p := p-1;
- q := i;
- h := px^[i];
- For k:=llmin1 Downto p Do
- Begin
- q := q+1;
- h := h-pal^[(q-1)*rwidth+k]*px^[q]
- End; {k}
- px^[i] := h/pal^[(i-1)*rwidth+ll]
- End {i}
- End {term=1}
- End; {dslgpb}
- Procedure dsldtr(n:ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
- Var
- i, j : ArbInt;
- di : ArbFloat;
- pd, pu, pb, px : ^arfloat1;
- pl : ^arfloat2;
- Begin
- If n<1 Then
- Begin
- term := 3;
- exit
- End; {wrong input}
- pl := @l;
- pd := @d;
- pu := @u;
- pb := @b;
- px := @x;
- move(pb^, px^, n*sizeof(ArbFloat));
- j := 1;
- while j <> n Do
- Begin
- i := j;
- j := j+1;
- px^[j] := px^[j]-pl^[j]*px^[i]
- End;
- di := pd^[n];
- If di=0 Then
- term := 2
- Else
- term := 1;
- If term=1 Then
- px^[n] := px^[n]/di;
- i := n-1;
- while (i >= 1) and (term=1) Do
- Begin
- di := pd^[i];
- If di=0 Then
- term := 2
- Else
- px^[i] := (px^[i]-pu^[i]*px^[i+1])/di;
- i := i-1
- End; {i}
- End; {dsldtr}
- End.
- {
- $Log$
- Revision 1.2 2000-01-25 20:21:41 marco
- * small updates, crlf fix, and RTE 207 problem
- Revision 1.1 2000/01/24 22:08:58 marco
- * initial version
- }
|