123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- {
- 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])
- Determinants for different kinds of matrices (different with respect
- to symmetry)
- 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 det;
- interface
- {$I DIRECT.INC}
- uses typ;
- {Generic determinant}
- procedure detgen(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
- {determinant symmetrical matrix}
- procedure detgsy(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
- {determinant of a symmetrical positive definitive matrix}
- procedure detgpd(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
- {determinant of a generic bandmatrix}
- procedure detgba(n, l, r: ArbInt; var a, f: ArbFloat; var k, term:ArbInt);
- {determinant of a symmetrical positive definitive bandmatrix}
- procedure detgpb(n, l: ArbInt; var a, f: ArbFloat; var k, term:ArbInt);
- {determinant of a tridiagonal matrix}
- procedure detgtr(n: ArbInt; var l, d, u, f: ArbFloat; var k, term:ArbInt);
- { moved to the TYP unit because of a bug in FPC 1.0.x FK
- var og : ArbFloat absolute ogx;
- bg : ArbFloat absolute bgx;
- MaxExp : ArbInt absolute maxexpx;
- }
- implementation
- uses mdt;
- procedure detgen(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
- var
- kk, ind, ind1, ns, i : ArbInt;
- u, ca : ArbFloat;
- pa, acopy : ^arfloat1;
- p : ^arint1;
- begin
- if (n<1) or (rwidth<1) then
- begin
- term:=3; exit
- end; {wrong input}
- pa:=@a;
- ns:=n*sizeof(ArbFloat);
- getmem(p, n*sizeof(ArbInt));
- getmem(acopy, n*ns);
- ind:=1; ind1:=1;
- for i:=1 to n do
- begin
- move(pa^[ind1], acopy^[ind], ns);
- ind1:=ind1+rwidth; ind:=ind+n
- end; {i}
- mdtgen(n, n, acopy^[1], p^[1], ca, term);
- if term=1 then
- begin
- f:=1; k:=0; kk:=1; ind:=1;
- while (kk<=n) and (f<>0) do
- begin
- u:=acopy^[ind];
- while (u<>0) and (abs(u)<og) do
- begin
- u:=u/og; k:=k-maxexp
- end; {underflow control}
- while abs(u)>bg do
- begin
- u:=u/bg; k:=k+maxexp
- end; {overflow control}
- f:=f*u;
- if p^[kk]<>kk then f:=-f;
- while (f<>0) and (abs(f)<og) do
- begin
- f:=f/og; k:=k-maxexp
- end; {underflow control}
- while abs(f)>bg do
- begin
- f:=f/bg; k:=k+maxexp
- end; {overflow control}
- kk:=kk+1; ind:=ind+n+1
- end; {kk}
- end {term=1}
- else {term=4}
- begin
- f:=0; k:=0; term:=1
- end;
- freemem(p, n*sizeof(ArbInt));
- freemem(acopy, n*ns)
- end; {detgen}
- procedure detgsy(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
- var i, kk, ind, ind1, s : ArbInt;
- u, ca : ArbFloat;
- pa, acopy : ^arfloat1;
- p : ^arint1;
- q : ^arbool1;
- begin
- if (n<1) or (rwidth<1) then
- begin
- term:=3; exit
- end; {wrong input}
- pa:=@a;
- getmem(p, n*sizeof(ArbInt));
- getmem(q, n*sizeof(boolean));
- s:=sizeof(ArbFloat);
- getmem(acopy, n*n*s);
- ind:=1; ind1:=1;
- for i:=1 to n do
- begin
- move(pa^[ind1], acopy^[ind], i*s);
- ind1:=ind1+rwidth; ind:=ind+n
- end; {i}
- mdtgsy(n, n, acopy^[1], p^[1], q^[1], ca, term);
- if term=1 then
- begin
- f:=1; k:=0; kk:=1; ind:=1;
- while (kk<=n) and (f<>0) do
- begin
- u:=acopy^[ind];
- while (u<>0) and (abs(u)<og) do
- begin
- u:=u/og; k:=k-maxexp
- end; {underflow control}
- while abs(u)>bg do
- begin
- u:=u/bg; k:=k+maxexp
- end; {overflow control}
- f:=f*u;
- if q^[kk] then f:=-f;
- while (f<>0) and (abs(f)<og) do
- begin
- f:=f/og; k:=k-maxexp
- end; {underflow control}
- while abs(f)>bg do
- begin
- f:=f/bg; k:=k+maxexp
- end; {overflow control}
- kk:=kk+1; ind:=ind+n+1
- end; {kk}
- end {term=1}
- else {term=4}
- begin
- term:=1; f:=0; k:=0
- end;
- freemem(p, n*sizeof(ArbInt));
- freemem(q, n*sizeof(boolean));
- freemem(acopy, n*n*s)
- end; {detgsy}
- procedure detgpd(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
- var
- i, kk, ind, ind1, s : ArbInt;
- u, ca : ArbFloat;
- pa, acopy : ^arfloat1;
- begin
- if (n<1) or (rwidth<1) then
- begin
- term:=3; exit
- end; {wrong input}
- pa:=@a;
- s:=sizeof(ArbFloat);
- getmem(acopy, n*n*s);
- ind:=1; ind1:=1;
- for i:=1 to n do
- begin
- move(pa^[ind1], acopy^[ind], i*s);
- ind1:=ind1+rwidth; ind:=ind+n
- end; {i}
- mdtgpd(n, n, acopy^[1], ca, term);
- if term=1 then
- begin
- f:=1; k:=0; kk:=1; ind:=1;
- while kk<=n do
- begin
- u:=sqr(acopy^[ind]);
- while u < og do
- begin
- u:=u/og; k:=k-maxexp
- end; {underflow control}
- while u > bg do
- begin
- u:=u/bg; k:=k+maxexp
- end; {overflow control}
- f:=f*u;
- while f < og do
- begin
- f:=f/og; k:=k-maxexp
- end; {underflow control}
- while f > bg do
- begin
- f:=f/bg; k:=k+maxexp
- end; {overflow control}
- kk:=kk+1; ind:=ind+n+1
- end; {kk}
- end; {term=1}
- freemem(acopy, n*n*s)
- end; {detgpd}
- procedure detgba(n, l, r: ArbInt; var a, f: ArbFloat;
- var k, term:ArbInt);
- var
- rwidth, s, ns, kk, ii, i, jj, ll : ArbInt;
- u, ca : ArbFloat;
- pa, l1, acopy : ^arfloat1;
- p : ^arint1;
- begin
- if (n<1) or (l<0) or (r<0) or (l>n-1) or (r>n-1) then
- begin
- term:=3; exit
- end; {wrong input}
- pa:=@a;
- s:=sizeof(ArbFloat); ns:=n*s;
- ll:=l+r+1;
- getmem(acopy, ll*ns);
- getmem(l1, l*ns);
- getmem(p, n*sizeof(ArbInt));
- jj:=1; ii:=1;
- for i:=1 to n do
- begin
- if i <= l+1 then
- begin
- if i <= (n-r) then rwidth:=r+i else rwidth:=n
- end else
- if i <= (n-r) then rwidth:=ll else rwidth:=n-i+l+1;
- if i > l then kk:=ii else kk:=ii+l-i+1;
- move(pa^[jj], acopy^[kk], rwidth*s);
- jj:=jj+rwidth; ii:=ii+ll;
- end; {i}
- mdtgba(n, l, r, ll, acopy^[1], l, l1^[1], p^[1], ca, term);
- if term=1 then
- begin
- f:=1; k:=0; kk:=1; ii:=1;
- while (kk<=n) and (f<>0) do
- begin
- u:=acopy^[ii];
- while (u<>0) and (abs(u)<og) do
- begin
- u:=u/og; k:=k-maxexp
- end; {underflow control}
- while abs(u)>bg do
- begin
- u:=u/bg; k:=k+maxexp
- end; {overflow control}
- f:=f*u;
- if p^[kk]<>kk then f:=-f;
- while (f<>0) and (abs(f)<og) do
- begin
- f:=f/og; k:=k-maxexp
- end; {underflow control}
- while abs(f)>bg do
- begin
- f:=f/bg; k:=k+maxexp
- end; {overflow control}
- kk:=kk+1; ii:=ii+ll
- end; {kk}
- end {term=1}
- else {term=4}
- begin
- term:=1; f:=0; k:=0
- end;
- freemem(acopy, ll*ns);
- freemem(l1, l*ns);
- freemem(p, n*sizeof(ArbInt))
- end; {detgba}
- procedure detgpb(n, l: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
- var
- rwidth, kk, ii, ns, ll, jj, i, s : ArbInt;
- u, ca : ArbFloat;
- pa, acopy : ^arfloat1;
- begin
- if (n<1) or (l<0) or (l>n-1) then
- begin
- term:=3; exit
- end; {wrong input}
- pa:=@a;
- ll:=l+1;
- s:=sizeof(ArbFloat); ns:=s*n;
- getmem(acopy, ll*ns);
- jj:=1; ii:=1;
- for i:=1 to n do
- begin
- if i>l then rwidth:=ll else rwidth:=i;
- move(pa^[jj], acopy^[ii+ll-rwidth], rwidth*s);
- jj:=jj+rwidth; ii:=ii+ll
- end; {i}
- mdtgpb(n, l, ll, acopy^[1], ca, term);
- if term=1 then
- begin
- f:=1; k:=0; kk:=1; ii:=ll;
- while (kk<=n) do
- begin
- u:=sqr(acopy^[ii]);
- while u < og do
- begin
- u:=u/og; k:=k-maxexp
- end; {underflow control}
- while u > bg do
- begin
- u:=u/bg; k:=k+maxexp
- end; {overflow control}
- f:=f*u;
- while f < og do
- begin
- f:=f/og; k:=k-maxexp
- end; {underflow control}
- while f > bg do
- begin
- f:=f/bg; k:=k+maxexp
- end; {overflow control}
- kk:=kk+1; ii:=ii+ll
- end; {kk}
- end; {term=1}
- freemem(acopy, ll*ns);
- end; {detgpb}
- procedure detgtr(n: ArbInt; var l, d, u, f: ArbFloat; var k, term:ArbInt);
- var
- ns, kk : ArbInt;
- uu, ca : ArbFloat;
- pl, pd, pu, l1, d1, u1, u2 : ^arfloat1;
- p : ^arbool1;
- begin
- if n<1 then
- begin
- term:=3; exit
- end; {wrong input}
- pl:=@l; pd:=@d; pu:=@u;
- ns:=n*sizeof(ArbFloat);
- getmem(l1, ns);
- getmem(d1, ns);
- getmem(u1, ns);
- getmem(u2, ns);
- getmem(p, n*sizeof(boolean));
- mdtgtr(n, pl^[1], pd^[1], pu^[1], l1^[1], d1^[1], u1^[1], u2^[1],
- p^[1], ca, term);
- if term=1 then
- begin
- f:=1; k:=0; kk:=1;
- while (kk<=n) and (f<>0) do
- begin
- if p^[kk] then f:=-f;
- uu:=d1^[kk];
- while (uu<>0) and (abs(uu)<og) do
- begin
- uu:=uu/og; k:=k-maxexp
- end; {underflow control}
- while abs(uu)>bg do
- begin
- uu:=uu/bg; k:=k+maxexp
- end; {overflow control}
- f:=f*uu;
- while (f<>0) and (abs(f)<og) do
- begin
- f:=f/og; k:=k-maxexp
- end; {underflow control}
- while abs(f)>bg do
- begin
- f:=f/bg; k:=k+maxexp
- end; {overflow control}
- kk:=kk+1
- end; {kk}
- end {term=1}
- else {term=4}
- begin
- term:=1; f:=0; k:=0
- end;
- freemem(l1, ns);
- freemem(d1, ns);
- freemem(u1, ns);
- freemem(u2, ns);
- freemem(p, n*sizeof(boolean));
- end; {detgtr}
- end.
|