det.pas 11 KB

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