det.pas 11 KB

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