dsl.pas 13 KB

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