mdt.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. {
  2. $Id$
  3. This file is part of the Numlib package.
  4. Copyright (c) 1986-2000 by
  5. Kees van Ginneken, Wil Kortsmit and Loek van Reij of the
  6. Computational centre of the Eindhoven University of Technology
  7. FPC port Code by Marco van de Voort ([email protected])
  8. documentation by Michael van Canneyt ([email protected])
  9. Unit was originally undocumented, but is probably an variant of DET.
  10. Det accepts vectors as arguments, while MDT calculates determinants for
  11. matrices.
  12. Contrary to the other undocumented units, this unit is exported in the
  13. DLL.
  14. See the file COPYING.FPC, included in this distribution,
  15. for details about the copyright.
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  19. **********************************************************************}
  20. Unit mdt;
  21. interface
  22. {$I DIRECT.INC}
  23. uses typ, dsl, omv;
  24. Procedure mdtgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt;
  25. Var ca:ArbFloat; Var term: ArbInt);
  26. Procedure mdtgtr(n: ArbInt; Var l, d, u, l1, d1, u1, u2: ArbFloat;
  27. Var p: boolean; Var ca: ArbFloat; Var term: ArbInt);
  28. Procedure mdtgsy(n, rwidth: ArbInt; Var a: ArbFloat; Var pp:ArbInt;
  29. Var qq:boolean; Var ca:ArbFloat; Var term:ArbInt);
  30. Procedure mdtgpd(n, rwidth: ArbInt; Var al, ca: ArbFloat; Var term: ArbInt);
  31. Procedure mdtgba(n, lb, rb, rwa: ArbInt; Var a: ArbFloat; rwl: ArbInt;
  32. Var l:ArbFloat; Var p: ArbInt; Var ca: ArbFloat; Var term:ArbInt);
  33. Procedure mdtgpb(n, lb, rwidth: ArbInt; Var al, ca: ArbFloat;
  34. Var term: ArbInt);
  35. Procedure mdtdtr(n: ArbInt; Var l, d, u, l1, d1, u1: ArbFloat;
  36. Var term:ArbInt);
  37. implementation
  38. Procedure mdtgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt;
  39. Var ca:ArbFloat; Var term: ArbInt);
  40. Var
  41. indi, indk, nsr, ind, i, j, k, indexpivot : ArbInt;
  42. normr, sumrowi, pivot, l, normt, maxim, h, s : ArbFloat;
  43. palu, sumrow, t : ^arfloat1;
  44. pp : ^arint1;
  45. singular : boolean;
  46. Begin
  47. If (n<1) Or (rwidth<1) Then
  48. Begin
  49. term := 3;
  50. exit
  51. End; {wrong input}
  52. palu := @alu;
  53. pp := @p;
  54. nsr := n*sizeof(ArbFloat);
  55. getmem(sumrow, nsr);
  56. getmem(t, nsr);
  57. normr := 0;
  58. singular := false ;
  59. For i:=1 To n Do
  60. Begin
  61. ind := (i-1)*rwidth;
  62. pp^[i] := i;
  63. sumrowi := 0;
  64. For j:=1 To n Do
  65. sumrowi := sumrowi+abs(palu^[ind+j]);
  66. sumrow^[i] := sumrowi;
  67. h := 2*random-1;
  68. t^[i] := sumrowi*h;
  69. h := abs(h);
  70. If normr<h Then normr := h;
  71. If sumrowi=0 Then
  72. singular := true
  73. End; {i}
  74. For k:=1 To n Do
  75. Begin
  76. maxim := 0;
  77. indexpivot := k;
  78. For i:=k To n Do
  79. Begin
  80. ind := (i-1)*rwidth;
  81. sumrowi := sumrow^[i];
  82. If sumrowi <> 0 Then
  83. Begin
  84. h := abs(palu^[ind+k])/sumrowi;
  85. If maxim<h Then
  86. Begin
  87. maxim := h;
  88. indexpivot := i
  89. End {maxim<h}
  90. End {sumrow <> 0}
  91. End; {i}
  92. If maxim=0 Then
  93. singular := true
  94. Else
  95. Begin
  96. If indexpivot <> k Then
  97. Begin
  98. ind := (indexpivot-1)*rwidth;
  99. indk := (k-1)*rwidth;
  100. For j:=1 To n Do
  101. Begin
  102. h := palu^[ind+j];
  103. palu^[ind+j] := palu^[indk+j];
  104. palu^[indk+j] := h
  105. End; {j}
  106. h := t^[indexpivot];
  107. t^[indexpivot] := t^[k];
  108. t^[k] := h;
  109. pp^[k] := indexpivot;
  110. sumrow^[indexpivot] := sumrow^[k]
  111. End; {indexpivot <> k}
  112. pivot := palu^[(k-1)*rwidth+k];
  113. For i:=k+1 To n Do
  114. Begin
  115. ind := (i-1)*rwidth;
  116. l := palu^[ind+k]/pivot;
  117. palu^[ind+k] := l;
  118. If l <> 0 Then
  119. Begin
  120. For j:=k+1 To n Do
  121. palu^[ind+j] := palu^[ind+j]-l*palu^[(k-1)*rwidth+j];
  122. If Not singular Then
  123. t^[i] := t^[i]-l*t^[k]
  124. End {l <> 0}
  125. End {i}
  126. End {maxim <> 0}
  127. End; {k}
  128. If Not singular Then
  129. Begin
  130. normt := 0;
  131. For i:=n Downto 1 Do
  132. Begin
  133. indi := (i-1)*rwidth;
  134. s := 0;
  135. For j:=i+1 To n Do
  136. s := s+t^[j]*palu^[indi+j];
  137. t^[i] := (t^[i]-s)/palu^[indi+i];
  138. h := abs(t^[i]);
  139. If normt<h Then
  140. normt := h
  141. End; {i}
  142. ca := normt/normr
  143. End; {not singular}
  144. If singular Then
  145. Begin
  146. term := 4;
  147. ca := giant
  148. End
  149. Else
  150. term := 1;
  151. freemem(sumrow, nsr);
  152. freemem(t, nsr)
  153. End; {mdtgen}
  154. Procedure mdtgtr(n: ArbInt; Var l, d, u, l1, d1, u1, u2: ArbFloat;
  155. Var p: boolean; Var ca: ArbFloat; Var term: ArbInt);
  156. Var
  157. i, j, k, nmin1, sr : ArbInt;
  158. normr, normt, sumrowi, h, lj, di, ui, ll : ArbFloat;
  159. sing : boolean;
  160. pd, pu, pd1, pu1, pu2, t, sumrow : ^arfloat1;
  161. pl, pl1 : ^arfloat2;
  162. pp : ^arbool1;
  163. Begin
  164. If n<1 Then
  165. Begin
  166. term := 3;
  167. exit
  168. End; {wrong input}
  169. pl := @l;
  170. pd := @d;
  171. pu := @u;
  172. pl1 := @l1;
  173. pd1 := @d1;
  174. pu1 := @u1;
  175. pu2 := @u2;
  176. pp := @p;
  177. sr := sizeof(ArbFloat);
  178. move(pl^, pl1^, (n-1)*sr);
  179. move(pd^, pd1^, n*sr);
  180. move(pu^, pu1^, (n-1)*sr);
  181. getmem(t, n*sr);
  182. getmem(sumrow, n*sr);
  183. normr := 0;
  184. sing := false;
  185. nmin1 := n-1;
  186. For i:=1 To n Do
  187. Begin
  188. pp^[i] := false;
  189. If i=1 Then
  190. sumrowi := abs(pd^[1])+abs(pu^[1])
  191. Else
  192. If i=n Then
  193. sumrowi := abs(pl^[n])+abs(pd^[n])
  194. Else
  195. sumrowi := abs(pl^[i])+abs(pd^[i])+abs(pu^[i]);
  196. sumrow^[i] := sumrowi;
  197. h := 2*random-1;
  198. t^[i] := sumrowi*h;
  199. h := abs(h);
  200. If normr<h Then
  201. normr := h;
  202. If sumrowi=0 Then
  203. sing := true
  204. End; {i}
  205. j := 1;
  206. while (j <> n) Do
  207. Begin
  208. i := j;
  209. j := j+1;
  210. lj := pl1^[j];
  211. If lj <> 0 Then
  212. Begin
  213. di := pd1^[i];
  214. If di=0 Then
  215. pp^[i] := true
  216. Else
  217. pp^[i] := abs(di/sumrow^[i])<abs(lj/sumrow^[j]);
  218. If pp^[i] Then
  219. Begin
  220. ui := pu1^[i];
  221. pd1^[i] := lj;
  222. pu1^[i] := pd1^[j];
  223. pl1^[j] := di/lj;
  224. ll := pl1^[j];
  225. pd1^[j] := ui-ll*pd1^[j];
  226. If i<nmin1 Then
  227. Begin
  228. pu2^[i] := pu1^[j];
  229. pu1^[j] := -ll*pu2^[i]
  230. End; {i<nmin1}
  231. sumrow^[j] := sumrow^[i];
  232. If (Not sing) Then
  233. Begin
  234. h := t^[i];
  235. t^[i] := t^[j];
  236. t^[j] := h-ll*t^[i]
  237. End {not sing}
  238. End {pp^[i]}
  239. Else
  240. Begin
  241. pl1^[j] := lj/di;
  242. ll := pl1^[j];
  243. pd1^[j] := pd1^[j]-ll*pu1^[i];
  244. If i<nmin1 Then
  245. pu2^[i] := 0;
  246. If (Not sing) Then
  247. t^[j] := t^[j]-ll*t^[i]
  248. End {not pp^[i]}
  249. End {lj<>0}
  250. Else
  251. Begin
  252. If i<nmin1 Then
  253. pu2^[i] := 0;
  254. If pd1^[i]=0 Then
  255. sing := true
  256. End {lj=0}
  257. End; {j}
  258. If pd1^[n]=0 Then
  259. sing := true;
  260. If (Not sing) Then
  261. Begin
  262. normt := 0;
  263. t^[n] := t^[n]/pd1^[n];
  264. h := abs(t^[n]);
  265. If normt<h Then
  266. normt := h;
  267. If n > 1 Then
  268. Begin
  269. t^[nmin1] := (t^[nmin1]-pu1^[nmin1]*t^[n])/pd1^[nmin1];
  270. h := abs(t^[nmin1])
  271. End; {n > 1}
  272. If normt<h Then
  273. normt := h;
  274. For i:=n-2 Downto 1 Do
  275. Begin
  276. t^[i] := (t^[i]-pu1^[i]*t^[i+1]-pu2^[i]*t^[i+2])/pd1^[i];
  277. h := abs(t^[i]);
  278. If normt<h Then
  279. normt := h
  280. End; {i}
  281. ca := normt/normr
  282. End; {not sing}
  283. If (sing) Then
  284. Begin
  285. term := 4;
  286. ca := giant
  287. End {sing}
  288. Else
  289. term := 1;
  290. freemem(t, n*sr);
  291. freemem(sumrow, n*sr)
  292. End; {mdtgtr}
  293. Procedure mdtgsy(n, rwidth: ArbInt; Var a: ArbFloat; Var pp:ArbInt;
  294. Var qq:boolean; Var ca:ArbFloat; Var term:ArbInt);
  295. Var
  296. i, j, kmin1, k, kplus1, kmin2, imin2, nsr, nsi, nsb, ii,
  297. imin1, jmin1, indexpivot, iplus1, indi, indj, indk, indp : ArbInt;
  298. ra, h, absh, maxim, pivot, ct, norma, sumrowi, normt, normr, s : ArbFloat;
  299. alt, l, d, t, u, v, l1, d1, u1, t1 : ^arfloat1;
  300. p : ^arint1;
  301. q : ^arbool1;
  302. Begin
  303. If (n<1) Or (rwidth<1) Then
  304. Begin
  305. term := 3;
  306. exit
  307. End; {if}
  308. alt := @a;
  309. p := @pp;
  310. q := @qq;
  311. nsr := n*sizeof(ArbFloat);
  312. nsi := n*sizeof(ArbInt);
  313. nsb := n*sizeof(boolean);
  314. getmem(l, nsr);
  315. getmem(d, nsr);
  316. getmem(t, nsr);
  317. getmem(u, nsr);
  318. getmem(v, nsr);
  319. getmem(l1, nsr);
  320. getmem(d1, nsr);
  321. getmem(u1, nsr);
  322. getmem(t1, nsr);
  323. norma := 0;
  324. For i:=1 To n Do
  325. Begin
  326. indi := (i-1)*rwidth;
  327. p^[i] := i;
  328. sumrowi := 0;
  329. For j:=1 To i Do
  330. sumrowi := sumrowi+abs(alt^[indi+j]);
  331. For j:=i+1 To n Do
  332. sumrowi := sumrowi+abs(alt^[(j-1)*rwidth+i]);
  333. If norma<sumrowi Then
  334. norma := sumrowi
  335. End; {i}
  336. kmin1 := -1;
  337. k := 0;
  338. kplus1 := 1;
  339. while k<n Do
  340. Begin
  341. kmin2 := kmin1;
  342. kmin1 := k;
  343. k := kplus1;
  344. kplus1 := kplus1+1;
  345. indk := kmin1*rwidth;
  346. If k>3 Then
  347. Begin
  348. t^[2] := alt^[rwidth+2]*alt^[indk+1]+alt^[2*rwidth+2]*alt^[indk+2];
  349. For i:=3 To kmin2 Do
  350. Begin
  351. indi := (i-1)*rwidth;
  352. t^[i] := alt^[indi+i-1]*alt^[indk+i-2]+alt^[indi+i]
  353. *alt^[indk+i-1]+alt^[indi+rwidth+i]*alt^[indk+i]
  354. End; {i}
  355. t^[kmin1] := alt^[indk-rwidth+kmin2]*alt^[indk+k-3]
  356. +alt^[indk-rwidth+kmin1]*alt^[indk+kmin2]
  357. +alt^[indk+kmin1];
  358. h := alt^[indk+k];
  359. For j:=2 To kmin1 Do
  360. h := h-t^[j]*alt^[indk+j-1];
  361. t^[k] := h;
  362. alt^[indk+k] := h-alt^[indk+kmin1]*alt^[indk+kmin2]
  363. End {k>3}
  364. Else
  365. If k=3 Then
  366. Begin
  367. t^[2] := alt^[rwidth+2]*alt^[2*rwidth+1]+alt^[2*rwidth+2];
  368. h := alt^[2*rwidth+3]-t^[2]*alt^[2*rwidth+1];
  369. t^[3] := h;
  370. alt^[2*rwidth+3] := h-alt^[2*rwidth+2]*alt^[2*rwidth+1]
  371. End {k=3}
  372. Else
  373. If k=2 Then
  374. t^[2] := alt^[rwidth+2];
  375. maxim := 0;
  376. For i:=kplus1 To n Do
  377. Begin
  378. indi := (i-1)*rwidth;
  379. h := alt^[indi+k];
  380. For j:=2 To k Do
  381. h := h-t^[j]*alt^[indi+j-1];
  382. absh := abs(h);
  383. If maxim<absh Then
  384. Begin
  385. maxim := absh;
  386. indexpivot := i
  387. End; {if}
  388. alt^[indi+k] := h
  389. End; {i}
  390. If maxim <> 0 Then
  391. Begin
  392. If indexpivot>kplus1 Then
  393. Begin
  394. indp := (indexpivot-1)*rwidth;
  395. indk := k*rwidth;
  396. p^[kplus1] := indexpivot;
  397. For j:=1 To k Do
  398. Begin
  399. h := alt^[indk+j];
  400. alt^[indk+j] := alt^[indp+j];
  401. alt^[indp+j] := h
  402. End; {j}
  403. For j:=indexpivot Downto kplus1 Do
  404. Begin
  405. indj := (j-1)*rwidth;
  406. h := alt^[indj+kplus1];
  407. alt^[indj+kplus1] := alt^[indp+j];
  408. alt^[indp+j] := h
  409. End; {j}
  410. For i:=indexpivot To n Do
  411. Begin
  412. indi := (i-1)*rwidth;
  413. h := alt^[indi+kplus1];
  414. alt^[indi+kplus1] := alt^[indi+indexpivot];
  415. alt^[indi+indexpivot] := h
  416. End {i}
  417. End; {if}
  418. pivot := alt^[k*rwidth+k];
  419. For i:=k+2 To n Do
  420. alt^[(i-1)*rwidth+k] := alt^[(i-1)*rwidth+k]/pivot
  421. End {maxim <> 0}
  422. End; {k}
  423. d^[1] := alt^[1];
  424. i := 1;
  425. while i<n Do
  426. Begin
  427. imin1 := i;
  428. i := i+1;
  429. u^[imin1] := alt^[(i-1)*rwidth+imin1];
  430. l^[imin1] := u^[imin1];
  431. d^[i] := alt^[(i-1)*rwidth+i]
  432. End; {i}
  433. mdtgtr(n, l^[1], d^[1], u^[1], l1^[1], d1^[1], u1^[1], v^[1],
  434. q^[1], ct, term);
  435. alt^[1] := d1^[1];
  436. alt^[rwidth+1] := l1^[1];
  437. alt^[rwidth+2] := d1^[2];
  438. alt^[2] := u1^[1];
  439. imin1 := 1;
  440. i := 2;
  441. while i<n Do
  442. Begin
  443. imin2 := imin1;
  444. imin1 := i;
  445. i := i+1;
  446. indi := imin1*rwidth;
  447. alt^[indi+imin1] := l1^[imin1];
  448. alt^[indi+i] := d1^[i];
  449. alt^[(imin1-1)*rwidth+i] := u1^[imin1];
  450. alt^[(imin2-1)*rwidth+i] := v^[imin2]
  451. End; {i}
  452. If term=1 Then
  453. Begin
  454. normr := 0;
  455. For i:=1 To n Do
  456. Begin
  457. t^[i] := 2*random-1;
  458. h := t^[i];
  459. h := abs(h);
  460. If normr<h Then
  461. normr := h
  462. End; {i}
  463. i := 0;
  464. while i<n Do
  465. Begin
  466. imin1 := i;
  467. i := i+1;
  468. j := 1;
  469. h := t^[i];
  470. while j<imin1 Do
  471. Begin
  472. jmin1 := j;
  473. j := j+1;
  474. h := h-alt^[(i-1)*rwidth+jmin1]*t^[j]
  475. End; {j}
  476. t^[i] := h
  477. End; {i}
  478. dslgtr(n, l1^[1], d1^[1], u1^[1], v^[1], q^[1], t^[1], t1^[1], term);
  479. i := n+1;
  480. imin1 := n;
  481. normt := 0;
  482. while i>2 Do
  483. Begin
  484. iplus1 := i;
  485. i := imin1;
  486. imin1 := imin1-1;
  487. h := t1^[i];
  488. For j:=iplus1 To n Do
  489. h := h-alt^[(j-1)*rwidth+imin1]*t1^[j];
  490. t1^[i] := h;
  491. h := abs(h);
  492. If normt<h Then
  493. normt := h
  494. End; {i}
  495. ca := norma*normt/normr
  496. End {term=1}
  497. Else ca := giant;
  498. freemem(l, nsr);
  499. freemem(d, nsr);
  500. freemem(t, nsr);
  501. freemem(u, nsr);
  502. freemem(v, nsr);
  503. freemem(l1, nsr);
  504. freemem(d1, nsr);
  505. freemem(u1, nsr);
  506. freemem(t1, nsr)
  507. End; {mdtgsy}
  508. Procedure mdtgpd(n, rwidth: ArbInt; Var al, ca: ArbFloat; Var term: ArbInt);
  509. Var
  510. posdef : boolean;
  511. i, j, k, kmin1, indk, indi : ArbInt;
  512. h, lkk, normr, normt, sumrowi, norma : ArbFloat;
  513. pal, t : ^arfloat1;
  514. Begin
  515. If (n<1) Or (rwidth<1) Then
  516. Begin
  517. term := 3;
  518. exit
  519. End; {wrong input}
  520. getmem(t, sizeof(ArbFloat)*n);
  521. pal := @al;
  522. normr := 0;
  523. posdef := true;
  524. norma := 0;
  525. For i:=1 To n Do
  526. Begin
  527. sumrowi := 0;
  528. For j:=1 To i Do
  529. sumrowi := sumrowi+abs(pal^[(i-1)*rwidth+j]);
  530. For j:=i+1 To n Do
  531. sumrowi := sumrowi+abs(pal^[(j-1)*rwidth+i]);
  532. If norma<sumrowi Then
  533. norma := sumrowi;
  534. t^[i] := 2*random-1;
  535. h := t^[i];
  536. h := abs(h);
  537. If normr<h Then
  538. normr := h
  539. End; {i}
  540. k := 0;
  541. while (k<n) and posdef Do
  542. Begin
  543. kmin1 := k;
  544. k := k+1;
  545. indk := (k-1)*rwidth;
  546. lkk := pal^[indk+k];
  547. For j:=1 To kmin1 Do
  548. lkk := lkk-sqr(pal^[indk+j]);
  549. If lkk <= 0 Then
  550. posdef := false
  551. Else
  552. Begin
  553. pal^[indk+k] := sqrt(lkk);
  554. lkk := pal^[indk+k];
  555. For i:=k+1 To n Do
  556. Begin
  557. indi := (i-1)*rwidth;
  558. h := pal^[indi+k];
  559. For j:=1 To kmin1 Do
  560. h := h-pal^[indk+j]*pal^[indi+j];
  561. pal^[indi+k] := h/lkk
  562. End; {i}
  563. h := t^[k];
  564. For j:=1 To kmin1 Do
  565. h := h-pal^[indk+j]*t^[j];
  566. t^[k] := h/lkk
  567. End {posdef}
  568. End; {k}
  569. If posdef Then
  570. Begin
  571. normt := 0;
  572. For i:=n Downto 1 Do
  573. Begin
  574. h := t^[i];
  575. For j:=i+1 To n Do
  576. h := h-pal^[(j-1)*rwidth+i]*t^[j];
  577. t^[i] := h/pal^[(i-1)*rwidth+i];
  578. h := abs(t^[i]);
  579. If normt<h Then
  580. normt := h
  581. End; {i}
  582. ca := norma*normt/normr
  583. End; {posdef}
  584. If posdef Then
  585. term := 1
  586. Else
  587. term := 2;
  588. freemem(t, sizeof(ArbFloat)*n);
  589. End; {mdtgpd}
  590. Procedure mdtgba(n, lb, rb, rwa: ArbInt; Var a: ArbFloat; rwl: ArbInt;
  591. Var l:ArbFloat; Var p: ArbInt; Var ca: ArbFloat; Var term:ArbInt);
  592. Var
  593. sr, i, j, k, ipivot, m, lbj, lbi, ubi, ls,
  594. ii, jj, ll, s, js, jl, ubj : ArbInt;
  595. ra, normr, sumrowi, pivot, normt, maxim, h : ArbFloat;
  596. pl, au, sumrow, t, row : ^arfloat1;
  597. pp : ^arint1;
  598. Begin
  599. If (n<1) Or (lb<0) Or (rb<0) Or (lb>n-1) Or (rb>n-1) Or (rwl<0) Or (rwa<1) Then
  600. Begin
  601. term := 3;
  602. exit
  603. End; {term=3}
  604. sr := sizeof(ArbFloat);
  605. au := @a;
  606. pl := @l;
  607. pp := @p;
  608. ll := lb+rb+1;
  609. ls := ll*sr;
  610. getmem(sumrow, n*sr);
  611. getmem(t, n*sr);
  612. getmem(row, ls);
  613. lbi := n-rb+1;
  614. lbj := 0;
  615. jj := 1;
  616. For i:=lb Downto 1 Do
  617. Begin
  618. move(au^[i+jj], au^[jj], (ll-i)*sr);
  619. fillchar(au^[jj+ll-i], i*sr, 0);
  620. jj := jj+rwa
  621. End; {i}
  622. jj := (n-rb)*rwa+ll;
  623. For i:=1 To rb Do
  624. Begin
  625. fillchar(au^[jj], i*sr, 0);
  626. jj := jj+rwa-1
  627. End; {i}
  628. normr := 0;
  629. term := 1;
  630. ii := 1;
  631. For i:=1 To n Do
  632. Begin
  633. pp^[i] := i;
  634. sumrowi := omvn1v(au^[ii], ll);
  635. ii := ii+rwa;
  636. sumrow^[i] := sumrowi;
  637. h := 2*random-1;
  638. t^[i] := sumrowi*h;
  639. h := abs(h);
  640. If normr<h Then
  641. normr := h;
  642. If sumrowi=0 Then
  643. term := 4
  644. End; {i}
  645. ubi := lb;
  646. jj := 1;
  647. For k:=1 To n Do
  648. Begin
  649. maxim := 0;
  650. ipivot := k;
  651. ii := jj;
  652. If ubi<n Then
  653. ubi := ubi+1;
  654. For i:=k To ubi Do
  655. Begin
  656. sumrowi := sumrow^[i];
  657. If sumrowi <> 0 Then
  658. Begin
  659. h := abs(au^[ii])/sumrowi;
  660. ii := ii+rwa;
  661. If maxim<h Then
  662. Begin
  663. maxim := h;
  664. ipivot := i
  665. End {maxim<h}
  666. End {sumrowi <> 0}
  667. End; {i}
  668. If maxim=0 Then
  669. Begin
  670. lbj := 1;
  671. ubj := ubi-k;
  672. For j:=lbj To ubj Do
  673. pl^[(k-1)*rwl+j] := 0;
  674. For i:=k+1 To ubi Do
  675. Begin
  676. ii := (i-1)*rwa;
  677. For j:=2 To ll Do
  678. au^[ii+j-1] := au^[ii+j];
  679. au^[ii+ll] := 0
  680. End; {i}
  681. term := 4
  682. End {maxim=0}
  683. Else
  684. Begin
  685. If ipivot <> k Then
  686. Begin
  687. ii := (ipivot-1)*rwa+1;
  688. move(au^[ii], row^, ls);
  689. move(au^[jj], au^[ii], ls);
  690. move(row^, au^[jj], ls);
  691. h := t^[ipivot];
  692. t^[ipivot] := t^[k];
  693. t^[k] := h;
  694. pp^[k] := ipivot;
  695. sumrow^[ipivot] := sumrow^[k]
  696. End; {ipivot <> k}
  697. pivot := au^[jj];
  698. jl := 0;
  699. ii := jj;
  700. For i:=k+1 To ubi Do
  701. Begin
  702. jl := jl+1;
  703. ii := ii+rwa;
  704. h := au^[ii]/pivot;
  705. pl^[(k-1)*rwl+jl] := h;
  706. For j:=0 To ll-2 Do
  707. au^[ii+j] := au^[ii+j+1]-h*au^[jj+j+1];
  708. au^[ii+ll-1] := 0;
  709. If term=1 Then
  710. t^[i] := t^[i]-h*t^[k]
  711. End {i}
  712. End; {maxim <> 0}
  713. jj := jj+rwa
  714. End; {k}
  715. If term=1 Then
  716. Begin
  717. normt := 0;
  718. ubj := -lb-1;
  719. jj := n*rwa+1;
  720. For i:=n Downto 1 Do
  721. Begin
  722. jj := jj-rwa;
  723. If ubj<rb Then
  724. ubj := ubj+1;
  725. h := t^[i];
  726. For j:=1 To ubj+lb Do
  727. h := h-au^[jj+j]*t^[i+j];
  728. t^[i] := h/au^[jj];
  729. h := abs(t^[i]);
  730. If normt<h Then
  731. normt := h
  732. End; {i}
  733. ca := normt/normr
  734. End {term=1}
  735. Else
  736. ca := giant;
  737. freemem(sumrow, n*sr);
  738. freemem(t, n*sr);
  739. freemem(row, ls)
  740. End; {mdtgba}
  741. Procedure mdtgpb(n, lb, rwidth: ArbInt; Var al, ca: ArbFloat;
  742. Var term: ArbInt);
  743. Var
  744. posdef : boolean;
  745. i, j, k, r, p, q, ll, llmin1, jmin1, indi : ArbInt;
  746. h, normr, normt, sumrowi, alim, norma : ArbFloat;
  747. pal, t : ^arfloat1;
  748. Procedure decomp(i, r: ArbInt);
  749. Var
  750. k, ii, ir : ArbInt;
  751. Begin
  752. ii := (i-1)*rwidth;
  753. ir := (r-1)*rwidth;
  754. h := pal^[ii+j];
  755. q := ll-j+p;
  756. For k:=p To jmin1 Do
  757. Begin
  758. h := h-pal^[ii+k]*pal^[ir+q];
  759. q := q+1
  760. End; {k}
  761. If j<ll Then
  762. pal^[ii+j] := h/pal^[ir+ll]
  763. End; {decomp}
  764. Procedure lmin1t(i: ArbInt);
  765. Var
  766. k:ArbInt;
  767. Begin
  768. h := t^[i];
  769. q := i;
  770. For k:=llmin1 Downto p Do
  771. Begin
  772. q := q-1;
  773. h := h-pal^[indi+k]*t^[q]
  774. End; {k}
  775. t^[i] := h/alim
  776. End; {lmin1t}
  777. Begin
  778. If (lb<0) Or (lb>n-1) Or (n<1) Or (rwidth<1) Then
  779. Begin
  780. term := 3;
  781. exit
  782. End; {wrong input}
  783. pal := @al;
  784. getmem(t, n*sizeof(ArbFloat));
  785. ll := lb+1;
  786. normr := 0;
  787. p := ll+1;
  788. norma := 0;
  789. For i:=1 To n Do
  790. Begin
  791. If p>1 Then
  792. p := p-1;
  793. indi := (i-1)*rwidth+p;
  794. sumrowi := omvn1v(pal^[indi], ll-p+1);
  795. r := i;
  796. j := ll;
  797. while (r<n) and (j>1) Do
  798. Begin
  799. r := r+1;
  800. j := j-1;
  801. sumrowi := sumrowi+abs(pal^[(r-1)*rwidth+j])
  802. End; {r,j}
  803. If norma<sumrowi Then
  804. norma := sumrowi;
  805. h := 2*random-1;
  806. t^[i] := h;
  807. h := abs(h);
  808. If normr<h Then
  809. normr := h
  810. End; {i}
  811. llmin1 := ll-1;
  812. p := ll+1;
  813. i := 0;
  814. posdef := true ;
  815. while (i<n) and posdef Do
  816. Begin
  817. i := i+1;
  818. indi := (i-1)*rwidth;
  819. If p>1 Then
  820. p := p-1;
  821. r := i-ll+p;
  822. j := p-1;
  823. while j<llmin1 Do
  824. Begin
  825. jmin1 := j;
  826. j := j+1;
  827. decomp(i, r);
  828. r := r+1
  829. End; {j}
  830. jmin1 := llmin1;
  831. j := ll;
  832. decomp(i, i);
  833. If h <= 0 Then
  834. posdef := false
  835. Else
  836. Begin
  837. alim := sqrt(h);
  838. pal^[indi+ll] := alim;
  839. lmin1t(i)
  840. End
  841. End; {i}
  842. If posdef Then
  843. Begin
  844. normt := 0;
  845. p := ll+1;
  846. For i:=n Downto 1 Do
  847. Begin
  848. If p>1 Then
  849. p := p-1;
  850. q := i;
  851. h := t^[i];
  852. For k:=llmin1 Downto p Do
  853. Begin
  854. q := q+1;
  855. h := h-pal^[(q-1)*rwidth+k]*t^[q]
  856. End; {k}
  857. t^[i] := h/pal^[(i-1)*rwidth+ll];
  858. h := abs(t^[i]);
  859. If normt<h Then
  860. normt := h
  861. End; {i}
  862. ca := norma*normt/normr
  863. End; {posdef}
  864. If posdef Then
  865. term := 1
  866. Else
  867. term := 2;
  868. freemem(t, n*sizeof(ArbFloat));
  869. End; {mdtgpb}
  870. Procedure mdtdtr(n: ArbInt; Var l, d, u, l1, d1, u1: ArbFloat;
  871. Var term:ArbInt);
  872. Var
  873. i, j, s : ArbInt;
  874. lj, di : ArbFloat;
  875. pd, pu, pd1, pu1 : ^arfloat1;
  876. pl, pl1 : ^arfloat2;
  877. Begin
  878. If n<1 Then
  879. Begin
  880. term := 3;
  881. exit
  882. End; {wrong input}
  883. pl := @l;
  884. pd := @d;
  885. pu := @u;
  886. pl1 := @l1;
  887. pd1 := @d1;
  888. pu1 := @u1;
  889. s := sizeof(ArbFloat);
  890. move(pl^, pl1^, (n-1)*s);
  891. move(pd^, pd1^, n*s);
  892. move(pu^, pu1^, (n-1)*s);
  893. j := 1;
  894. di := pd1^[j];
  895. If di=0 Then
  896. term := 2
  897. Else
  898. term := 1;
  899. while (term=1) and (j <> n) Do
  900. Begin
  901. i := j;
  902. j := j+1;
  903. lj := pl1^[j]/di;
  904. pl1^[j] := lj;
  905. di := pd1^[j]-lj*pu1^[i];
  906. pd1^[j] := di;
  907. If di=0 Then
  908. term := 2
  909. End {j}
  910. End; {mdtdtr}
  911. Begin
  912. randseed := 12345
  913. End.
  914. {
  915. $Log$
  916. Revision 1.1 2000-07-13 06:34:15 michael
  917. + Initial import
  918. Revision 1.2 2000/01/25 20:21:42 marco
  919. * small updates, crlf fix, and RTE 207 problem
  920. Revision 1.1 2000/01/24 22:08:58 marco
  921. * initial version
  922. }