diff options
Diffstat (limited to 'packages/numlib/src/mdt.pas')
-rw-r--r-- | packages/numlib/src/mdt.pas | 950 |
1 files changed, 950 insertions, 0 deletions
diff --git a/packages/numlib/src/mdt.pas b/packages/numlib/src/mdt.pas new file mode 100644 index 0000000000..a2d87e68f8 --- /dev/null +++ b/packages/numlib/src/mdt.pas @@ -0,0 +1,950 @@ +{ + 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 (marco@freepascal.org) + documentation by Michael van Canneyt (Michael@freepascal.org) + + Unit was originally undocumented, but is probably an variant of DET. + Det accepts vectors as arguments, while MDT calculates determinants for + matrices. + + Contrary to the other undocumented units, this unit is exported in the + DLL. + + 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 mdt; + +interface +{$I DIRECT.INC} + +uses typ, dsl, omv; + +Procedure mdtgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt; + Var ca:ArbFloat; Var term: ArbInt); + +Procedure mdtgtr(n: ArbInt; Var l, d, u, l1, d1, u1, u2: ArbFloat; + Var p: boolean; Var ca: ArbFloat; Var term: ArbInt); + +Procedure mdtgsy(n, rwidth: ArbInt; Var a: ArbFloat; Var pp:ArbInt; + Var qq:boolean; Var ca:ArbFloat; Var term:ArbInt); + +Procedure mdtgpd(n, rwidth: ArbInt; Var al, ca: ArbFloat; Var term: ArbInt); + +Procedure mdtgba(n, lb, rb, rwa: ArbInt; Var a: ArbFloat; rwl: ArbInt; + Var l:ArbFloat; Var p: ArbInt; Var ca: ArbFloat; Var term:ArbInt); + +Procedure mdtgpb(n, lb, rwidth: ArbInt; Var al, ca: ArbFloat; + Var term: ArbInt); + +Procedure mdtdtr(n: ArbInt; Var l, d, u, l1, d1, u1: ArbFloat; + Var term:ArbInt); + +implementation + +Procedure mdtgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt; + Var ca:ArbFloat; Var term: ArbInt); + +Var + indi, indk, nsr, ind, i, j, k, indexpivot : ArbInt; + normr, sumrowi, pivot, l, normt, maxim, h, s : ArbFloat; + palu, sumrow, t : ^arfloat1; + pp : ^arint1; + singular : boolean; +Begin + If (n<1) Or (rwidth<1) Then + Begin + term := 3; + exit + End; {wrong input} + palu := @alu; + pp := @p; + nsr := n*sizeof(ArbFloat); + getmem(sumrow, nsr); + getmem(t, nsr); + normr := 0; + singular := false ; + For i:=1 To n Do + Begin + ind := (i-1)*rwidth; + pp^[i] := i; + sumrowi := 0; + For j:=1 To n Do + sumrowi := sumrowi+abs(palu^[ind+j]); + sumrow^[i] := sumrowi; + h := 2*random-1; + t^[i] := sumrowi*h; + h := abs(h); + If normr<h Then normr := h; + If sumrowi=0 Then + singular := true + End; {i} + For k:=1 To n Do + Begin + maxim := 0; + indexpivot := k; + For i:=k To n Do + Begin + ind := (i-1)*rwidth; + sumrowi := sumrow^[i]; + If sumrowi <> 0 Then + Begin + h := abs(palu^[ind+k])/sumrowi; + If maxim<h Then + Begin + maxim := h; + indexpivot := i + End {maxim<h} + End {sumrow <> 0} + End; {i} + If maxim=0 Then + singular := true + Else + Begin + If indexpivot <> k Then + Begin + ind := (indexpivot-1)*rwidth; + indk := (k-1)*rwidth; + For j:=1 To n Do + Begin + h := palu^[ind+j]; + palu^[ind+j] := palu^[indk+j]; + palu^[indk+j] := h + End; {j} + h := t^[indexpivot]; + t^[indexpivot] := t^[k]; + t^[k] := h; + pp^[k] := indexpivot; + sumrow^[indexpivot] := sumrow^[k] + End; {indexpivot <> k} + pivot := palu^[(k-1)*rwidth+k]; + For i:=k+1 To n Do + Begin + ind := (i-1)*rwidth; + l := palu^[ind+k]/pivot; + palu^[ind+k] := l; + If l <> 0 Then + Begin + For j:=k+1 To n Do + palu^[ind+j] := palu^[ind+j]-l*palu^[(k-1)*rwidth+j]; + If Not singular Then + t^[i] := t^[i]-l*t^[k] + End {l <> 0} + End {i} + End {maxim <> 0} + End; {k} + If Not singular Then + Begin + normt := 0; + For i:=n Downto 1 Do + Begin + indi := (i-1)*rwidth; + s := 0; + For j:=i+1 To n Do + s := s+t^[j]*palu^[indi+j]; + t^[i] := (t^[i]-s)/palu^[indi+i]; + h := abs(t^[i]); + If normt<h Then + normt := h + End; {i} + ca := normt/normr + End; {not singular} + If singular Then + Begin + term := 4; + ca := giant + End + Else + term := 1; + freemem(sumrow, nsr); + freemem(t, nsr) +End; {mdtgen} + +Procedure mdtgtr(n: ArbInt; Var l, d, u, l1, d1, u1, u2: ArbFloat; + Var p: boolean; Var ca: ArbFloat; Var term: ArbInt); + +Var + i, j, nmin1, sr : ArbInt; + normr, normt, sumrowi, h, lj, di, ui, ll : ArbFloat; + sing : boolean; + pd, pu, pd1, pu1, pu2, t, sumrow : ^arfloat1; + pl, pl1 : ^arfloat2; + pp : ^arbool1; +Begin + If n<1 Then + Begin + term := 3; + exit + End; {wrong input} + pl := @l; + pd := @d; + pu := @u; + pl1 := @l1; + pd1 := @d1; + pu1 := @u1; + pu2 := @u2; + pp := @p; + sr := sizeof(ArbFloat); + move(pl^, pl1^, (n-1)*sr); + move(pd^, pd1^, n*sr); + move(pu^, pu1^, (n-1)*sr); + getmem(t, n*sr); + getmem(sumrow, n*sr); + normr := 0; + sing := false; + nmin1 := n-1; + For i:=1 To n Do + Begin + pp^[i] := false; + If i=1 Then + sumrowi := abs(pd^[1])+abs(pu^[1]) + Else + If i=n Then + sumrowi := abs(pl^[n])+abs(pd^[n]) + Else + sumrowi := abs(pl^[i])+abs(pd^[i])+abs(pu^[i]); + sumrow^[i] := sumrowi; + h := 2*random-1; + t^[i] := sumrowi*h; + h := abs(h); + If normr<h Then + normr := h; + If sumrowi=0 Then + sing := true + End; {i} + j := 1; + while (j <> n) Do + Begin + i := j; + j := j+1; + lj := pl1^[j]; + If lj <> 0 Then + Begin + di := pd1^[i]; + If di=0 Then + pp^[i] := true + Else + pp^[i] := abs(di/sumrow^[i])<abs(lj/sumrow^[j]); + If pp^[i] Then + Begin + ui := pu1^[i]; + pd1^[i] := lj; + pu1^[i] := pd1^[j]; + pl1^[j] := di/lj; + ll := pl1^[j]; + pd1^[j] := ui-ll*pd1^[j]; + If i<nmin1 Then + Begin + pu2^[i] := pu1^[j]; + pu1^[j] := -ll*pu2^[i] + End; {i<nmin1} + sumrow^[j] := sumrow^[i]; + If (Not sing) Then + Begin + h := t^[i]; + t^[i] := t^[j]; + t^[j] := h-ll*t^[i] + End {not sing} + End {pp^[i]} + Else + Begin + pl1^[j] := lj/di; + ll := pl1^[j]; + pd1^[j] := pd1^[j]-ll*pu1^[i]; + If i<nmin1 Then + pu2^[i] := 0; + If (Not sing) Then + t^[j] := t^[j]-ll*t^[i] + End {not pp^[i]} + End {lj<>0} + Else + Begin + If i<nmin1 Then + pu2^[i] := 0; + If pd1^[i]=0 Then + sing := true + End {lj=0} + End; {j} + If pd1^[n]=0 Then + sing := true; + If (Not sing) Then + Begin + normt := 0; + t^[n] := t^[n]/pd1^[n]; + h := abs(t^[n]); + If normt<h Then + normt := h; + If n > 1 Then + Begin + t^[nmin1] := (t^[nmin1]-pu1^[nmin1]*t^[n])/pd1^[nmin1]; + h := abs(t^[nmin1]) + End; {n > 1} + If normt<h Then + normt := h; + For i:=n-2 Downto 1 Do + Begin + t^[i] := (t^[i]-pu1^[i]*t^[i+1]-pu2^[i]*t^[i+2])/pd1^[i]; + h := abs(t^[i]); + If normt<h Then + normt := h + End; {i} + ca := normt/normr + End; {not sing} + If (sing) Then + Begin + term := 4; + ca := giant + End {sing} + Else + term := 1; + freemem(t, n*sr); + freemem(sumrow, n*sr) +End; {mdtgtr} + +Procedure mdtgsy(n, rwidth: ArbInt; Var a: ArbFloat; Var pp:ArbInt; + Var qq:boolean; Var ca:ArbFloat; Var term:ArbInt); + +Var + i, j, kmin1, k, kplus1, kmin2, imin2, nsr, nsi, nsb, + imin1, jmin1, indexpivot, iplus1, indi, indj, indk, indp : ArbInt; + h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr : ArbFloat; + alt, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1; + p : ^arint1; + q : ^arbool1; +Begin + If (n<1) Or (rwidth<1) Then + Begin + term := 3; + exit + End; {if} + alt := @a; + p := @pp; + q := @qq; + nsr := n*sizeof(ArbFloat); + nsi := n*sizeof(ArbInt); + nsb := n*sizeof(boolean); + getmem(l, nsr); + getmem(d, nsr); + getmem(t, nsr); + getmem(u, nsr); + getmem(v, nsr); + getmem(l1, nsr); + getmem(d1, nsr); + getmem(u1, nsr); + getmem(t1, nsr); + norma := 0; + For i:=1 To n Do + Begin + indi := (i-1)*rwidth; + p^[i] := i; + sumrowi := 0; + For j:=1 To i Do + sumrowi := sumrowi+abs(alt^[indi+j]); + For j:=i+1 To n Do + sumrowi := sumrowi+abs(alt^[(j-1)*rwidth+i]); + If norma<sumrowi Then + norma := sumrowi + End; {i} + kmin1 := -1; + k := 0; + kplus1 := 1; + while k<n Do + Begin + kmin2 := kmin1; + kmin1 := k; + k := kplus1; + kplus1 := kplus1+1; + indk := kmin1*rwidth; + If k>3 Then + Begin + t^[2] := alt^[rwidth+2]*alt^[indk+1]+alt^[2*rwidth+2]*alt^[indk+2]; + For i:=3 To kmin2 Do + Begin + indi := (i-1)*rwidth; + t^[i] := alt^[indi+i-1]*alt^[indk+i-2]+alt^[indi+i] + *alt^[indk+i-1]+alt^[indi+rwidth+i]*alt^[indk+i] + End; {i} + t^[kmin1] := alt^[indk-rwidth+kmin2]*alt^[indk+k-3] + +alt^[indk-rwidth+kmin1]*alt^[indk+kmin2] + +alt^[indk+kmin1]; + h := alt^[indk+k]; + For j:=2 To kmin1 Do + h := h-t^[j]*alt^[indk+j-1]; + t^[k] := h; + alt^[indk+k] := h-alt^[indk+kmin1]*alt^[indk+kmin2] + End {k>3} + Else + If k=3 Then + Begin + t^[2] := alt^[rwidth+2]*alt^[2*rwidth+1]+alt^[2*rwidth+2]; + h := alt^[2*rwidth+3]-t^[2]*alt^[2*rwidth+1]; + t^[3] := h; + alt^[2*rwidth+3] := h-alt^[2*rwidth+2]*alt^[2*rwidth+1] + End {k=3} + Else + If k=2 Then + t^[2] := alt^[rwidth+2]; + maxim := 0; + For i:=kplus1 To n Do + Begin + indi := (i-1)*rwidth; + h := alt^[indi+k]; + For j:=2 To k Do + h := h-t^[j]*alt^[indi+j-1]; + absh := abs(h); + If maxim<absh Then + Begin + maxim := absh; + indexpivot := i + End; {if} + alt^[indi+k] := h + End; {i} + If maxim <> 0 Then + Begin + If indexpivot>kplus1 Then + Begin + indp := (indexpivot-1)*rwidth; + indk := k*rwidth; + p^[kplus1] := indexpivot; + For j:=1 To k Do + Begin + h := alt^[indk+j]; + alt^[indk+j] := alt^[indp+j]; + alt^[indp+j] := h + End; {j} + For j:=indexpivot Downto kplus1 Do + Begin + indj := (j-1)*rwidth; + h := alt^[indj+kplus1]; + alt^[indj+kplus1] := alt^[indp+j]; + alt^[indp+j] := h + End; {j} + For i:=indexpivot To n Do + Begin + indi := (i-1)*rwidth; + h := alt^[indi+kplus1]; + alt^[indi+kplus1] := alt^[indi+indexpivot]; + alt^[indi+indexpivot] := h + End {i} + End; {if} + pivot := alt^[k*rwidth+k]; + For i:=k+2 To n Do + alt^[(i-1)*rwidth+k] := alt^[(i-1)*rwidth+k]/pivot + End {maxim <> 0} + End; {k} + d^[1] := alt^[1]; + i := 1; + while i<n Do + Begin + imin1 := i; + i := i+1; + u^[imin1] := alt^[(i-1)*rwidth+imin1]; + l^[imin1] := u^[imin1]; + d^[i] := alt^[(i-1)*rwidth+i] + End; {i} + mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1], + q^[1], ct, term); + alt^[1] := d1^[1]; + alt^[rwidth+1] := l1^[1]; + alt^[rwidth+2] := d1^[2]; + alt^[2] := u1^[1]; + imin1 := 1; + i := 2; + while i<n Do + Begin + imin2 := imin1; + imin1 := i; + i := i+1; + indi := imin1*rwidth; + alt^[indi+imin1] := l1^[imin1]; + alt^[indi+i] := d1^[i]; + alt^[(imin1-1)*rwidth+i] := u1^[imin1]; + alt^[(imin2-1)*rwidth+i] := v^[imin2] + End; {i} + If term=1 Then + Begin + normr := 0; + For i:=1 To n Do + Begin + t^[i] := 2*random-1; + h := t^[i]; + h := abs(h); + If normr<h Then + normr := h + End; {i} + i := 0; + while i<n Do + Begin + imin1 := i; + i := i+1; + j := 1; + h := t^[i]; + while j<imin1 Do + Begin + jmin1 := j; + j := j+1; + h := h-alt^[(i-1)*rwidth+jmin1]*t^[j] + End; {j} + t^[i] := h + End; {i} + dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term); + i := n+1; + imin1 := n; + normt := 0; + while i>2 Do + Begin + iplus1 := i; + i := imin1; + imin1 := imin1-1; + h := t1^[i]; + For j:=iplus1 To n Do + h := h-alt^[(j-1)*rwidth+imin1]*t1^[j]; + t1^[i] := h; + h := abs(h); + If normt<h Then + normt := h + End; {i} + ca := norma*normt/normr + End {term=1} + Else ca := giant; + freemem(l, nsr); + freemem(d, nsr); + freemem(t, nsr); + freemem(u, nsr); + freemem(v, nsr); + freemem(l1, nsr); + freemem(d1, nsr); + freemem(u1, nsr); + freemem(t1, nsr) +End; {mdtgsy} + +Procedure mdtgpd(n, rwidth: ArbInt; Var al, ca: ArbFloat; Var term: ArbInt); + +Var + posdef : boolean; + i, j, k, kmin1, indk, indi : ArbInt; + h, lkk, normr, normt, sumrowi, norma : ArbFloat; + pal, t : ^arfloat1; +Begin + If (n<1) Or (rwidth<1) Then + Begin + term := 3; + exit + End; {wrong input} + getmem(t, sizeof(ArbFloat)*n); + pal := @al; + normr := 0; + posdef := true; + norma := 0; + For i:=1 To n Do + Begin + sumrowi := 0; + For j:=1 To i Do + sumrowi := sumrowi+abs(pal^[(i-1)*rwidth+j]); + For j:=i+1 To n Do + sumrowi := sumrowi+abs(pal^[(j-1)*rwidth+i]); + If norma<sumrowi Then + norma := sumrowi; + t^[i] := 2*random-1; + h := t^[i]; + h := abs(h); + If normr<h Then + normr := h + End; {i} + k := 0; + while (k<n) and posdef Do + Begin + kmin1 := k; + k := k+1; + indk := (k-1)*rwidth; + lkk := pal^[indk+k]; + For j:=1 To kmin1 Do + lkk := lkk-sqr(pal^[indk+j]); + If lkk <= 0 Then + posdef := false + Else + Begin + pal^[indk+k] := sqrt(lkk); + lkk := pal^[indk+k]; + For i:=k+1 To n Do + Begin + indi := (i-1)*rwidth; + h := pal^[indi+k]; + For j:=1 To kmin1 Do + h := h-pal^[indk+j]*pal^[indi+j]; + pal^[indi+k] := h/lkk + End; {i} + h := t^[k]; + For j:=1 To kmin1 Do + h := h-pal^[indk+j]*t^[j]; + t^[k] := h/lkk + End {posdef} + End; {k} + If posdef Then + Begin + normt := 0; + For i:=n Downto 1 Do + Begin + h := t^[i]; + For j:=i+1 To n Do + h := h-pal^[(j-1)*rwidth+i]*t^[j]; + t^[i] := h/pal^[(i-1)*rwidth+i]; + h := abs(t^[i]); + If normt<h Then + normt := h + End; {i} + ca := norma*normt/normr + End; {posdef} + If posdef Then + term := 1 + Else + term := 2; + freemem(t, sizeof(ArbFloat)*n); +End; {mdtgpd} + +Procedure mdtgba(n, lb, rb, rwa: ArbInt; Var a: ArbFloat; rwl: ArbInt; + Var l:ArbFloat; Var p: ArbInt; Var ca: ArbFloat; Var term:ArbInt); + +Var + sr, i, j, k, ipivot, lbj, lbi, ubi, ls, + ii, jj, ll, jl, ubj : ArbInt; + normr, sumrowi, pivot, normt, maxim, h : ArbFloat; + pl, au, sumrow, t, row : ^arfloat1; + pp : ^arint1; + +Begin + If (n<1) Or (lb<0) Or (rb<0) Or (lb>n-1) Or (rb>n-1) Or (rwl<0) Or (rwa<1) Then + Begin + term := 3; + exit + End; {term=3} + sr := sizeof(ArbFloat); + au := @a; + pl := @l; + pp := @p; + ll := lb+rb+1; + ls := ll*sr; + getmem(sumrow, n*sr); + getmem(t, n*sr); + getmem(row, ls); + lbi := n-rb+1; + lbj := 0; + jj := 1; + For i:=lb Downto 1 Do + Begin + move(au^[i+jj], au^[jj], (ll-i)*sr); + fillchar(au^[jj+ll-i], i*sr, 0); + jj := jj+rwa + End; {i} + jj := (n-rb)*rwa+ll; + For i:=1 To rb Do + Begin + fillchar(au^[jj], i*sr, 0); + jj := jj+rwa-1 + End; {i} + normr := 0; + term := 1; + ii := 1; + For i:=1 To n Do + Begin + pp^[i] := i; + sumrowi := omvn1v(au^[ii], ll); + ii := ii+rwa; + sumrow^[i] := sumrowi; + h := 2*random-1; + t^[i] := sumrowi*h; + h := abs(h); + If normr<h Then + normr := h; + If sumrowi=0 Then + term := 4 + End; {i} + ubi := lb; + jj := 1; + For k:=1 To n Do + Begin + maxim := 0; + ipivot := k; + ii := jj; + If ubi<n Then + ubi := ubi+1; + For i:=k To ubi Do + Begin + sumrowi := sumrow^[i]; + If sumrowi <> 0 Then + Begin + h := abs(au^[ii])/sumrowi; + ii := ii+rwa; + If maxim<h Then + Begin + maxim := h; + ipivot := i + End {maxim<h} + End {sumrowi <> 0} + End; {i} + If maxim=0 Then + Begin + lbj := 1; + ubj := ubi-k; + For j:=lbj To ubj Do + pl^[(k-1)*rwl+j] := 0; + For i:=k+1 To ubi Do + Begin + ii := (i-1)*rwa; + For j:=2 To ll Do + au^[ii+j-1] := au^[ii+j]; + au^[ii+ll] := 0 + End; {i} + term := 4 + End {maxim=0} + Else + Begin + If ipivot <> k Then + Begin + ii := (ipivot-1)*rwa+1; + move(au^[ii], row^, ls); + move(au^[jj], au^[ii], ls); + move(row^, au^[jj], ls); + h := t^[ipivot]; + t^[ipivot] := t^[k]; + t^[k] := h; + pp^[k] := ipivot; + sumrow^[ipivot] := sumrow^[k] + End; {ipivot <> k} + pivot := au^[jj]; + jl := 0; + ii := jj; + For i:=k+1 To ubi Do + Begin + jl := jl+1; + ii := ii+rwa; + h := au^[ii]/pivot; + pl^[(k-1)*rwl+jl] := h; + For j:=0 To ll-2 Do + au^[ii+j] := au^[ii+j+1]-h*au^[jj+j+1]; + au^[ii+ll-1] := 0; + If term=1 Then + t^[i] := t^[i]-h*t^[k] + End {i} + End; {maxim <> 0} + jj := jj+rwa + End; {k} + If term=1 Then + Begin + normt := 0; + ubj := -lb-1; + jj := n*rwa+1; + For i:=n Downto 1 Do + Begin + jj := jj-rwa; + If ubj<rb Then + ubj := ubj+1; + h := t^[i]; + For j:=1 To ubj+lb Do + h := h-au^[jj+j]*t^[i+j]; + t^[i] := h/au^[jj]; + h := abs(t^[i]); + If normt<h Then + normt := h + End; {i} + ca := normt/normr + End {term=1} + Else + ca := giant; + freemem(sumrow, n*sr); + freemem(t, n*sr); + freemem(row, ls) +End; {mdtgba} + +Procedure mdtgpb(n, lb, rwidth: ArbInt; Var al, ca: ArbFloat; + Var term: ArbInt); + +Var + posdef : boolean; + i, j, k, r, p, q, ll, llmin1, jmin1, indi : ArbInt; + h, normr, normt, sumrowi, alim, norma : ArbFloat; + pal, t : ^arfloat1; + + Procedure decomp(i, r: ArbInt); + + Var + k, ii, ir : ArbInt; + Begin + ii := (i-1)*rwidth; + ir := (r-1)*rwidth; + h := pal^[ii+j]; + q := ll-j+p; + For k:=p To jmin1 Do + Begin + h := h-pal^[ii+k]*pal^[ir+q]; + q := q+1 + End; {k} + If j<ll Then + pal^[ii+j] := h/pal^[ir+ll] + End; {decomp} + + Procedure lmin1t(i: ArbInt); + + Var + k:ArbInt; + Begin + h := t^[i]; + q := i; + For k:=llmin1 Downto p Do + Begin + q := q-1; + h := h-pal^[indi+k]*t^[q] + End; {k} + t^[i] := h/alim + End; {lmin1t} + +Begin + If (lb<0) Or (lb>n-1) Or (n<1) Or (rwidth<1) Then + Begin + term := 3; + exit + End; {wrong input} + pal := @al; + getmem(t, n*sizeof(ArbFloat)); + ll := lb+1; + normr := 0; + p := ll+1; + norma := 0; + For i:=1 To n Do + Begin + If p>1 Then + p := p-1; + indi := (i-1)*rwidth+p; + sumrowi := omvn1v(pal^[indi], ll-p+1); + r := i; + j := ll; + while (r<n) and (j>1) Do + Begin + r := r+1; + j := j-1; + sumrowi := sumrowi+abs(pal^[(r-1)*rwidth+j]) + End; {r,j} + If norma<sumrowi Then + norma := sumrowi; + h := 2*random-1; + t^[i] := h; + h := abs(h); + If normr<h Then + normr := h + End; {i} + llmin1 := ll-1; + p := ll+1; + i := 0; + posdef := true ; + while (i<n) and posdef Do + Begin + i := i+1; + indi := (i-1)*rwidth; + If p>1 Then + p := p-1; + r := i-ll+p; + j := p-1; + while j<llmin1 Do + Begin + jmin1 := j; + j := j+1; + decomp(i, r); + r := r+1 + End; {j} + jmin1 := llmin1; + j := ll; + decomp(i, i); + If h <= 0 Then + posdef := false + Else + Begin + alim := sqrt(h); + pal^[indi+ll] := alim; + lmin1t(i) + End + End; {i} + If posdef Then + Begin + normt := 0; + p := ll+1; + For i:=n Downto 1 Do + Begin + If p>1 Then + p := p-1; + q := i; + h := t^[i]; + For k:=llmin1 Downto p Do + Begin + q := q+1; + h := h-pal^[(q-1)*rwidth+k]*t^[q] + End; {k} + t^[i] := h/pal^[(i-1)*rwidth+ll]; + h := abs(t^[i]); + If normt<h Then + normt := h + End; {i} + ca := norma*normt/normr + End; {posdef} + If posdef Then + term := 1 + Else + term := 2; + freemem(t, n*sizeof(ArbFloat)); +End; {mdtgpb} + +Procedure mdtdtr(n: ArbInt; Var l, d, u, l1, d1, u1: ArbFloat; + Var term:ArbInt); + +Var + i, j, s : ArbInt; + lj, di : ArbFloat; + pd, pu, pd1, pu1 : ^arfloat1; + pl, pl1 : ^arfloat2; + +Begin + If n<1 Then + Begin + term := 3; + exit + End; {wrong input} + pl := @l; + pd := @d; + pu := @u; + pl1 := @l1; + pd1 := @d1; + pu1 := @u1; + s := sizeof(ArbFloat); + move(pl^, pl1^, (n-1)*s); + move(pd^, pd1^, n*s); + move(pu^, pu1^, (n-1)*s); + j := 1; + di := pd1^[j]; + If di=0 Then + term := 2 + Else + term := 1; + while (term=1) and (j <> n) Do + Begin + i := j; + j := j+1; + lj := pl1^[j]/di; + pl1^[j] := lj; + di := pd1^[j]-lj*pu1^[i]; + pd1^[j] := di; + If di=0 Then + term := 2 + End {j} +End; {mdtdtr} + +Begin + randseed := 12345 +End. |