det.pas 11 KB

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