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
!! modifies randseed, might not exactly work as TP version!!!
12
Solve set of linear equations of the type Ax=b, for generic, and a
13
variety of special matrices.
15
See the file COPYING.FPC, included in this distribution,
16
for details about the copyright.
18
This program is distributed in the hope that it will be useful,
19
but WITHOUT ANY WARRANTY; without even the implied warranty of
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22
**********************************************************************}
24
{Solve set of linear equations of the type Ax=b, for generic, and a variety of
26
One (generic) function for overdetermined sets of this kind : slegls
28
overdetermined are sets that look like this: (I don't know if I
29
translated "overdetermined" right)
36
The two bottom rows look much alike, which introduces a big uncertainty in the
37
result, therefore these matrices need special treatment.
39
All procedures have similar procedure with a "L" appended to the name. We
40
didn't receive docs for those procedures. If you know what the difference is,
49
{solve for special tridiagonal matrices}
50
Procedure sledtr(n: ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
52
{solve for generic bandmatrices}
53
Procedure slegba(n, l, r: ArbInt;
54
Var a, b, x, ca: ArbFloat; Var term:ArbInt);
56
Procedure slegbal(n, l, r: ArbInt;
57
Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
59
{generic solve for all matrices}
60
Procedure slegen(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
63
Procedure slegenl( n: ArbInt;
65
Var b1, x1, ca: ArbFloat;
68
{solve for overdetermined matrices, see unit comments}
69
Procedure slegls(Var a: ArbFloat; m, n, rwidtha: ArbInt; Var b, x: ArbFloat;
73
Procedure sleglsl(Var a1; m, n: ArbInt; Var b1, x1: ArbFloat;
76
{Symmetrical positive definitive bandmatrices}
77
Procedure slegpb(n, l: ArbInt; Var a, b, x, ca: ArbFloat;
80
Procedure slegpbl(n, l: ArbInt;
81
Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
83
{Symmetrical positive definitive matrices}
84
Procedure slegpd(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
87
Procedure slegpdl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
90
{Symmetrical matrices}
91
Procedure slegsy(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
94
Procedure slegsyl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
97
{tridiagonal matrices}
98
Procedure slegtr(n:ArbInt; Var l, d, u, b, x, ca: ArbFloat;
105
{Here originally stood an exact copy of mdtgtr from unit mdt}
106
{Here originally stood an exact copy of dslgtr from unit DSL}
108
Procedure decomp(Var qr: ArbFloat; m, n, rwidthq: ArbInt; Var alpha: ArbFloat;
109
Var pivot, term: ArbInt);
111
Var i, j, jbar, k, ns, ii : ArbInt;
112
beta, sigma, alphak, qrkk, s : ArbFloat;
113
pqr, pal, y, sum : ^arfloat1;
121
ns := n*sizeof(ArbFloat);
128
s := s+sqr(pqr^[(i-1)*rwidthq+j]);
137
If sigma < sum^[j] Then
146
piv^[k] := piv^[jbar];
148
sum^[jbar] := sum^[k];
154
pqr^[ii+k] := pqr^[ii+jbar];
155
pqr^[ii+jbar] := sigma
157
End; {column interchange}
160
sigma := sigma+sqr(pqr^[(i-1)*rwidthq+k]);
168
qrkk := pqr^[(k-1)*rwidthq+k];
170
alphak := sqrt(sigma)
172
alphak := -sqrt(sigma);
174
beta := 1/(sigma-qrkk*alphak);
175
pqr^[(k-1)*rwidthq+k] := qrkk-alphak;
182
s := s+pqr^[ii+k]*pqr^[ii+j]
191
pqr^[ii+j] := pqr^[ii+j]-pqr^[ii+k]*y^[j]
193
sum^[j] := sum^[j]-sqr(pqr^[(k-1)*rwidthq+j])
200
Procedure decomp1(Var qr1; m, n: ArbInt; Var alpha1: ArbFloat;
201
Var pivot1, term: ArbInt);
203
Var i, j, jbar, k, ns : ArbInt;
204
beta, sigma, alphak, qrkk, s : ArbFloat;
205
qr : ar2dr1 absolute qr1;
206
alpha : arfloat1 absolute alpha1;
207
pivot : arint1 absolute pivot1;
211
ns := n*sizeof(ArbFloat);
218
s := s+sqr(qr[i]^[j]);
237
pivot[k] := pivot[jbar];
239
sum^[jbar] := sum^[k];
244
qr[i]^[k] := qr[i]^[jbar];
245
qr[i]^[jbar] := sigma
247
End; {column interchange}
250
sigma := sigma+sqr(qr[i]^[k]);
260
If qrkk < 0 Then alphak := sqrt(sigma)
261
Else alphak := -sqrt(sigma);
263
beta := 1/(sigma-qrkk*alphak);
264
qr[k]^[k] := qrkk-alphak;
269
s := s+qr[i]^[k]*qr[i]^[j];
275
qr[i]^[j] := qr[i]^[j]-qr[i]^[k]*y^[j];
276
sum^[j] := sum^[j]-sqr(qr[k]^[j])
283
Procedure solve(Var qr: ArbFloat; m, n, rwidthq: ArbInt; Var alpha: ArbFloat;
284
Var pivot: ArbInt; Var r, y: ArbFloat);
286
Var i, j, ii : ArbInt;
288
pqr, pal, pr, py, z : ^arfloat1;
296
getmem(z, n*sizeof(ArbFloat));
301
gamma := gamma+pqr^[(i-1)*rwidthq+j]*pr^[i];
302
gamma := gamma/(pal^[j]*pqr^[(j-1)*rwidthq+j]);
304
pr^[i] := pr^[i]+gamma*pqr^[(i-1)*rwidthq+j]
306
z^[n] := pr^[n]/pal^[n];
307
For i:=n-1 Downto 1 Do
312
s := s-pqr^[ii+j]*z^[j];
316
py^[piv^[i]] := z^[i];
317
freemem(z, n*sizeof(ArbFloat));
320
Procedure solve1(Var qr1; m, n: ArbInt; Var alpha1: ArbFloat;
321
Var pivot1: ArbInt; Var r1, y1: ArbFloat);
325
qr : ar2dr1 absolute qr1;
326
alpha : arfloat1 absolute alpha1;
327
r : arfloat1 absolute r1;
328
y : arfloat1 absolute y1;
329
pivot : arint1 absolute pivot1;
332
getmem(z, n*sizeof(ArbFloat));
337
gamma := gamma+qr[i]^[j]*r[i];
338
gamma := gamma/(alpha[j]*qr[j]^[j]);
340
r[i] := r[i]+gamma*qr[i]^[j]
342
z^[n] := r[n]/alpha[n];
343
For i:=n-1 Downto 1 Do
347
s := s-qr[i]^[j]*z^[j];
351
y[pivot[i]] := z^[i];
352
freemem(z, n*sizeof(ArbFloat));
355
Procedure sledtr(n: ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
357
Var i, j, sr : ArbInt;
359
pd, pu, pb, px, dd : ^arfloat1;
373
sr := sizeof(ArbFloat);
375
move(pb^, px^, n*sr);
384
while (term=1) and (j <> n) Do
389
di := pd^[j]-lj*pu^[i];
395
px^[j] := px^[j]-lj*px^[i]
400
px^[n] := px^[n]/dd^[n];
401
For i:=n-1 Downto 1 Do
402
px^[i] := (px^[i]-pu^[i]*px^[i+1])/dd^[i]
407
Procedure slegba(n, l, r: ArbInt;
408
Var a, b, x, ca: ArbFloat; Var term:ArbInt);
411
sr, i, j, k, ipivot, lbj, lbi, ubi, ls,
412
ii, jj, ll, ubj, rwidth : ArbInt;
413
normr, sumrowi, pivot, normt, maxim, h : ArbFloat;
414
pa, pb, px, au, sumrow, t, row : ^arfloat1;
416
If (n<1) Or (l<0) Or (r<0) Or (l>n-1) Or (r>n-1)
422
sr := sizeof(ArbFloat);
429
getmem(sumrow, n*sr);
432
move(pb^, px^, n*sr);
439
If i <= n-r Then rwidth := r+i
443
If i <= n-r Then rwidth := ll
444
Else rwidth := n-i+l+1;
445
move(pa^[jj], au^[ii], rwidth*sr);
446
fillchar(au^[ii+rwidth], (ll-rwidth)*sr, 0);
457
sumrowi := omvn1v(au^[ii], ll);
459
sumrow^[i] := sumrowi;
463
If normr<h Then normr := h;
464
If sumrowi=0 Then term := 2
469
while (k<n) and (term=1) Do
479
sumrowi := sumrow^[i];
483
h := abs(au^[ii])/sumrowi;
501
ii := (ipivot-1)*ll+1;
502
move(au^[ii], row^, ls);
503
move(au^[jj], au^[ii], ls);
504
move(row^, au^[jj], ls);
509
px^[ipivot] := px^[k];
511
sumrow^[ipivot] := sumrow^[k]
520
au^[ii+j] := au^[ii+j+1]-h*au^[jj+j+1];
522
t^[i] := t^[i]-h*t^[k];
523
px^[i] := px^[i]-h*px^[k];
542
h := h-au^[jj+j]*t^[i+j];
546
h := h-au^[jj+j]*px^[i+j];
556
freemem(sumrow, n*sr);
561
Procedure slegbal(n, l, r: ArbInt;
562
Var a1; Var b1, x1, ca: ArbFloat; Var term:ArbInt);
565
sr, i, j, k, ipivot, ubi, ls,
566
ll, ubj, rwidth : ArbInt;
567
normr, sumrowi, pivot, normt, maxim, h : ArbFloat;
568
a : ar2dr1 absolute a1;
569
b : arfloat1 absolute b1;
570
x : arfloat1 absolute x1;
572
sumrow, t, row : ^arfloat1;
574
If (n<1) Or (l<0) Or (r<0) Or (l>n-1) Or (r>n-1)
580
sr := sizeof(ArbFloat);
583
AllocateAr2dr(n, ll, au);
584
getmem(sumrow, n*sr);
587
move(b[1], x[1], n*sr);
592
If i <= n-r Then rwidth := r+i
596
If i <= n-r Then rwidth := ll
597
Else rwidth := n-i+l+1;
598
move(a[i]^, au^[i]^, rwidth*sr);
599
fillchar(au^[i]^[rwidth+1], (ll-rwidth)*sr, 0);
605
sumrowi := omvn1v(au^[i]^[1], ll);
606
sumrow^[i] := sumrowi;
610
If normr<h Then normr := h;
611
If sumrowi=0 Then term := 2
615
while (k<n) and (term=1) Do
620
If ubi<n Then ubi := ubi+1;
623
sumrowi := sumrow^[i];
626
h := abs(au^[i]^[1])/sumrowi;
634
If maxim=0 Then term := 2
639
move(au^[ipivot]^, row^, ls);
640
move(au^[k]^, au^[ipivot]^, ls);
641
move(row^, au^[k]^, ls);
648
sumrow^[ipivot] := sumrow^[k]
653
h := au^[i]^[1]/pivot;
655
au^[i]^[j+1] := au^[i]^[j+2]-h*au^[k]^[j+2];
657
t^[i] := t^[i]-h*t^[k];
668
If ubj<r Then ubj := ubj+1;
671
h := h-au^[i]^[j+1]*t^[i+j];
672
t^[i] := h/au^[i]^[1];
675
h := h-au^[i]^[j+1]*x[i+j];
676
x[i] := h/au^[i]^[1];
678
If normt<h Then normt := h
682
freemem(sumrow, n*sr);
685
DeAllocateAr2dr(n, ll, au);
688
Procedure slegen(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
692
nsr, i, j, k, ipiv, ip, ik, i1n, k1n : ArbInt;
694
normr, pivot, l, normt, maxim, h, s : ArbFloat;
695
pa, px, pb, au, sumrow, t, row : ^arfloat1;
698
If (n<1) Or (rwidth<1)
704
getmem(au, sqr(n)*sizeof(ArbFloat));
705
nsr := n*sizeof(ArbFloat);
713
move(pa^[1+(i-1)*rwidth], au^[1+(i-1)*n], nsr);
714
move(pb^[1], px^[1], nsr);
719
while (i<n) and (Not singular) Do
722
sumrow^[i] := omvn1v(au^[1+(i-1)*n], n);
729
t^[i] := sumrow^[i]*h;
737
while (k<n) and not singular Do
744
h := abs(au^[k+(i-1)*n])/sumrow^[i];
763
move(au^[ip], row^[1], nsr);
764
move(au^[ik], au^[ip], nsr);
765
move(row^[1], au^[ik], nsr);
772
sumrow^[ipiv] := sumrow^[k]
778
l := au^[k+i1n]/pivot;
783
au^[j+i1n] := au^[j+i1n]-l*au^[j+k1n];
784
t^[i] := t^[i]-l*t^[k];
785
px^[i] := px^[i]-l*px^[k]
799
s := s+t^[j]*au^[j+i1n];
800
t^[i] := (t^[i]-s)/au^[i+i1n];
803
s := s+px^[j]*au^[j+i1n];
804
px^[i] := (px^[i]-s)/au^[i+i1n];
817
freemem(au, sqr(n)*sizeof(ArbFloat));
820
freemem(sumrow, nsr);
823
Procedure slegenl( n: ArbInt;
825
Var b1, x1, ca: ArbFloat;
829
nsr, i, j, k, ipiv : ArbInt;
831
normr, pivot, l, normt, maxim, h, s : ArbFloat;
832
a : ar2dr1 absolute a1;
833
x : arfloat1 absolute x1;
834
b : arfloat1 absolute b1;
836
sumrow, t, row : ^arfloat1;
843
AllocateAr2dr(n, n, au);
844
nsr := n*sizeof(ArbFloat);
849
move(a[i]^, au^[i]^, nsr);
850
move(b[1], x[1], nsr);
855
while (i<n) and (Not singular) Do
858
sumrow^[i] := omvn1v(au^[i]^[1], n);
865
t^[i] := sumrow^[i]*h;
873
while (k<n) and not singular Do
880
h := abs(au^[i]^[k])/sumrow^[i];
896
move(au^[ipiv]^, row^, nsr);
897
move(au^[k]^, au^[ipiv]^, nsr);
898
move(row^, au^[k]^, nsr);
905
sumrow^[ipiv] := sumrow^[k]
910
l := au^[i]^[k]/pivot;
915
au^[i]^[j] := au^[i]^[j]-l*au^[k]^[j];
916
t^[i] := t^[i]-l*t^[k];
930
s := s+t^[j]*au^[i]^[j];
931
t^[i] := (t^[i]-s)/au^[i]^[i];
934
s := s+x[j]*au^[i]^[j];
935
x[i] := (x[i]-s)/au^[i]^[i];
950
freemem(sumrow, nsr);
951
DeAllocateAr2dr(n, n, au);
954
Procedure slegls(Var a: ArbFloat; m, n, rwidtha: ArbInt; Var b, x: ArbFloat;
957
Var i, j, ns, ms, ii : ArbInt;
958
normy0, norme1, s : ArbFloat;
959
pa, pb, px, qr, alpha, e, y, r : ^arfloat1;
971
ns := n*sizeof(ArbFloat);
972
ms := m*sizeof(ArbFloat);
977
getmem(r, m*sizeof(ArbFloat));
978
getmem(pivot, n*sizeof(ArbInt));
980
move(pa^[(i-1)*rwidtha+1], qr^[(i-1)*n+1], ns);
981
decomp(qr^[1], m, n, n, alpha^[1], pivot^[1], term);
989
freemem(r, m*sizeof(ArbFloat));
990
freemem(pivot, n*sizeof(ArbInt));
993
move(pb^[1], r^[1], ms);
994
solve(qr^[1], m, n, n, alpha^[1], pivot^[1], r^[1], y^[1]);
1000
s := s-pa^[ii+j]*y^[j];
1003
solve(qr^[1], m, n, n, alpha^[1], pivot^[1], r^[1], e^[1]);
1008
normy0 := normy0+sqr(y^[i]);
1009
norme1 := norme1+sqr(e^[i])
1011
If norme1 > 0.0625*normy0
1019
freemem(r, m*sizeof(ArbFloat));
1020
freemem(pivot, n*sizeof(ArbInt));
1029
freemem(r, m*sizeof(ArbFloat));
1030
freemem(pivot, n*sizeof(ArbInt));
1033
Procedure sleglsl(Var a1; m, n: ArbInt; Var b1, x1: ArbFloat;
1036
Var i, j, ns, ms : ArbInt;
1037
normy0, norme1, s : ArbFloat;
1038
a : ar2dr1 absolute a1;
1039
b : arfloat1 absolute b1;
1040
x : arfloat1 absolute x1;
1041
alpha, e, y, r : ^arfloat1;
1051
AllocateAr2dr(m, n, qr);
1052
ns := n*sizeof(ArbFloat);
1053
ms := m*sizeof(ArbFloat);
1058
getmem(pivot, n*sizeof(ArbInt));
1060
move(a[i]^, qr^[i]^, ns);
1061
decomp1(qr^[1], m, n, alpha^[1], pivot^[1], term);
1070
freemem(pivot, n*sizeof(ArbInt));
1074
solve1(qr^[1], m, n, alpha^[1], pivot^[1], r^[1], y^[1]);
1079
s := s-a[i]^[j]*y^[j];
1082
solve1(qr^[1], m, n, alpha^[1], pivot^[1], r^[1], e^[1]);
1087
normy0 := normy0+sqr(y^[i]);
1088
norme1 := norme1+sqr(e^[i])
1090
If norme1 > 0.0625*normy0
1098
freemem(r, m*sizeof(ArbFloat));
1099
freemem(pivot, n*sizeof(ArbInt));
1108
freemem(pivot, n*sizeof(ArbInt));
1109
DeAllocateAr2dr(m, n, qr);
1112
Procedure slegpb(n, l: ArbInt; Var a, b, x, ca: ArbFloat;
1117
i, j, k, r, p, q, jmin1, ii, jj, ri, ind,
1118
ll, llm1, sr, rwidth : ArbInt;
1119
h, normr, normt, sumrowi, hh, alim, norma : ArbFloat;
1120
pa, pb, px, al, t, v : ^arfloat1;
1122
Procedure decomp(i, r: ArbInt);
1129
For k:=p To jmin1 Do
1131
h := h-al^[ii+k]*al^[ri+q];
1136
al^[ii+j] := h/al^[ri+ll];
1140
If (n<1) Or (l<0) Or (l>n-1)
1146
sr := sizeof(ArbFloat);
1151
getmem(al, ll*n*sr);
1154
move(pb^, px^, n*sr);
1159
If i>l Then rwidth := ll
1161
move(pa^[jj], al^[ii+ll-rwidth], rwidth*sr);
1174
v^[j] := al^[j+(i-1)*ll];
1175
sumrowi := omvn1v(v^[p], ll-p+1);
1178
while (r<n) and (j>1) Do
1182
sumrowi := sumrowi+abs(al^[j+(r-1)*ll])
1198
while (i<n) and posdef Do
1201
If p>1 Then p := p-1;
1224
For k:=llm1 Downto p Do
1227
h := h-al^[ii+k]*t^[q]
1232
For k:=llm1 Downto p Do
1235
h := h-al^[ii+k]*px^[q]
1245
For i:=n Downto 1 Do
1253
For k:=llm1 Downto p Do
1257
h := h-al^[ind]*t^[q];
1258
hh := hh-al^[ind]*px^[q]
1261
t^[i] := h/al^[ind];
1262
px^[i] := hh/al^[ind];
1268
ca := norma*normt/normr
1275
freemem(al, ll*n*sr);
1280
Procedure slegpbl(n, l: ArbInt;
1281
Var a1; Var b1, x1, ca: ArbFloat; Var term: ArbInt);
1285
i, j, k, r, p, q, ll, sr, rwidth : ArbInt;
1286
h, normr, normt, sumrowi, hh, alim, norma : ArbFloat;
1287
a : ar2dr1 absolute a1;
1288
b : arfloat1 absolute b1;
1289
x : arfloat1 absolute x1;
1293
Procedure decomp(r: ArbInt);
1301
h := h-al^[i]^[k]*al^[r]^[q];
1304
If j<ll Then al^[i]^[j] := h/al^[r]^[ll];
1308
If (n<1) Or (l<0) Or (l>n-1)
1314
sr := sizeof(ArbFloat);
1316
AllocateAr2dr(n, ll, al);
1319
move(b[1], x[1], n*sr);
1322
If i>l Then rwidth := ll
1324
move(a[i]^, al^[i]^[ll-rwidth+1], rwidth*sr);
1333
v^[j] := al^[i]^[j];
1334
sumrowi := omvn1v(v^[p], ll-p+1);
1337
while (r<n) and (j>1) Do
1341
sumrowi := sumrowi+abs(al^[r]^[j])
1343
If norma<sumrowi Then norma := sumrowi;
1347
If normr<h Then normr := h
1352
while (i<n) and posdef Do
1366
If h <= 0 Then posdef := false
1370
al^[i]^[ll] := alim;
1373
For k:=ll-1 Downto p Do
1376
h := h-al^[i]^[k]*t^[q]
1381
For k:=ll-1 Downto p Do
1384
h := h-al^[i]^[k]*x[q]
1394
For i:=n Downto 1 Do
1400
For k:=ll-1 Downto p Do
1403
h := h-al^[q]^[k]*t^[q];
1404
hh := hh-al^[q]^[k]*x[q]
1406
t^[i] := h/al^[i]^[ll];
1407
x[i] := hh/al^[i]^[ll];
1409
If normt<h Then normt := h
1411
ca := norma*normt/normr
1413
If posdef Then term := 1
1417
DeAllocateAr2dr(n, ll, al);
1420
Procedure slegpd(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
1424
sr, i, j, k, kmin1, kk, k1n, i1n, ik, ii : ArbInt;
1426
h, lkk, normr, normt, sumrowi, norma : ArbFloat;
1427
pa, pb, px, al, t : ^arfloat1;
1430
If (n<1) Or (rwidth<1)
1436
sr := sizeof(ArbFloat);
1437
getmem(al, sqr(n)*sr);
1443
move(pa^[1+(i-1)*rwidth], al^[1+(i-1)*n], i*sr);
1444
move(pb^[1], px^[1], n*sr);
1452
sumrowi := sumrowi+abs(al^[j+(i-1)*n]);
1454
sumrowi := sumrowi+abs(al^[i+(j-1)*n]);
1458
t^[i] := 2*random-1;
1465
while (k<n) and pd Do
1472
For j:=1 To kmin1 Do
1473
lkk := lkk-sqr(al^[j+k1n]);
1479
al^[kk] := sqrt(lkk);
1486
For j:=1 To kmin1 Do
1487
h := h-al^[j+k1n]*al^[j+i1n];
1491
For j:=1 To kmin1 Do
1492
h := h-al^[j+k1n]*t^[j];
1495
For j:=1 To kmin1 Do
1496
h := h-al^[j+k1n]*px^[j];
1504
For i:=n Downto 1 Do
1509
h := h-al^[i+(j-1)*n]*t^[j];
1513
h := h-al^[i+(j-1)*n]*px^[j];
1514
px^[i] := h/al^[ii];
1520
ca := norma*normt/normr
1527
freemem(al, sqr(n)*sr);
1531
Procedure slegpdl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
1534
Var sr, i, j, k, kmin1 : ArbInt;
1536
h, lkk, normr, normt, sumrowi, norma : ArbFloat;
1537
a : ar2dr1 absolute a1;
1538
b : arfloat1 absolute b1;
1539
x : arfloat1 absolute x1;
1549
sr := sizeof(ArbFloat);
1550
AllocateL2dr(n, al);
1553
move(a[i]^, al^[i]^, i*sr);
1554
move(b[1], x[1], n*sr);
1562
sumrowi := sumrowi+abs(al^[i]^[j]);
1564
sumrowi := sumrowi+abs(al^[j]^[i]);
1565
If norma<sumrowi Then norma := sumrowi;
1566
t^[i] := 2*random-1;
1568
If normr<h Then normr := h
1571
while (k<n) and pd Do
1576
For j:=1 To kmin1 Do
1577
lkk := lkk-sqr(al^[k]^[j]);
1578
If lkk<=0 Then pd := false
1581
al^[k]^[k] := sqrt(lkk);
1586
For j:=1 To kmin1 Do
1587
h := h-al^[k]^[j]*al^[i]^[j];
1591
For j:=1 To kmin1 Do
1592
h := h-al^[k]^[j]*t^[j];
1595
For j:=1 To kmin1 Do
1596
h := h-al^[k]^[j]*x[j];
1603
For i:=n Downto 1 Do
1607
h := h-al^[j]^[i]*t^[j];
1608
t^[i] := h/al^[i]^[i];
1611
h := h-al^[j]^[i]*x[j];
1612
x[i] := h/al^[i]^[i];
1614
If normt<h Then normt := h
1616
ca := norma*normt/normr
1618
If pd Then term := 1
1620
DeAllocateL2dr(n, al);
1624
Procedure slegsy(n, rwidth: ArbInt; Var a, b, x, ca: ArbFloat;
1628
i, j, kmin1, k, kplus1, kmin2, nsr, nsi, nsb,
1629
imin1, jmin1, indexpivot, iplus1, indi, indj, indk, indp : ArbInt;
1630
h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr, s : ArbFloat;
1631
pa, pb, pb1, px, alt, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1;
1635
If (n<1) Or (rwidth<1)
1644
nsr := n*sizeof(ArbFloat);
1645
nsi := n*sizeof(ArbInt);
1646
nsb := n*sizeof(boolean);
1660
move(pb^, pb1^, nsr);
1665
alt^[indi+j] := pa^[(i-1)*rwidth+j];
1674
sumrowi := sumrowi+abs(alt^[indi+j]);
1676
sumrowi := sumrowi+abs(alt^[(j-1)*n+i]);
1694
t^[2] := alt^[n+2]*alt^[indk+1]+alt^[2*n+2]*alt^[indk+2];
1695
For i:=3 To kmin2 Do
1698
t^[i] := alt^[indi+i-1]*alt^[indk+i-2]+alt^[indi+i]
1699
*alt^[indk+i-1]+alt^[indi+n+i]*alt^[indk+i]
1701
t^[kmin1] := alt^[indk-n+kmin2]*alt^[indk+k-3]
1702
+alt^[indk-n+kmin1]*alt^[indk+kmin2]
1705
For j:=2 To kmin1 Do
1706
h := h-t^[j]*alt^[indk+j-1];
1708
alt^[indk+k] := h-alt^[indk+kmin1]*alt^[indk+kmin2]
1714
t^[2] := alt^[n+2]*alt^[2*n+1]+alt^[2*n+2];
1715
h := alt^[2*n+3]-t^[2]*alt^[2*n+1];
1717
alt^[2*n+3] := h-alt^[2*n+2]*alt^[2*n+1]
1724
For i:=kplus1 To n Do
1729
h := h-t^[j]*alt^[indi+j-1];
1742
If indexpivot>kplus1
1745
indp := (indexpivot-1)*n;
1747
p^[kplus1] := indexpivot;
1751
alt^[indk+j] := alt^[indp+j];
1754
For j:=indexpivot Downto kplus1 Do
1757
h := alt^[indj+kplus1];
1758
alt^[indj+kplus1] := alt^[indp+j];
1761
For i:=indexpivot To n Do
1764
h := alt^[indi+kplus1];
1765
alt^[indi+kplus1] := alt^[indi+indexpivot];
1766
alt^[indi+indexpivot] := h
1769
pivot := alt^[k*n+k];
1771
alt^[(i-1)*n+k] := alt^[(i-1)*n+k]/pivot
1780
u^[imin1] := alt^[(i-1)*n+imin1];
1781
l^[imin1] := u^[imin1];
1782
d^[i] := alt^[(i-1)*n+i]
1784
mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1],
1792
t^[i] := 2*random-1;
1801
indexpivot := p^[i];
1806
pb1^[i] := pb1^[indexpivot];
1807
pb1^[indexpivot] := h
1823
s := s-alt^[indi+jmin1]*pb1^[j];
1824
h := h-alt^[indi+jmin1]*t^[j]
1829
dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], pb1^[1], px^[1], term);
1830
dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term);
1841
For j:=iplus1 To n Do
1843
indj := (j-1)*n+imin1;
1844
h := h-alt^[indj]*t1^[j];
1845
s := s-alt^[indj]*px^[j]
1854
For i:=n Downto 1 Do
1856
indexpivot := p^[i];
1861
px^[i] := px^[indexpivot];
1862
px^[indexpivot] := h
1865
ca := norma*normt/normr
1869
freemem(alt, n*nsr);
1884
Procedure slegsyl(n: ArbInt; Var a1; Var b1, x1, ca: ArbFloat;
1888
i, j, k, nsr, nsi, nsb, indexpivot: ArbInt;
1889
h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr, s : ArbFloat;
1890
a : ar2dr1 absolute a1;
1891
b : arfloat1 absolute b1;
1892
x : arfloat1 absolute x1;
1893
b0, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1;
1903
nsr := n*sizeof(ArbFloat);
1904
nsi := n*sizeof(ArbInt);
1905
nsb := n*sizeof(boolean);
1906
AllocateL2dr(n, alt);
1919
move(b[1], b0^, nsr);
1921
move(a[i]^, alt^[i]^, i*sizeof(ArbFloat));
1928
sumrowi := sumrowi+abs(alt^[i]^[j]);
1930
sumrowi := sumrowi+abs(alt^[j]^[i]);
1931
If norma<sumrowi Then norma := sumrowi
1939
t^[2] := alt^[2]^[2]*alt^[k]^[1]+alt^[3]^[2]*alt^[k]^[2];
1941
t^[i] := alt^[i]^[i-1]*alt^[k]^[i-2]+alt^[i]^[i]
1942
*alt^[k]^[i-1]+alt^[i+1]^[i]*alt^[k]^[i];
1943
t^[k-1] := alt^[k-1]^[k-2]*alt^[k]^[k-3]
1944
+alt^[k-1]^[k-1]*alt^[k]^[k-2]+alt^[k]^[k-1];
1947
h := h-t^[j]*alt^[k]^[j-1];
1949
alt^[k]^[k] := h-alt^[k]^[k-1]*alt^[k]^[k-2]
1955
t^[2] := alt^[2]^[2]*alt^[3]^[1]+alt^[3]^[2];
1956
h := alt^[3]^[3]-t^[2]*alt^[3]^[1];
1958
alt^[3]^[3] := h-alt^[3]^[2]*alt^[3]^[1]
1961
If k=2 Then t^[2] := alt^[2]^[2];
1967
h := h-t^[j]*alt^[i]^[j-1];
1979
If indexpivot>k+1 Then
1981
p^[k+1] := indexpivot;
1985
alt^[k+1]^[j] := alt^[indexpivot]^[j];
1986
alt^[indexpivot]^[j] := h
1988
For j:=indexpivot Downto k+1 Do
1991
alt^[j]^[k+1] := alt^[indexpivot]^[j];
1992
alt^[indexpivot]^[j] := h
1994
For i:=indexpivot To n Do
1997
alt^[i]^[k+1] := alt^[i]^[indexpivot];
1998
alt^[i]^[indexpivot] := h
2001
pivot := alt^[k+1]^[k];
2003
alt^[i]^[k] := alt^[i]^[k]/pivot
2006
d^[1] := alt^[1]^[1];
2011
u^[i-1] := alt^[i]^[i-1];
2013
d^[i] := alt^[i]^[i]
2015
mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1],
2022
t^[i] := 2*random-1;
2025
If normr<h Then normr := h
2029
indexpivot := p^[i];
2034
b0^[i] := b0^[indexpivot];
2035
b0^[indexpivot] := h
2048
s := s-alt^[i]^[j-1]*b0^[j];
2049
h := h-alt^[i]^[j-1]*t^[j]
2054
dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], b0^[1], x[1], term);
2055
dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term);
2065
h := h-alt^[j]^[i-1]*t1^[j];
2066
s := s-alt^[j]^[i-1]*x[j]
2071
If normt<h Then normt := h
2073
For i:=n Downto 1 Do
2075
indexpivot := p^[i];
2076
If indexpivot <> i Then
2079
x[i] := x[indexpivot];
2083
ca := norma*normt/normr
2099
DeAllocateL2dr(n, alt);
2102
Procedure slegtr(n:ArbInt; Var l, d, u, b, x, ca: ArbFloat;
2105
Var singular, ch : boolean;
2106
i, j, nm1, sr, n1s, ns, n2s : ArbInt;
2107
normr, normt, h, lj, di, ui, m : ArbFloat;
2109
pd, pu, pb, px, dd, uu1, u2, t, sumrow : ^arfloat1;
2117
sr := sizeof(ArbFloat);
2133
move(pl^[2], ll^[2], n1s);
2134
move(pd^[1], dd^[1], ns);
2137
move(pu^[1], uu1^[1], n1s);
2138
move(pb^[1], px^[1], ns);
2143
while (i<n) and not singular Do
2149
sumrow^[i] := abs(dd^[1]);
2152
sumrow^[i] := sumrow^[i]+abs(uu1^[1])
2157
sumrow^[i] := abs(ll^[n])+abs(dd^[n])
2159
sumrow^[i] := abs(ll^[i])+abs(dd^[i])+abs(uu1^[i]);
2166
t^[i] := sumrow^[i]*h;
2171
End {sumrow^[i] <> 0}
2174
while (j <> n) and not singular Do
2183
ch := abs(di/sumrow^[i])<abs(lj/sumrow^[j]);
2191
dd^[j] := ui-m*dd^[j];
2196
uu1^[j] := -m*u2^[i]
2198
sumrow^[j] := sumrow^[i];
2204
px^[j] := h-m*px^[i]
2209
dd^[j] := dd^[j]-m*uu1^[i];
2213
t^[j] := t^[j]-m*t^[i];
2214
px^[j] := px^[j]-m*px^[i]
2234
t^[n] := t^[n]/dd^[n];
2235
px^[n] := px^[n]/dd^[n];
2243
t^[nm1] := (t^[nm1]-uu1^[nm1]*t^[n])/dd^[nm1];
2244
px^[nm1] := (px^[nm1]-uu1^[nm1]*px^[n])/dd^[nm1];
2250
For i:=n-2 Downto 1 Do
2252
t^[i] := (t^[i]-uu1^[i]*t^[i+1]-u2^[i]*t^[i+2])/dd^[i];
2253
px^[i] := (px^[i]-uu1^[i]*px^[i+1]-u2^[i]*px^[i+2])/dd^[i];
2271
freemem(sumrow, ns);