dsl.pas 12 KB

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