det.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  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. Determinants for different kinds of matrices (different with respect
  9. to symmetry)
  10. See the file COPYING.FPC, included in this distribution,
  11. for details about the copyright.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. **********************************************************************}
  16. {$IFNDEF FPC_DOTTEDUNITS}
  17. unit det;
  18. {$ENDIF FPC_DOTTEDUNITS}
  19. interface
  20. {$I DIRECT.INC}
  21. {$IFDEF FPC_DOTTEDUNITS}
  22. uses NumLib.Typ;
  23. {$ELSE FPC_DOTTEDUNITS}
  24. uses typ;
  25. {$ENDIF FPC_DOTTEDUNITS}
  26. {Generic determinant}
  27. procedure detgen(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
  28. {determinant symmetrical matrix}
  29. procedure detgsy(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
  30. {determinant of a symmetrical positive definitive matrix}
  31. procedure detgpd(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
  32. {determinant of a generic bandmatrix}
  33. procedure detgba(n, l, r: ArbInt; var a, f: ArbFloat; var k, term:ArbInt);
  34. {determinant of a symmetrical positive definitive bandmatrix}
  35. procedure detgpb(n, l: ArbInt; var a, f: ArbFloat; var k, term:ArbInt);
  36. {determinant of a tridiagonal matrix}
  37. procedure detgtr(n: ArbInt; var l, d, u, f: ArbFloat; var k, term:ArbInt);
  38. { moved to the TYP unit because of a bug in FPC 1.0.x FK
  39. var og : ArbFloat absolute ogx;
  40. bg : ArbFloat absolute bgx;
  41. MaxExp : ArbInt absolute maxexpx;
  42. }
  43. implementation
  44. {$IFDEF FPC_DOTTEDUNITS}
  45. uses NumLib.Mdt;
  46. {$ELSE FPC_DOTTEDUNITS}
  47. uses mdt;
  48. {$ENDIF FPC_DOTTEDUNITS}
  49. procedure detgen(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
  50. var
  51. kk, ind, ind1, ns, i : ArbInt;
  52. u, ca : ArbFloat;
  53. pa, acopy : ^arfloat1;
  54. p : ^arint1;
  55. begin
  56. if (n<1) or (rwidth<1) then
  57. begin
  58. term:=3; exit
  59. end; {wrong input}
  60. pa:=@a;
  61. ns:=n*sizeof(ArbFloat);
  62. getmem(p, n*sizeof(ArbInt));
  63. getmem(acopy, n*ns);
  64. ind:=1; ind1:=1;
  65. for i:=1 to n do
  66. begin
  67. move(pa^[ind1], acopy^[ind], ns);
  68. ind1:=ind1+rwidth; ind:=ind+n
  69. end; {i}
  70. mdtgen(n, n, acopy^[1], p^[1], ca, term);
  71. if term=1 then
  72. begin
  73. f:=1; k:=0; kk:=1; ind:=1;
  74. while (kk<=n) and (f<>0) do
  75. begin
  76. u:=acopy^[ind];
  77. while (u<>0) and (abs(u)<og) do
  78. begin
  79. u:=u/og; k:=k-maxexp
  80. end; {underflow control}
  81. while abs(u)>bg do
  82. begin
  83. u:=u/bg; k:=k+maxexp
  84. end; {overflow control}
  85. f:=f*u;
  86. if p^[kk]<>kk then f:=-f;
  87. while (f<>0) and (abs(f)<og) do
  88. begin
  89. f:=f/og; k:=k-maxexp
  90. end; {underflow control}
  91. while abs(f)>bg do
  92. begin
  93. f:=f/bg; k:=k+maxexp
  94. end; {overflow control}
  95. kk:=kk+1; ind:=ind+n+1
  96. end; {kk}
  97. end {term=1}
  98. else {term=4}
  99. begin
  100. f:=0; k:=0; term:=1
  101. end;
  102. freemem(p, n*sizeof(ArbInt));
  103. freemem(acopy, n*ns)
  104. end; {detgen}
  105. procedure detgsy(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
  106. var i, kk, ind, ind1, s : ArbInt;
  107. u, ca : ArbFloat;
  108. pa, acopy : ^arfloat1;
  109. p : ^arint1;
  110. q : ^arbool1;
  111. begin
  112. if (n<1) or (rwidth<1) then
  113. begin
  114. term:=3; exit
  115. end; {wrong input}
  116. pa:=@a;
  117. getmem(p, n*sizeof(ArbInt));
  118. getmem(q, n*sizeof(boolean));
  119. s:=sizeof(ArbFloat);
  120. getmem(acopy, n*n*s);
  121. ind:=1; ind1:=1;
  122. for i:=1 to n do
  123. begin
  124. move(pa^[ind1], acopy^[ind], i*s);
  125. ind1:=ind1+rwidth; ind:=ind+n
  126. end; {i}
  127. mdtgsy(n, n, acopy^[1], p^[1], q^[1], ca, term);
  128. if term=1 then
  129. begin
  130. f:=1; k:=0; kk:=1; ind:=1;
  131. while (kk<=n) and (f<>0) do
  132. begin
  133. u:=acopy^[ind];
  134. while (u<>0) and (abs(u)<og) do
  135. begin
  136. u:=u/og; k:=k-maxexp
  137. end; {underflow control}
  138. while abs(u)>bg do
  139. begin
  140. u:=u/bg; k:=k+maxexp
  141. end; {overflow control}
  142. f:=f*u;
  143. if q^[kk] then f:=-f;
  144. while (f<>0) and (abs(f)<og) do
  145. begin
  146. f:=f/og; k:=k-maxexp
  147. end; {underflow control}
  148. while abs(f)>bg do
  149. begin
  150. f:=f/bg; k:=k+maxexp
  151. end; {overflow control}
  152. kk:=kk+1; ind:=ind+n+1
  153. end; {kk}
  154. end {term=1}
  155. else {term=4}
  156. begin
  157. term:=1; f:=0; k:=0
  158. end;
  159. freemem(p, n*sizeof(ArbInt));
  160. freemem(q, n*sizeof(boolean));
  161. freemem(acopy, n*n*s)
  162. end; {detgsy}
  163. procedure detgpd(n, rwidth: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
  164. var
  165. i, kk, ind, ind1, s : ArbInt;
  166. u, ca : ArbFloat;
  167. pa, acopy : ^arfloat1;
  168. begin
  169. if (n<1) or (rwidth<1) then
  170. begin
  171. term:=3; exit
  172. end; {wrong input}
  173. pa:=@a;
  174. s:=sizeof(ArbFloat);
  175. getmem(acopy, n*n*s);
  176. ind:=1; ind1:=1;
  177. for i:=1 to n do
  178. begin
  179. move(pa^[ind1], acopy^[ind], i*s);
  180. ind1:=ind1+rwidth; ind:=ind+n
  181. end; {i}
  182. mdtgpd(n, n, acopy^[1], ca, term);
  183. if term=1 then
  184. begin
  185. f:=1; k:=0; kk:=1; ind:=1;
  186. while kk<=n do
  187. begin
  188. u:=sqr(acopy^[ind]);
  189. while u < og do
  190. begin
  191. u:=u/og; k:=k-maxexp
  192. end; {underflow control}
  193. while u > bg do
  194. begin
  195. u:=u/bg; k:=k+maxexp
  196. end; {overflow control}
  197. f:=f*u;
  198. while f < og do
  199. begin
  200. f:=f/og; k:=k-maxexp
  201. end; {underflow control}
  202. while f > bg do
  203. begin
  204. f:=f/bg; k:=k+maxexp
  205. end; {overflow control}
  206. kk:=kk+1; ind:=ind+n+1
  207. end; {kk}
  208. end; {term=1}
  209. freemem(acopy, n*n*s)
  210. end; {detgpd}
  211. procedure detgba(n, l, r: ArbInt; var a, f: ArbFloat;
  212. var k, term:ArbInt);
  213. var
  214. rwidth, s, ns, kk, ii, i, jj, ll : ArbInt;
  215. u, ca : ArbFloat;
  216. pa, l1, acopy : ^arfloat1;
  217. p : ^arint1;
  218. begin
  219. if (n<1) or (l<0) or (r<0) or (l>n-1) or (r>n-1) then
  220. begin
  221. term:=3; exit
  222. end; {wrong input}
  223. pa:=@a;
  224. s:=sizeof(ArbFloat); ns:=n*s;
  225. ll:=l+r+1;
  226. getmem(acopy, ll*ns);
  227. getmem(l1, l*ns);
  228. getmem(p, n*sizeof(ArbInt));
  229. jj:=1; ii:=1;
  230. for i:=1 to n do
  231. begin
  232. if i <= l+1 then
  233. begin
  234. if i <= (n-r) then rwidth:=r+i else rwidth:=n
  235. end else
  236. if i <= (n-r) then rwidth:=ll else rwidth:=n-i+l+1;
  237. if i > l then kk:=ii else kk:=ii+l-i+1;
  238. move(pa^[jj], acopy^[kk], rwidth*s);
  239. jj:=jj+rwidth; ii:=ii+ll;
  240. end; {i}
  241. mdtgba(n, l, r, ll, acopy^[1], l, l1^[1], p^[1], ca, term);
  242. if term=1 then
  243. begin
  244. f:=1; k:=0; kk:=1; ii:=1;
  245. while (kk<=n) and (f<>0) do
  246. begin
  247. u:=acopy^[ii];
  248. while (u<>0) and (abs(u)<og) do
  249. begin
  250. u:=u/og; k:=k-maxexp
  251. end; {underflow control}
  252. while abs(u)>bg do
  253. begin
  254. u:=u/bg; k:=k+maxexp
  255. end; {overflow control}
  256. f:=f*u;
  257. if p^[kk]<>kk then f:=-f;
  258. while (f<>0) and (abs(f)<og) do
  259. begin
  260. f:=f/og; k:=k-maxexp
  261. end; {underflow control}
  262. while abs(f)>bg do
  263. begin
  264. f:=f/bg; k:=k+maxexp
  265. end; {overflow control}
  266. kk:=kk+1; ii:=ii+ll
  267. end; {kk}
  268. end {term=1}
  269. else {term=4}
  270. begin
  271. term:=1; f:=0; k:=0
  272. end;
  273. freemem(acopy, ll*ns);
  274. freemem(l1, l*ns);
  275. freemem(p, n*sizeof(ArbInt))
  276. end; {detgba}
  277. procedure detgpb(n, l: ArbInt; var a, f: ArbFloat; var k, term: ArbInt);
  278. var
  279. rwidth, kk, ii, ns, ll, jj, i, s : ArbInt;
  280. u, ca : ArbFloat;
  281. pa, acopy : ^arfloat1;
  282. begin
  283. if (n<1) or (l<0) or (l>n-1) then
  284. begin
  285. term:=3; exit
  286. end; {wrong input}
  287. pa:=@a;
  288. ll:=l+1;
  289. s:=sizeof(ArbFloat); ns:=s*n;
  290. getmem(acopy, ll*ns);
  291. jj:=1; ii:=1;
  292. for i:=1 to n do
  293. begin
  294. if i>l then rwidth:=ll else rwidth:=i;
  295. move(pa^[jj], acopy^[ii+ll-rwidth], rwidth*s);
  296. jj:=jj+rwidth; ii:=ii+ll
  297. end; {i}
  298. mdtgpb(n, l, ll, acopy^[1], ca, term);
  299. if term=1 then
  300. begin
  301. f:=1; k:=0; kk:=1; ii:=ll;
  302. while (kk<=n) do
  303. begin
  304. u:=sqr(acopy^[ii]);
  305. while u < og do
  306. begin
  307. u:=u/og; k:=k-maxexp
  308. end; {underflow control}
  309. while u > bg do
  310. begin
  311. u:=u/bg; k:=k+maxexp
  312. end; {overflow control}
  313. f:=f*u;
  314. while f < og do
  315. begin
  316. f:=f/og; k:=k-maxexp
  317. end; {underflow control}
  318. while f > bg do
  319. begin
  320. f:=f/bg; k:=k+maxexp
  321. end; {overflow control}
  322. kk:=kk+1; ii:=ii+ll
  323. end; {kk}
  324. end; {term=1}
  325. freemem(acopy, ll*ns);
  326. end; {detgpb}
  327. procedure detgtr(n: ArbInt; var l, d, u, f: ArbFloat; var k, term:ArbInt);
  328. var
  329. ns, kk : ArbInt;
  330. uu, ca : ArbFloat;
  331. pl, pd, pu, l1, d1, u1, u2 : ^arfloat1;
  332. p : ^arbool1;
  333. begin
  334. if n<1 then
  335. begin
  336. term:=3; exit
  337. end; {wrong input}
  338. pl:=@l; pd:=@d; pu:=@u;
  339. ns:=n*sizeof(ArbFloat);
  340. getmem(l1, ns);
  341. getmem(d1, ns);
  342. getmem(u1, ns);
  343. getmem(u2, ns);
  344. getmem(p, n*sizeof(boolean));
  345. mdtgtr(n, pl^[1], pd^[1], pu^[1], l1^[1], d1^[1], u1^[1], u2^[1],
  346. p^[1], ca, term);
  347. if term=1 then
  348. begin
  349. f:=1; k:=0; kk:=1;
  350. while (kk<=n) and (f<>0) do
  351. begin
  352. if p^[kk] then f:=-f;
  353. uu:=d1^[kk];
  354. while (uu<>0) and (abs(uu)<og) do
  355. begin
  356. uu:=uu/og; k:=k-maxexp
  357. end; {underflow control}
  358. while abs(uu)>bg do
  359. begin
  360. uu:=uu/bg; k:=k+maxexp
  361. end; {overflow control}
  362. f:=f*uu;
  363. while (f<>0) and (abs(f)<og) do
  364. begin
  365. f:=f/og; k:=k-maxexp
  366. end; {underflow control}
  367. while abs(f)>bg do
  368. begin
  369. f:=f/bg; k:=k+maxexp
  370. end; {overflow control}
  371. kk:=kk+1
  372. end; {kk}
  373. end {term=1}
  374. else {term=4}
  375. begin
  376. term:=1; f:=0; k:=0
  377. end;
  378. freemem(l1, ns);
  379. freemem(d1, ns);
  380. freemem(u1, ns);
  381. freemem(u2, ns);
  382. freemem(p, n*sizeof(boolean));
  383. end; {detgtr}
  384. end.