dsl.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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. Unknown unit. There doesn't exist any documentation for it, it isn't
  10. commented, and I don't recognize the algortism directly.
  11. I added some comments, since suffixes of the procedures seem to indicate
  12. some features of the matrixtype (from unit SLE)
  13. So probably Some pivot matrix?
  14. This code was probably internal in older libs, and only exported
  15. in later versions.
  16. See the file COPYING.FPC, included in this distribution,
  17. 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.
  21. **********************************************************************}
  22. Unit dsl;
  23. interface
  24. {$I DIRECT.INC}
  25. uses typ;
  26. {Gen=generic, matrix without special or unknown ordering}
  27. Procedure dslgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt;
  28. Var b, x: ArbFloat; Var term: ArbInt);
  29. {"tridiagonal matrix"}
  30. Procedure dslgtr(n: ArbInt; Var l1, d1, u1, u2: ArbFloat;
  31. Var p: boolean; Var b, x: ArbFloat; Var term: ArbInt);
  32. {Symmetrical matrix}
  33. Procedure dslgsy(n, rwidth: ArbInt; Var alt: ArbFloat; Var p: ArbInt;
  34. Var q: boolean; Var b, x: ArbFloat; Var term: ArbInt);
  35. {Symmetrical positive definitive matrix}
  36. Procedure dslgpd(n, rwidth: ArbInt; Var al, b, x: ArbFloat;
  37. Var term: ArbInt);
  38. {Generic "band" matrix}
  39. Procedure dslgba(n, lb, rb, rwa: ArbInt; Var au: ArbFloat; rwl: ArbInt;
  40. Var l: ArbFloat; Var p: ArbInt; Var b, x: ArbFloat;
  41. Var term: ArbInt);
  42. {Positive definite bandmatrix}
  43. Procedure dslgpb(n, lb, rwidth: ArbInt; Var al, b, x: ArbFloat;
  44. Var term: ArbInt);
  45. {Special tridiagonal matrix}
  46. Procedure dsldtr(n:ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
  47. implementation
  48. Procedure dslgen(n, rwidth: ArbInt; Var alu: ArbFloat; Var p: ArbInt;
  49. Var b, x: ArbFloat; Var term: ArbInt);
  50. Var
  51. success : boolean;
  52. indk, j, k, indexpivot, kmin1 : ArbInt;
  53. h, pivot, s : ArbFloat;
  54. pp : ^arint1;
  55. palu, pb, px : ^arfloat1;
  56. Begin
  57. If (n<1) Or (rwidth<1) Then
  58. Begin
  59. term := 3;
  60. exit
  61. End; {wrong input}
  62. pp := @p;
  63. palu := @alu;
  64. pb := @b;
  65. px := @x;
  66. move(pb^, px^, n*sizeof(ArbFloat));
  67. For k:=1 To n Do
  68. Begin
  69. indexpivot := pp^[k];
  70. If indexpivot <> k Then
  71. Begin
  72. h := px^[k];
  73. px^[k] := px^[indexpivot];
  74. px^[indexpivot] := h
  75. End {indexpivot <> k}
  76. End; {k}
  77. For k:=2 To n Do
  78. Begin
  79. s := px^[k];
  80. kmin1 := k-1;
  81. For j:=1 To kmin1 Do
  82. s := s-palu^[(k-1)*rwidth+j]*px^[j];
  83. px^[k] := s
  84. End; {k}
  85. success := true;
  86. k := n+1;
  87. while (k>1) and success Do
  88. Begin
  89. k := k-1;
  90. indk := (k-1)*rwidth;
  91. pivot := palu^[indk+k];
  92. If pivot=0 Then
  93. success := false
  94. Else
  95. Begin
  96. s := px^[k];
  97. For j:=k+1 To n Do
  98. s := s-palu^[indk+j]*px^[j];
  99. px^[k] := s/pivot
  100. End {pivot <> 0}
  101. End; {k}
  102. If success Then
  103. term := 1
  104. Else
  105. term := 2
  106. End; {dslgen}
  107. Procedure dslgtr(n: ArbInt; Var l1, d1, u1, u2: ArbFloat;
  108. Var p: boolean; Var b, x: ArbFloat; Var term: ArbInt);
  109. Var
  110. i, j, nmin1 : ArbInt;
  111. h, di : ArbFloat;
  112. success : boolean;
  113. pd1, pu1, pu2, pb, px : ^arfloat1;
  114. pl1 : ^arfloat2;
  115. pp : ^arbool1;
  116. Begin
  117. If n<1 Then
  118. Begin
  119. term := 3;
  120. exit
  121. End; {wrong input}
  122. pl1 := @l1; pd1 := @d1; pu1 := @u1; pu2 := @u2; pb := @b; px := @x;
  123. pp := @p;
  124. move(pb^, px^, n*sizeof(ArbFloat));
  125. success := true;
  126. i := 0;
  127. while (i<>n) and success Do
  128. Begin
  129. i := i+1;
  130. success := pd1^[i]<>0
  131. End; {i}
  132. If success Then
  133. Begin
  134. nmin1 := n-1;
  135. j := 1;
  136. while j <> n Do
  137. Begin
  138. i := j;
  139. j := j+1;
  140. If pp^[i] Then
  141. Begin
  142. h := px^[i];
  143. px^[i] := px^[j];
  144. px^[j] := h-pl1^[j]*px^[i]
  145. End {pp^[i]}
  146. Else
  147. px^[j] := px^[j]-pl1^[j]*px^[i]
  148. End; {j}
  149. di := pd1^[n];
  150. px^[n] := px^[n]/di;
  151. If n > 1 Then
  152. Begin
  153. di := pd1^[nmin1];
  154. px^[nmin1] := (px^[nmin1]-pu1^[nmin1]*px^[n])/di
  155. End; {n > 1}
  156. For i:=n-2 Downto 1 Do
  157. Begin
  158. di := pd1^[i];
  159. px^[i] := (px^[i]-pu1^[i]*px^[i+1]-pu2^[i]*px^[i+2])/di
  160. End {i}
  161. End; {success}
  162. If success Then
  163. term := 1
  164. Else
  165. term := 2
  166. End; {dslgtr}
  167. Procedure dslgsy(n, rwidth: ArbInt; Var alt: ArbFloat; Var p: ArbInt;
  168. Var q: boolean; Var b, x: ArbFloat; Var term: ArbInt);
  169. Var
  170. i, indexpivot, imin1, j, jmin1, iplus1, imin2, ns, ii : ArbInt;
  171. success, regular : boolean;
  172. h, ct, di : ArbFloat;
  173. palt, pb, px, y, l, d, u, v : ^arfloat1;
  174. pp : ^arint1;
  175. pq : ^arbool1;
  176. Begin
  177. If (n<1) Or (rwidth<1) Then
  178. Begin
  179. term := 3;
  180. exit
  181. End; {wrong input}
  182. palt := @alt;
  183. pp := @p;
  184. pq := @q;
  185. pb := @b;
  186. px := @x;
  187. ns := n*sizeof(ArbFloat);
  188. getmem(l, ns);
  189. getmem(d, ns);
  190. getmem(u, ns);
  191. getmem(v, ns);
  192. getmem(y, ns);
  193. move(pb^, y^, ns);
  194. success := true;
  195. i := 0;
  196. ii := 1;
  197. while (i<>n) and success Do
  198. Begin
  199. i := i+1;
  200. success := palt^[ii]<>0;
  201. ii := ii+rwidth+1
  202. End; {i}
  203. If success Then
  204. Begin
  205. For i:=1 To n Do
  206. Begin
  207. indexpivot := pp^[i];
  208. If indexpivot <> i Then
  209. Begin
  210. h := y^[i];
  211. y^[i] := y^[indexpivot];
  212. y^[indexpivot] := h
  213. End {indexpivot <> i}
  214. End; {i}
  215. i := 0;
  216. while i<n Do
  217. Begin
  218. imin1 := i;
  219. i := i+1;
  220. j := 1;
  221. h := y^[i];
  222. while j<imin1 Do
  223. Begin
  224. jmin1 := j;
  225. j := j+1;
  226. h := h-palt^[(i-1)*rwidth+jmin1]*y^[j]
  227. End; {j}
  228. y^[i] := h
  229. End; {i}
  230. d^[1] := palt^[1];
  231. di := d^[1];
  232. If n>1 Then
  233. Begin
  234. l^[1] := palt^[rwidth+1];
  235. d^[2] := palt^[rwidth+2];
  236. di := d^[2];
  237. u^[1] := palt^[2]
  238. End; {n>1}
  239. imin1 := 1;
  240. i := 2;
  241. while i<n Do
  242. Begin
  243. imin2 := imin1;
  244. imin1 := i;
  245. i := i+1;
  246. ii := (i-1)*rwidth;
  247. l^[imin1] := palt^[ii+imin1];
  248. d^[i] := palt^[ii+i];
  249. di := d^[i];
  250. u^[imin1] := palt^[ii-rwidth+i];
  251. v^[imin2] := palt^[ii-2*rwidth+i]
  252. End; {i}
  253. dslgtr(n, l^[1], d^[1], u^[1], v^[1], pq^[1], y^[1], px^[1], term);
  254. i := n+1;
  255. imin1 := n;
  256. while i>2 Do
  257. Begin
  258. iplus1 := i;
  259. i := imin1;
  260. imin1 := imin1-1;
  261. h := px^[i];
  262. For j:=iplus1 To n Do
  263. h := h-palt^[(j-1)*rwidth+imin1]*px^[j];
  264. px^[i] := h
  265. End; {i}
  266. For i:=n Downto 1 Do
  267. Begin
  268. indexpivot := pp^[i];
  269. If indexpivot <> i Then
  270. Begin
  271. h := px^[i];
  272. px^[i] := px^[indexpivot];
  273. px^[indexpivot] := h
  274. End {indexpivot <> i}
  275. End {i}
  276. End; {success}
  277. If success Then
  278. term := 1
  279. Else
  280. term := 2;
  281. freemem(l, ns);
  282. freemem(d, ns);
  283. freemem(u, ns);
  284. freemem(v, ns);
  285. freemem(y, ns)
  286. End; {dslgsy}
  287. Procedure dslgpd(n, rwidth: ArbInt; Var al, b, x: ArbFloat;
  288. Var term: ArbInt);
  289. Var
  290. ii, imin1, i, j : ArbInt;
  291. h, lii : ArbFloat;
  292. success : boolean;
  293. pal, pb, px : ^arfloat1;
  294. Begin
  295. If (n<1) Or (rwidth<1) Then
  296. Begin
  297. term := 3;
  298. exit
  299. End; {wrong input}
  300. pal := @al;
  301. pb := @b;
  302. px := @x;
  303. move(pb^, px^, n*sizeof(ArbFloat));
  304. success := true;
  305. i := 0;
  306. ii := 1;
  307. while (i<>n) and success Do
  308. Begin
  309. i := i+1;
  310. success := pal^[ii]<>0;
  311. ii := ii+rwidth+1
  312. End; {i}
  313. If success Then
  314. Begin
  315. For i:=1 To n Do
  316. Begin
  317. ii := (i-1)*rwidth;
  318. h := px^[i];
  319. imin1 := i-1;
  320. For j:=1 To imin1 Do
  321. h := h-pal^[ii+j]*px^[j];
  322. lii := pal^[ii+i];
  323. px^[i] := h/lii
  324. End; {i}
  325. For i:=n Downto 1 Do
  326. Begin
  327. h := px^[i];
  328. For j:=i+1 To n Do
  329. h := h-pal^[(j-1)*rwidth+i]*px^[j];
  330. px^[i] := h/pal^[(i-1)*rwidth+i]
  331. End {i}
  332. End; {success}
  333. If success Then
  334. term := 1
  335. Else
  336. term := 2
  337. End; {dslgpd}
  338. Procedure dslgba(n, lb, rb, rwa: ArbInt; Var au: ArbFloat; rwl: ArbInt;
  339. Var l: ArbFloat; Var p: ArbInt; Var b, x: ArbFloat;
  340. Var term: ArbInt);
  341. Var
  342. i, j, k, ipivot, ubi, ubj : ArbInt;
  343. h, pivot : ArbFloat;
  344. pau, pl, px, pb : ^arfloat1;
  345. pp : ^arint1;
  346. Begin
  347. If (n<1) Or (lb<0) Or (rb<0) Or (lb>n-1)
  348. Or (rb>n-1) Or (rwa<1) Or (rwl<0) Then
  349. Begin
  350. term := 3;
  351. exit
  352. End; {term=3}
  353. pau := @au;
  354. pl := @l;
  355. pb := @b;
  356. px := @x;
  357. pp := @p;
  358. move(pb^, px^, n*sizeof(ArbFloat));
  359. ubi := lb;
  360. For k:=1 To n Do
  361. Begin
  362. ipivot := pp^[k];
  363. If ipivot <> k Then
  364. Begin
  365. h := px^[k];
  366. px^[k] := px^[ipivot];
  367. px^[ipivot] := h
  368. End; {ipivot <> k}
  369. If ubi<n Then
  370. ubi := ubi+1;
  371. For i:=k+1 To ubi Do
  372. px^[i] := px^[i]-px^[k]*pl^[(k-1)*rwl+i-k]
  373. End; {k}
  374. ubj := 0;
  375. i := n;
  376. term := 1;
  377. while (i >= 1) and (term=1) Do
  378. Begin
  379. If ubj<rb+lb+1 Then
  380. ubj := ubj+1;
  381. h := px^[i];
  382. For j:=2 To ubj Do
  383. h := h-pau^[(i-1)*rwa+j]*px^[i+j-1];
  384. pivot := pau^[(i-1)*rwa+1];
  385. If pivot=0 Then
  386. term := 2
  387. Else
  388. px^[i] := h/pivot;
  389. i := i-1
  390. End {i}
  391. End; {dslgba}
  392. Procedure dslgpb(n, lb, rwidth: ArbInt; Var al, b, x: ArbFloat;
  393. Var term: ArbInt);
  394. Var
  395. ll, ii, llmin1, p, i, q, k : ArbInt;
  396. h, hh, alim : ArbFloat;
  397. pal, pb, px : ^arfloat1;
  398. Begin
  399. If (lb<0) Or (lb>n-1) Or (n<1) Or (rwidth<1) Then
  400. Begin
  401. term := 3;
  402. exit
  403. End; {wrong input}
  404. pal := @al;
  405. pb := @b;
  406. px := @x;
  407. move(pb^, px^, n*sizeof(ArbFloat));
  408. ll := lb+1;
  409. llmin1 := ll-1;
  410. p := ll+1;
  411. term := 1;
  412. i := 1;
  413. while (i <= n) and (term=1) Do
  414. Begin
  415. ii := (i-1)*rwidth;
  416. If p>1 Then
  417. p := p-1;
  418. h := px^[i];
  419. q := i;
  420. For k:=llmin1 Downto p Do
  421. Begin
  422. q := q-1;
  423. h := h-pal^[ii+k]*px^[q]
  424. End; {k}
  425. alim := pal^[ii+ll];
  426. If alim=0 Then
  427. term := 2
  428. Else
  429. px^[i] := h/alim;
  430. i := i+1
  431. End; {i}
  432. If term=1 Then
  433. Begin
  434. p := ll+1;
  435. For i:=n Downto 1 Do
  436. Begin
  437. If p>1 Then
  438. p := p-1;
  439. q := i;
  440. h := px^[i];
  441. For k:=llmin1 Downto p Do
  442. Begin
  443. q := q+1;
  444. h := h-pal^[(q-1)*rwidth+k]*px^[q]
  445. End; {k}
  446. px^[i] := h/pal^[(i-1)*rwidth+ll]
  447. End {i}
  448. End {term=1}
  449. End; {dslgpb}
  450. Procedure dsldtr(n:ArbInt; Var l, d, u, b, x: ArbFloat; Var term: ArbInt);
  451. Var
  452. i, j : ArbInt;
  453. di : ArbFloat;
  454. pd, pu, pb, px : ^arfloat1;
  455. pl : ^arfloat2;
  456. Begin
  457. If n<1 Then
  458. Begin
  459. term := 3;
  460. exit
  461. End; {wrong input}
  462. pl := @l;
  463. pd := @d;
  464. pu := @u;
  465. pb := @b;
  466. px := @x;
  467. move(pb^, px^, n*sizeof(ArbFloat));
  468. j := 1;
  469. while j <> n Do
  470. Begin
  471. i := j;
  472. j := j+1;
  473. px^[j] := px^[j]-pl^[j]*px^[i]
  474. End;
  475. di := pd^[n];
  476. If di=0 Then
  477. term := 2
  478. Else
  479. term := 1;
  480. If term=1 Then
  481. px^[n] := px^[n]/di;
  482. i := n-1;
  483. while (i >= 1) and (term=1) Do
  484. Begin
  485. di := pd^[i];
  486. If di=0 Then
  487. term := 2
  488. Else
  489. px^[i] := (px^[i]-pu^[i]*px^[i+1])/di;
  490. i := i-1
  491. End; {i}
  492. End; {dsldtr}
  493. End.
  494. {
  495. $Log$
  496. Revision 1.2 2000-01-25 20:21:41 marco
  497. * small updates, crlf fix, and RTE 207 problem
  498. Revision 1.1 2000/01/24 22:08:58 marco
  499. * initial version
  500. }