2
This file is part of the Numlib package.
3
Copyright (c) 1986-2000 by
4
Kees van Ginneken, Wil Kortsmit and Loek van Reij of the
5
Computational centre of the Eindhoven University of Technology
7
FPC port Code by Marco van de Voort (marco@freepascal.org)
8
documentation by Michael van Canneyt (Michael@freepascal.org)
10
Unit was originally undocumented, but is probably an variant of DET.
11
Det accepts vectors as arguments, while MDT calculates determinants for
14
Contrary to the other undocumented units, this unit is exported in the
17
See the file COPYING.FPC, included in this distribution,
18
for details about the copyright.
20
This program is distributed in the hope that it will be useful,
21
but WITHOUT ANY WARRANTY; without even the implied warranty of
22
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24
**********************************************************************}
32
Procedure mdtgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt;
33
Var ca:ArbFloat; Var term: ArbInt);
35
Procedure mdtgtr(n: ArbInt; Var l, d, u, l1, d1, u1, u2: ArbFloat;
36
Var p: boolean; Var ca: ArbFloat; Var term: ArbInt);
38
Procedure mdtgsy(n, rwidth: ArbInt; Var a: ArbFloat; Var pp:ArbInt;
39
Var qq:boolean; Var ca:ArbFloat; Var term:ArbInt);
41
Procedure mdtgpd(n, rwidth: ArbInt; Var al, ca: ArbFloat; Var term: ArbInt);
43
Procedure mdtgba(n, lb, rb, rwa: ArbInt; Var a: ArbFloat; rwl: ArbInt;
44
Var l:ArbFloat; Var p: ArbInt; Var ca: ArbFloat; Var term:ArbInt);
46
Procedure mdtgpb(n, lb, rwidth: ArbInt; Var al, ca: ArbFloat;
49
Procedure mdtdtr(n: ArbInt; Var l, d, u, l1, d1, u1: ArbFloat;
54
Procedure mdtgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt;
55
Var ca:ArbFloat; Var term: ArbInt);
58
indi, indk, nsr, ind, i, j, k, indexpivot : ArbInt;
59
normr, sumrowi, pivot, l, normt, maxim, h, s : ArbFloat;
60
palu, sumrow, t : ^arfloat1;
64
If (n<1) Or (rwidth<1) Then
71
nsr := n*sizeof(ArbFloat);
82
sumrowi := sumrowi+abs(palu^[ind+j]);
83
sumrow^[i] := sumrowi;
87
If normr<h Then normr := h;
98
sumrowi := sumrow^[i];
101
h := abs(palu^[ind+k])/sumrowi;
113
If indexpivot <> k Then
115
ind := (indexpivot-1)*rwidth;
116
indk := (k-1)*rwidth;
120
palu^[ind+j] := palu^[indk+j];
124
t^[indexpivot] := t^[k];
126
pp^[k] := indexpivot;
127
sumrow^[indexpivot] := sumrow^[k]
128
End; {indexpivot <> k}
129
pivot := palu^[(k-1)*rwidth+k];
133
l := palu^[ind+k]/pivot;
138
palu^[ind+j] := palu^[ind+j]-l*palu^[(k-1)*rwidth+j];
140
t^[i] := t^[i]-l*t^[k]
150
indi := (i-1)*rwidth;
153
s := s+t^[j]*palu^[indi+j];
154
t^[i] := (t^[i]-s)/palu^[indi+i];
168
freemem(sumrow, nsr);
172
Procedure mdtgtr(n: ArbInt; Var l, d, u, l1, d1, u1, u2: ArbFloat;
173
Var p: boolean; Var ca: ArbFloat; Var term: ArbInt);
176
i, j, k, nmin1, sr : ArbInt;
177
normr, normt, sumrowi, h, lj, di, ui, ll : ArbFloat;
179
pd, pu, pd1, pu1, pu2, t, sumrow : ^arfloat1;
196
sr := sizeof(ArbFloat);
197
move(pl^, pl1^, (n-1)*sr);
198
move(pd^, pd1^, n*sr);
199
move(pu^, pu1^, (n-1)*sr);
201
getmem(sumrow, n*sr);
209
sumrowi := abs(pd^[1])+abs(pu^[1])
212
sumrowi := abs(pl^[n])+abs(pd^[n])
214
sumrowi := abs(pl^[i])+abs(pd^[i])+abs(pu^[i]);
215
sumrow^[i] := sumrowi;
236
pp^[i] := abs(di/sumrow^[i])<abs(lj/sumrow^[j]);
244
pd1^[j] := ui-ll*pd1^[j];
248
pu1^[j] := -ll*pu2^[i]
250
sumrow^[j] := sumrow^[i];
262
pd1^[j] := pd1^[j]-ll*pu1^[i];
266
t^[j] := t^[j]-ll*t^[i]
282
t^[n] := t^[n]/pd1^[n];
288
t^[nmin1] := (t^[nmin1]-pu1^[nmin1]*t^[n])/pd1^[nmin1];
293
For i:=n-2 Downto 1 Do
295
t^[i] := (t^[i]-pu1^[i]*t^[i+1]-pu2^[i]*t^[i+2])/pd1^[i];
310
freemem(sumrow, n*sr)
313
Procedure mdtgsy(n, rwidth: ArbInt; Var a: ArbFloat; Var pp:ArbInt;
314
Var qq:boolean; Var ca:ArbFloat; Var term:ArbInt);
317
i, j, kmin1, k, kplus1, kmin2, imin2, nsr, nsi, nsb, ii,
318
imin1, jmin1, indexpivot, iplus1, indi, indj, indk, indp : ArbInt;
319
ra, h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr, s : ArbFloat;
320
alt, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1;
324
If (n<1) Or (rwidth<1) Then
332
nsr := n*sizeof(ArbFloat);
333
nsi := n*sizeof(ArbInt);
334
nsb := n*sizeof(boolean);
347
indi := (i-1)*rwidth;
351
sumrowi := sumrowi+abs(alt^[indi+j]);
353
sumrowi := sumrowi+abs(alt^[(j-1)*rwidth+i]);
354
If norma<sumrowi Then
366
indk := kmin1*rwidth;
369
t^[2] := alt^[rwidth+2]*alt^[indk+1]+alt^[2*rwidth+2]*alt^[indk+2];
372
indi := (i-1)*rwidth;
373
t^[i] := alt^[indi+i-1]*alt^[indk+i-2]+alt^[indi+i]
374
*alt^[indk+i-1]+alt^[indi+rwidth+i]*alt^[indk+i]
376
t^[kmin1] := alt^[indk-rwidth+kmin2]*alt^[indk+k-3]
377
+alt^[indk-rwidth+kmin1]*alt^[indk+kmin2]
381
h := h-t^[j]*alt^[indk+j-1];
383
alt^[indk+k] := h-alt^[indk+kmin1]*alt^[indk+kmin2]
388
t^[2] := alt^[rwidth+2]*alt^[2*rwidth+1]+alt^[2*rwidth+2];
389
h := alt^[2*rwidth+3]-t^[2]*alt^[2*rwidth+1];
391
alt^[2*rwidth+3] := h-alt^[2*rwidth+2]*alt^[2*rwidth+1]
395
t^[2] := alt^[rwidth+2];
397
For i:=kplus1 To n Do
399
indi := (i-1)*rwidth;
402
h := h-t^[j]*alt^[indi+j-1];
413
If indexpivot>kplus1 Then
415
indp := (indexpivot-1)*rwidth;
417
p^[kplus1] := indexpivot;
421
alt^[indk+j] := alt^[indp+j];
424
For j:=indexpivot Downto kplus1 Do
426
indj := (j-1)*rwidth;
427
h := alt^[indj+kplus1];
428
alt^[indj+kplus1] := alt^[indp+j];
431
For i:=indexpivot To n Do
433
indi := (i-1)*rwidth;
434
h := alt^[indi+kplus1];
435
alt^[indi+kplus1] := alt^[indi+indexpivot];
436
alt^[indi+indexpivot] := h
439
pivot := alt^[k*rwidth+k];
441
alt^[(i-1)*rwidth+k] := alt^[(i-1)*rwidth+k]/pivot
450
u^[imin1] := alt^[(i-1)*rwidth+imin1];
451
l^[imin1] := u^[imin1];
452
d^[i] := alt^[(i-1)*rwidth+i]
454
mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1],
457
alt^[rwidth+1] := l1^[1];
458
alt^[rwidth+2] := d1^[2];
467
indi := imin1*rwidth;
468
alt^[indi+imin1] := l1^[imin1];
469
alt^[indi+i] := d1^[i];
470
alt^[(imin1-1)*rwidth+i] := u1^[imin1];
471
alt^[(imin2-1)*rwidth+i] := v^[imin2]
495
h := h-alt^[(i-1)*rwidth+jmin1]*t^[j]
499
dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term);
509
For j:=iplus1 To n Do
510
h := h-alt^[(j-1)*rwidth+imin1]*t1^[j];
516
ca := norma*normt/normr
530
Procedure mdtgpd(n, rwidth: ArbInt; Var al, ca: ArbFloat; Var term: ArbInt);
534
i, j, k, kmin1, indk, indi : ArbInt;
535
h, lkk, normr, normt, sumrowi, norma : ArbFloat;
538
If (n<1) Or (rwidth<1) Then
543
getmem(t, sizeof(ArbFloat)*n);
552
sumrowi := sumrowi+abs(pal^[(i-1)*rwidth+j]);
554
sumrowi := sumrowi+abs(pal^[(j-1)*rwidth+i]);
555
If norma<sumrowi Then
564
while (k<n) and posdef Do
568
indk := (k-1)*rwidth;
571
lkk := lkk-sqr(pal^[indk+j]);
576
pal^[indk+k] := sqrt(lkk);
580
indi := (i-1)*rwidth;
583
h := h-pal^[indk+j]*pal^[indi+j];
584
pal^[indi+k] := h/lkk
588
h := h-pal^[indk+j]*t^[j];
599
h := h-pal^[(j-1)*rwidth+i]*t^[j];
600
t^[i] := h/pal^[(i-1)*rwidth+i];
605
ca := norma*normt/normr
611
freemem(t, sizeof(ArbFloat)*n);
614
Procedure mdtgba(n, lb, rb, rwa: ArbInt; Var a: ArbFloat; rwl: ArbInt;
615
Var l:ArbFloat; Var p: ArbInt; Var ca: ArbFloat; Var term:ArbInt);
618
sr, i, j, k, ipivot, m, lbj, lbi, ubi, ls,
619
ii, jj, ll, s, js, jl, ubj : ArbInt;
620
ra, normr, sumrowi, pivot, normt, maxim, h : ArbFloat;
621
pl, au, sumrow, t, row : ^arfloat1;
625
If (n<1) Or (lb<0) Or (rb<0) Or (lb>n-1) Or (rb>n-1) Or (rwl<0) Or (rwa<1) Then
630
sr := sizeof(ArbFloat);
636
getmem(sumrow, n*sr);
642
For i:=lb Downto 1 Do
644
move(au^[i+jj], au^[jj], (ll-i)*sr);
645
fillchar(au^[jj+ll-i], i*sr, 0);
651
fillchar(au^[jj], i*sr, 0);
660
sumrowi := omvn1v(au^[ii], ll);
662
sumrow^[i] := sumrowi;
682
sumrowi := sumrow^[i];
685
h := abs(au^[ii])/sumrowi;
699
pl^[(k-1)*rwl+j] := 0;
704
au^[ii+j-1] := au^[ii+j];
713
ii := (ipivot-1)*rwa+1;
714
move(au^[ii], row^, ls);
715
move(au^[jj], au^[ii], ls);
716
move(row^, au^[jj], ls);
721
sumrow^[ipivot] := sumrow^[k]
731
pl^[(k-1)*rwl+jl] := h;
733
au^[ii+j] := au^[ii+j+1]-h*au^[jj+j+1];
736
t^[i] := t^[i]-h*t^[k]
752
For j:=1 To ubj+lb Do
753
h := h-au^[jj+j]*t^[i+j];
763
freemem(sumrow, n*sr);
768
Procedure mdtgpb(n, lb, rwidth: ArbInt; Var al, ca: ArbFloat;
773
i, j, k, r, p, q, ll, llmin1, jmin1, indi : ArbInt;
774
h, normr, normt, sumrowi, alim, norma : ArbFloat;
777
Procedure decomp(i, r: ArbInt);
788
h := h-pal^[ii+k]*pal^[ir+q];
792
pal^[ii+j] := h/pal^[ir+ll]
795
Procedure lmin1t(i: ArbInt);
802
For k:=llmin1 Downto p Do
805
h := h-pal^[indi+k]*t^[q]
811
If (lb<0) Or (lb>n-1) Or (n<1) Or (rwidth<1) Then
817
getmem(t, n*sizeof(ArbFloat));
826
indi := (i-1)*rwidth+p;
827
sumrowi := omvn1v(pal^[indi], ll-p+1);
830
while (r<n) and (j>1) Do
834
sumrowi := sumrowi+abs(pal^[(r-1)*rwidth+j])
836
If norma<sumrowi Then
848
while (i<n) and posdef Do
851
indi := (i-1)*rwidth;
871
pal^[indi+ll] := alim;
885
For k:=llmin1 Downto p Do
888
h := h-pal^[(q-1)*rwidth+k]*t^[q]
890
t^[i] := h/pal^[(i-1)*rwidth+ll];
895
ca := norma*normt/normr
901
freemem(t, n*sizeof(ArbFloat));
904
Procedure mdtdtr(n: ArbInt; Var l, d, u, l1, d1, u1: ArbFloat;
910
pd, pu, pd1, pu1 : ^arfloat1;
925
s := sizeof(ArbFloat);
926
move(pl^, pl1^, (n-1)*s);
927
move(pd^, pd1^, n*s);
928
move(pu^, pu1^, (n-1)*s);
935
while (term=1) and (j <> n) Do
941
di := pd1^[j]-lj*pu1^[i];