det.pas 11 KB

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