eig.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  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. See the file COPYING.FPC, included in this distribution,
  10. for details about the copyright.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. **********************************************************************}
  15. unit eig;
  16. {$I DIRECT.INC}
  17. interface
  18. uses typ;
  19. const versie = 'augustus 1993';
  20. procedure eiggs1(var a: ArbFloat; n, rwidth: ArbInt; var lam: ArbFloat;
  21. var term: ArbInt);
  22. procedure eiggs2(var a: ArbFloat; n, rwidth, k1, k2: ArbInt;
  23. var lam: ArbFloat; var term: ArbInt);
  24. procedure eiggs3(var a: ArbFloat; n, rwidtha: ArbInt; var lam, x: ArbFloat;
  25. rwidthx: ArbInt; var term: ArbInt);
  26. procedure eiggs4(var a: ArbFloat; n, rwidtha, k1, k2: ArbInt; var lam, x: ArbFloat;
  27. rwidthx: ArbInt; var m2, term: ArbInt);
  28. procedure eigts1(var d, cd: ArbFloat; n: ArbInt; var lam: ArbFloat;
  29. var term: ArbInt);
  30. procedure eigts2(var d, cd: ArbFloat; n, k1, k2: ArbInt; var lam: ArbFloat;
  31. var term: ArbInt);
  32. procedure eigts3(var d, cd: ArbFloat; n: ArbInt; var lam, x: ArbFloat;
  33. rwidth: ArbInt; var term: ArbInt);
  34. procedure eigts4(var d, cd: ArbFloat; n, k1, k2: ArbInt; var lam, x: ArbFloat;
  35. rwidth: ArbInt; var m2, term: ArbInt);
  36. procedure eigbs1(var a: ArbFloat; n, l: ArbInt; var lam: ArbFloat;
  37. var term: ArbInt);
  38. procedure eigbs2(var a: ArbFloat; n, l, k1, k2: ArbInt; var lam: ArbFloat;
  39. var term: ArbInt);
  40. procedure eigbs3(var a: ArbFloat; n, l: ArbInt; var lam, x: ArbFloat;
  41. rwidthx: ArbInt; var term: ArbInt);
  42. procedure eigbs4(var a: ArbFloat; n, l, k1, k2: ArbInt;
  43. var lam, x: ArbFloat; rwidthx: ArbInt;
  44. var m2, term: ArbInt);
  45. procedure eigge1(var a: ArbFloat; n, rwidth: ArbInt; var lam: complex;
  46. var term: ArbInt);
  47. procedure eigge3(var a: ArbFloat; n, rwidtha: ArbInt; var lam, x: complex;
  48. rwidthx: ArbInt; var term: ArbInt);
  49. procedure eiggg1(var a: ArbFloat; n, rwidtha: ArbInt; var b: ArbFloat;
  50. rwidthb: ArbInt; var lam: ArbFloat; var term: ArbInt);
  51. procedure eiggg2(var a: ArbFloat; n, rwidtha, k1, k2: ArbInt; var b: ArbFloat;
  52. rwidthb: ArbInt; var lam: ArbFloat; var term: ArbInt);
  53. procedure eiggg3(var a: ArbFloat; n, rwidtha: ArbInt; var b: ArbFloat;
  54. rwidthb: ArbInt; var lam, x: ArbFloat; rwidthx: ArbInt;
  55. var term: ArbInt);
  56. procedure eiggg4(var a: ArbFloat; n, rwidtha, k1, k2: ArbInt; var b: ArbFloat;
  57. rwidthb: ArbInt; var lam, x: ArbFloat; rwidthx: ArbInt;
  58. var m2, term: ArbInt);
  59. procedure eigsv1(var a: ArbFloat; m, n, rwidth: ArbInt; var sig: ArbFloat;
  60. var term: ArbInt);
  61. procedure eigsv3(var a: ArbFloat; m, n, rwidtha: ArbInt; var sig, u: ArbFloat;
  62. rwidthu: ArbInt; var v: ArbFloat; rwidthv: ArbInt;
  63. var term: ArbInt);
  64. implementation
  65. uses eigh1, eigh2;
  66. procedure eiggs1(var a: ArbFloat; n, rwidth: ArbInt; var lam: ArbFloat;
  67. var term: ArbInt);
  68. var i, sr, nsr : ArbInt;
  69. d, cd, dh, cdh, u, pa : ^arfloat1;
  70. begin
  71. if n<1 then
  72. begin
  73. term:=3; exit
  74. end; {wrong input}
  75. pa:=@a;
  76. sr:=sizeof(ArbFloat); nsr:=n*sr;
  77. getmem(d, nsr); getmem(cd, nsr); getmem(dh, nsr); getmem(cdh, nsr);
  78. getmem(u, n*nsr);
  79. for i:=1 to n do move(pa^[(i-1)*rwidth+1], u^[(i-1)*n+1], i*sr);
  80. tred1(u^[1], n, n, d^[1], cd^[1], term);
  81. move(d^[1], dh^[1], nsr); move(cd^[1], cdh^[1], nsr);
  82. tql1(d^[1], cd^[1], n, lam, term);
  83. if term=2 then bisect(dh^[1], cdh^[1], n, 1, n, 0, lam, term);
  84. freemem(d, nsr); freemem(cd, nsr); freemem(dh, nsr); freemem(cdh, nsr);
  85. freemem(u, n*nsr);
  86. end; {eiggs1}
  87. procedure eiggs2(var a: ArbFloat; n, rwidth, k1, k2: ArbInt;
  88. var lam: ArbFloat; var term: ArbInt);
  89. var i, sr, nsr : ArbInt;
  90. d, cd, u, pa : ^arfloat1;
  91. begin
  92. if (n<1) or (k1<1) or (k2<k1) or (k2>n) then
  93. begin
  94. term:=3; exit
  95. end; {wrong input}
  96. pa:=@a;
  97. sr:=sizeof(ArbFloat); nsr:=n*sr;
  98. getmem(d, nsr); getmem(cd, nsr); getmem(u, n*nsr);
  99. for i:=1 to n do move(pa^[(i-1)*rwidth+1], u^[(i-1)*n+1], i*sr);
  100. tred1(u^[1], n, n, d^[1], cd^[1], term);
  101. bisect(d^[1], cd^[1], n, k1, k2, 0, lam, term);
  102. freemem(d, nsr); freemem(cd, nsr); freemem(u, n*nsr);
  103. end; {eiggs2}
  104. procedure eiggs3(var a: ArbFloat; n, rwidtha: ArbInt; var lam, x: ArbFloat;
  105. rwidthx: ArbInt; var term: ArbInt);
  106. var nsr : ArbInt;
  107. d, cd : ^arfloat1;
  108. begin
  109. if n<1 then
  110. begin
  111. term:=3; exit
  112. end;
  113. nsr:=n*sizeof(ArbFloat);
  114. getmem(d, nsr); getmem(cd, nsr);
  115. tred2(a, n, rwidtha, d^[1], cd^[1], x, rwidthx, term);
  116. tql2(d^[1], cd^[1], n, lam, x, rwidthx, term);
  117. freemem(d, nsr); freemem(cd, nsr)
  118. end; {eiggs3}
  119. procedure eiggs4(var a: ArbFloat; n, rwidtha, k1, k2: ArbInt; var lam, x: ArbFloat;
  120. rwidthx: ArbInt; var m2, term: ArbInt);
  121. var i, sr, nsr : ArbInt;
  122. pa, d, cd, u : ^arfloat1;
  123. begin
  124. if (n<1) or (k1<1) or (k2<k1) or (k2>n) then
  125. begin
  126. term:=3; exit
  127. end; {wrong input}
  128. pa:=@a;
  129. sr:=sizeof(ArbFloat); nsr:=n*sr;
  130. getmem(d, nsr); getmem(cd, nsr); getmem(u, n*nsr);
  131. for i:=1 to n do move(pa^[(i-1)*rwidtha+1], u^[(i-1)*n+1], i*sr);
  132. tred1(u^[1], n, n, d^[1], cd^[1], term);
  133. trsturm1(d^[1], cd^[1], n, k1, k2, lam, x, rwidthx, m2, term);
  134. trbak1(u^[1], n, n, cd^[1], k1, k2, x, rwidthx);
  135. freemem(d, nsr); freemem(cd, nsr); freemem(u, n*nsr) { toegevoegd 3 apr 92 }
  136. end; {eiggs4}
  137. procedure eigts1(var d, cd: ArbFloat; n: ArbInt; var lam: ArbFloat;
  138. var term: ArbInt);
  139. var sr, nsr : ArbInt;
  140. pd, pcd, dh, cdh : ^arfloat1;
  141. begin
  142. if n<1 then
  143. begin
  144. term:=3; exit
  145. end; {wrong input}
  146. sr:=sizeof(ArbFloat); nsr:=n*sr;
  147. pd:=@d; pcd:=@cd; getmem(dh, nsr); getmem(cdh, nsr);
  148. move(pd^[1], dh^[1], nsr); move(pcd^[1], cdh^[2], (n-1)*sr);
  149. tql1(dh^[1], cdh^[1], n, lam, term);
  150. if term=2 then
  151. begin
  152. move(pd^[1], dh^[1], nsr); move(pcd^[1], cdh^[2], (n-1)*sr);
  153. bisect(dh^[1], cdh^[1], n, 1, n, 0, lam, term)
  154. end;
  155. freemem(dh, nsr); freemem(cdh, nsr);
  156. end; {eigts1}
  157. procedure eigts2(var d, cd: ArbFloat; n, k1, k2: ArbInt; var lam: ArbFloat;
  158. var term: ArbInt);
  159. var sr, nsr : ArbInt;
  160. pcd, cdh : ^arfloat1;
  161. begin
  162. if (n<1) or (k1<1) or (k2<k1) or (k2>n) then
  163. begin
  164. term:=3; exit
  165. end; {wrong input}
  166. pcd:=@cd;
  167. term:=1; sr:=sizeof(ArbFloat); nsr:=n*sr; getmem(cdh, nsr);
  168. move(pcd^[1], cdh^[2], (n-1)*sr);
  169. bisect(d, cdh^[1], n, k1, k2, 0, lam, term);
  170. freemem(cdh, nsr)
  171. end; {eigts2}
  172. procedure eigts3(var d, cd: ArbFloat; n: ArbInt; var lam, x: ArbFloat;
  173. rwidth: ArbInt; var term: ArbInt);
  174. var i, sr, nsr : ArbInt;
  175. px, pcd, cdh : ^arfloat1;
  176. begin
  177. if n<1 then
  178. begin
  179. term:=3; exit
  180. end;
  181. px:=@x; pcd:=@cd;
  182. sr:=sizeof(ArbFloat); nsr:=n*sr;
  183. getmem(cdh, nsr);
  184. move(pcd^[1], cdh^[2], (n-1)*sr);
  185. for i:=1 to n do fillchar(px^[(i-1)*rwidth+1], nsr, 0);
  186. for i:=1 to n do px^[(i-1)*rwidth+i]:=1;
  187. tql2(d, cdh^[1], n, lam, px^[1], rwidth, term);
  188. freemem(cdh, nsr);
  189. end; {eigts3}
  190. procedure eigts4(var d, cd: ArbFloat; n, k1, k2: ArbInt; var lam, x: ArbFloat;
  191. rwidth: ArbInt; var m2, term: ArbInt);
  192. var sr : ArbInt;
  193. pcd, cdh : ^arfloat1;
  194. begin
  195. if (n<1) or (k1<1) or (k2<k1) or (k2>n) then
  196. begin
  197. term:=3; exit
  198. end; {wrong input}
  199. term:=1;
  200. pcd:=@cd; sr:=sizeof(ArbFloat);
  201. getmem(cdh, n*sr);
  202. move(pcd^[1], cdh^[2], (n-1)*sr);
  203. trsturm1(d, cdh^[1], n, k1, k2, lam, x, rwidth, m2, term);
  204. freemem(cdh, n*sr)
  205. end; {eigts4}
  206. procedure eigbs1(var a: ArbFloat; n, l: ArbInt; var lam: ArbFloat;
  207. var term: ArbInt);
  208. var u, d, cd : ^arfloat1;
  209. uwidth, i, sr, nsr : ArbInt;
  210. begin
  211. if (n<1) or (l<0) or (l>n-1) then
  212. begin
  213. term:=3; exit
  214. end; {wrong input}
  215. sr:=sizeof(ArbFloat); nsr:=n*sr; uwidth:=l+1;
  216. getmem(u, uwidth*nsr); getmem(d, nsr); getmem(cd, nsr);
  217. transf(a, n, l, u^[1], uwidth);
  218. bandrd1(u^[1], n, l, uwidth, d^[1], cd^[1]);
  219. eigts1(d^[1], cd^[2], n, lam, term);
  220. freemem(u, uwidth*nsr); freemem(d, nsr); freemem(cd, nsr);
  221. end; {eigbs1}
  222. procedure eigbs2(var a: ArbFloat; n, l, k1, k2: ArbInt; var lam: ArbFloat;
  223. var term: ArbInt);
  224. var u, d, cd : ^arfloat1;
  225. i, sr, nsr, uwidth : ArbInt;
  226. begin
  227. if (n<1) or (k1<1) or (k2<k1) or (k2>n) or (l<0) or (l>n-1) then
  228. begin
  229. term:=3; exit
  230. end; {wrong input}
  231. sr:=sizeof(ArbFloat); nsr:=n*sr; uwidth:=l+1;
  232. getmem(u, uwidth*nsr); getmem(d, nsr); getmem(cd, nsr);
  233. transf(a, n, l, u^[1], uwidth);
  234. bandrd1(u^[1], n, l, uwidth, d^[1], cd^[1]);
  235. eigts2(d^[1], cd^[2], n, k1, k2, lam, term);
  236. freemem(u, uwidth*nsr); freemem(d, nsr); freemem(cd, nsr)
  237. end; {eigbs2}
  238. procedure eigbs3(var a: ArbFloat; n, l: ArbInt; var lam, x: ArbFloat;
  239. rwidthx: ArbInt; var term: ArbInt);
  240. var u, d, cd : ^arfloat1;
  241. i, sr, nsr, uwidth : ArbInt;
  242. begin
  243. if (n<1) or (l<0) or (l>n-1) then
  244. begin
  245. term:=3; exit
  246. end; {wrong input}
  247. sr:=sizeof(ArbFloat); nsr:=n*sr; uwidth:=l+1;
  248. getmem(u, uwidth*nsr); getmem(d, nsr); getmem(cd, nsr);
  249. transf(a, n, l, u^[1], uwidth);
  250. bandrd2(u^[1], n, l, uwidth, d^[1], cd^[1], x, rwidthx);
  251. tql2(d^[1], cd^[1], n, lam, x, rwidthx, term);
  252. freemem(u, uwidth*nsr); freemem(d, nsr); freemem(cd, nsr)
  253. end; {eigbs3}
  254. procedure eigbs4(var a: ArbFloat; n, l, k1, k2: ArbInt;
  255. var lam, x: ArbFloat; rwidthx: ArbInt;
  256. var m2, term: ArbInt);
  257. var i, j, k, m, uwidth : ArbInt;
  258. plam, px, pa, v, u : ^arfloat1;
  259. s, norm : ArbFloat;
  260. begin
  261. if (n<1) or (k1<1) or (k2<k1) or (k2>n) or (l<0) or (l>n-1) then
  262. begin
  263. term:=3; exit
  264. end; {wrong input}
  265. plam:=@lam; px:=@x; pa:=@a; getmem(v, n*sizeof(ArbFloat));
  266. uwidth:=l+1; getmem(u, n*uwidth*sizeof(ArbFloat));
  267. eigbs2(a, n, l, k1, k2, plam^[1], term);
  268. { kijk of norm(A-lambda.I)=0 }
  269. { zo ja, lever dan de eenheidsvectoren e(k1) t/m e(k2) af }
  270. norm:=0; j:=1;
  271. for i:=1 to n do
  272. begin
  273. if i<=l then m:=i else m:=l+1; s:=0;
  274. for k:=j to j+m-1 do
  275. if k=j+m-1 then s:=s+abs(pa^[k]-plam^[1]) else s:=s+abs(pa^[k]);
  276. if s>norm then norm:=s;
  277. j:=j+m
  278. end;
  279. if norm=0 then
  280. begin
  281. for i:=k1 to k2 do for j:=1 to n do
  282. if j=i then px^[(j-1)*rwidthx+i-k1+1]:=1
  283. else px^[(j-1)*rwidthx+i-k1+1]:=0;
  284. freemem(v, n*sizeof(ArbFloat)); freemem(u, n*uwidth*sizeof(ArbFloat));
  285. m2:=k2; term:=1; exit
  286. end;
  287. transf(a, n, l, u^[1], uwidth);
  288. i:=k1; m2:=k1-1;
  289. while (i <= k2) and (term=1) do
  290. begin
  291. bandev(u^[1], n, l, uwidth, plam^[i-k1+1], v^[1], term);
  292. if term=1 then
  293. begin
  294. m2:=i; for j:=1 to n do px^[(j-1)*rwidthx+i-k1+1]:=v^[j]
  295. end;
  296. i:=i+1
  297. end; {i}
  298. freemem(v, n*sizeof(ArbFloat));
  299. freemem(u, n*uwidth*sizeof(ArbFloat));
  300. end; {eigbs4}
  301. procedure eigge1(var a: ArbFloat; n, rwidth: ArbInt; var lam: complex;
  302. var term: ArbInt);
  303. var pa, h, dummy : ^arfloat1;
  304. i, ns : ArbInt;
  305. begin
  306. if n<1 then
  307. begin
  308. term:=3; exit
  309. end;
  310. ns:=n*sizeof(ArbFloat); pa:=@a;
  311. getmem(dummy, ns); getmem(h, n*ns);
  312. for i:=1 to n do move(pa^[(i-1)*rwidth+1], h^[(i-1)*n+1], ns);
  313. orthes(h^[1], n, n, dummy^[1]);
  314. hessva(h^[1], n, n, lam, term);
  315. freemem(dummy, ns); freemem(h, n*ns);
  316. end; {eigge1}
  317. procedure eigge3(var a: ArbFloat; n, rwidtha: ArbInt; var lam, x: complex;
  318. rwidthx: ArbInt; var term: ArbInt);
  319. var pa, pd, u, v: ^arfloat1;
  320. m1, m2, i, j, ns: ArbInt;
  321. begin
  322. if n<1 then
  323. begin
  324. term:=3; exit
  325. end;
  326. ns:=n*sizeof(ArbFloat); getmem(pd, ns); getmem(u, n*ns); getmem(v, n*ns);
  327. pa:=@a; for i:=1 to n do move(pa^[(i-1)*rwidtha+1], u^[(i-1)*n+1], ns);
  328. balance(u^[1], n, n, m1, m2, pd^[1]);
  329. orttrans(u^[1], n, n, v^[1], n);
  330. hessvec(u^[1], n, n, lam, v^[1], n, term);
  331. if term=1 then
  332. begin
  333. balback(pd^[1], n, m1, m2, 1, n, v^[1], n);
  334. normeer(lam, n, v^[1], n);
  335. transx(v^[1], n, n, lam, x, rwidthx)
  336. end;
  337. freemem(pd, ns); freemem(u, n*ns); freemem(v, n*ns);
  338. end; {eigge3}
  339. procedure eiggg1(var a: ArbFloat; n, rwidtha: ArbInt; var b: ArbFloat;
  340. rwidthb: ArbInt; var lam: ArbFloat; var term: ArbInt);
  341. var u, v, pa, pb : ^arfloat1;
  342. i, j, ns : ArbInt;
  343. begin
  344. if n<1 then
  345. begin
  346. term:=3; exit
  347. end;
  348. pa:=@a; pb:=@b; ns:=n*sizeof(ArbFloat); getmem(u, n*ns); getmem(v, n*ns);
  349. for i:=1 to n do move(pa^[(i-1)*rwidtha+1], u^[(i-1)*n+1], ns);
  350. for i:=1 to n do move(pb^[(i-1)*rwidthb+1], v^[(i-1)*n+1], ns);
  351. reduc1(u^[1], n, n, v^[1], n, term);
  352. if term=1 then eiggs1(u^[1], n, n, lam, term);
  353. freemem(u, n*ns); freemem(v, n*ns);
  354. end; {eiggg1}
  355. procedure eiggg2(var a: ArbFloat; n, rwidtha, k1, k2: ArbInt; var b: ArbFloat;
  356. rwidthb: ArbInt; var lam: ArbFloat; var term: ArbInt);
  357. var u, v, pa, pb : ^arfloat1;
  358. i, j, ns : ArbInt;
  359. begin
  360. if (n<1) or (k1<1) or (k2<k1) or (k2>n) then
  361. begin
  362. term:=3; exit
  363. end;
  364. pa:=@a; pb:=@b; ns:=n*sizeof(ArbFloat); getmem(u, n*ns); getmem(v, n*ns);
  365. for i:=1 to n do move(pa^[(i-1)*rwidtha+1], u^[(i-1)*n+1], ns);
  366. for i:=1 to n do move(pb^[(i-1)*rwidthb+1], v^[(i-1)*n+1], ns);
  367. reduc1(u^[1], n, n, v^[1], n, term);
  368. if term=1 then eiggs2(u^[1], n, n, k1, k2, lam, term);
  369. freemem(u, n*ns); freemem(v, n*ns)
  370. end; {eiggg2}
  371. procedure eiggg3(var a: ArbFloat; n, rwidtha: ArbInt; var b: ArbFloat;
  372. rwidthb: ArbInt; var lam, x: ArbFloat; rwidthx: ArbInt;
  373. var term: ArbInt);
  374. var u, v, pa, pb : ^arfloat1;
  375. i, j, ns : ArbInt;
  376. begin
  377. if n<1 then
  378. begin
  379. term:=3; exit
  380. end;
  381. pa:=@a; pb:=@b;
  382. ns:=n*sizeof(ArbFloat);
  383. getmem(u, n*ns); getmem(v, n*ns);
  384. for i:=1 to n do move(pa^[(i-1)*rwidtha+1], u^[(i-1)*n+1], ns);
  385. for i:=1 to n do move(pb^[(i-1)*rwidthb+1], v^[(i-1)*n+1], ns);
  386. reduc1(u^[1], n, n, v^[1], n, term);
  387. if term=1 then
  388. begin
  389. eiggs3(u^[1], n, n, lam, x, rwidthx, term);
  390. if term=1 then rebaka(v^[1], n, n, 1, n, x, rwidthx, term)
  391. end;
  392. freemem(u, n*ns); freemem(v, n*ns)
  393. end; {eiggg3}
  394. procedure eiggg4(var a: ArbFloat; n, rwidtha, k1, k2: ArbInt; var b: ArbFloat;
  395. rwidthb: ArbInt; var lam, x: ArbFloat; rwidthx: ArbInt;
  396. var m2, term: ArbInt);
  397. var u, v, pa, pb : ^arfloat1;
  398. i, j, ns, t : ArbInt;
  399. begin
  400. if (n<1) or (k1<1) or (k2<k1) or (k2>n) then
  401. begin
  402. term:=3; exit
  403. end;
  404. pa:=@a; pb:=@b; ns:=n*sizeof(ArbFloat); getmem(u, n*ns); getmem(v, n*ns);
  405. for i:=1 to n do move(pa^[(i-1)*rwidtha+1], u^[(i-1)*n+1], ns);
  406. for i:=1 to n do move(pb^[(i-1)*rwidthb+1], v^[(i-1)*n+1], ns);
  407. reduc1(u^[1], n, n, v^[1], n, term);
  408. if term=1 then
  409. begin
  410. eiggs4(u^[1], n, n, k1, k2, lam, x, rwidthx, m2, term);
  411. if m2 < k2 then term:=4;
  412. if m2 > k1-1 then
  413. begin
  414. rebaka(v^[1], n, n, k1, m2, x, rwidthx, t);
  415. if t=2 then
  416. begin
  417. term:=4; m2:=k1-1
  418. end
  419. end
  420. end;
  421. freemem(u, n*ns); freemem(v, n*ns)
  422. end; {eiggg4}
  423. procedure eigsv1(var a: ArbFloat; m, n, rwidth: ArbInt; var sig: ArbFloat;
  424. var term: ArbInt);
  425. var pa, pq, u, e : ^arfloat1;
  426. i, j, k, l, ns, ii, jj, kk : ArbInt;
  427. c, f, g, h, p, s, x, y, z, eps, tol : ArbFloat;
  428. conv, goon, cancel : boolean;
  429. begin
  430. if (n<1) or (m<n) then
  431. begin
  432. term:=3; exit
  433. end;
  434. pa:=@a; pq:=@sig; term:=1;
  435. ns:=n*sizeof(ArbFloat); getmem(e, ns); getmem(u, m*ns);
  436. for i:=1 to m do move(pa^[(i-1)*rwidth+1], u^[(i-1)*n+1], ns);
  437. g:=0; x:=0; tol:=midget/macheps;
  438. for i:=1 to n do
  439. begin
  440. ii:=(i-1)*n; e^[i]:=g;
  441. s:=0; for j:=i to m do s:=s+sqr(u^[(j-1)*n+i]);
  442. if s<tol then g:=0 else
  443. begin
  444. f:=u^[ii+i]; if f<0 then g:=sqrt(s) else g:=-sqrt(s);
  445. h:=f*g-s; u^[ii+i]:=f-g;
  446. for j:=i+1 to n do
  447. begin
  448. s:=0;
  449. for k:=i to m do
  450. begin
  451. kk:=(k-1)*n; s:=s+u^[kk+i]*u^[kk+j]
  452. end; {k}
  453. f:=s/h;
  454. for k:=i to m do
  455. begin
  456. kk:=(k-1)*n; u^[kk+j]:=u^[kk+j]+f*u^[kk+i]
  457. end {k}
  458. end {j}
  459. end; {s}
  460. pq^[i]:=g; s:=0;
  461. for j:=i+1 to n do s:=s+sqr(u^[ii+j]);
  462. if s < tol then g:=0 else
  463. begin
  464. f:=u^[ii+i+1]; if f < 0 then g:=sqrt(s) else g:=-sqrt(s);
  465. h:=f*g-s; u^[ii+i+1]:=f-g;
  466. for j:=i+1 to n do e^[j]:=u^[ii+j]/h;
  467. for j:=i+1 to m do
  468. begin
  469. s:=0; jj:=(j-1)*n;
  470. for k:=i+1 to n do s:=s+u^[jj+k]*u^[ii+k];
  471. for k:=i+1 to n do u^[jj+k]:=u^[jj+k]+s*e^[k]
  472. end {j}
  473. end; {s}
  474. y:=abs(pq^[i])+abs(e^[i]); if y > x then x:=y
  475. end; {i}
  476. eps:=macheps*x;
  477. for k:=n downto 1 do
  478. begin
  479. conv:=false;
  480. repeat
  481. l:=k; goon:=true;
  482. while goon do
  483. begin
  484. if abs(e^[l]) <= eps then
  485. begin
  486. goon:=false; cancel:=false
  487. end else
  488. if abs(pq^[l-1]) <= eps then
  489. begin
  490. goon:=false; cancel:=true
  491. end
  492. else l:=l-1
  493. end; {goon}
  494. if cancel then
  495. begin
  496. c:=0; s:=1;
  497. i:=l; goon:=true;
  498. while goon do
  499. begin
  500. f:=s*e^[i]; e^[i]:=c*e^[i]; goon:=abs(f) > eps;
  501. if goon then
  502. begin
  503. g:=pq^[i]; h:=sqrt(f*f+g*g); pq^[i]:=h;
  504. c:=g/h; s:=-f/h;
  505. i:=i+1; goon:=i <= k
  506. end {goon}
  507. end {while goon}
  508. end; {cancel}
  509. z:=pq^[k];
  510. if k=l then conv:=true else
  511. begin
  512. x:=pq^[l]; y:=pq^[k-1]; g:=e^[k-1]; h:=e^[k];
  513. f:=((y-z)*(y+z)+(g-h)*(g+h))/(2*h*y); g:=sqrt(f*f+1);
  514. if f < 0 then s:=f-g else s:=f+g;
  515. f:=((x-z)*(x+z)+h*(y/s-h))/x;
  516. c:=1; s:=1;
  517. for i:=l+1 to k do
  518. begin
  519. g:=e^[i]; y:=pq^[i]; h:=s*g; g:=c*g;
  520. z:=sqrt(f*f+h*h); e^[i-1]:=z; c:=f/z; s:=h/z;
  521. f:=x*c+g*s; g:=-x*s+g*c; h:=y*s; y:=y*c;
  522. z:=sqrt(f*f+h*h); pq^[i-1]:=z; c:=f/z; s:=h/z;
  523. f:=c*g+s*y; x:=-s*g+c*y
  524. end; {i}
  525. e^[l]:=0; e^[k]:=f; pq^[k]:=x
  526. end {k <> l}
  527. until conv;
  528. if z < 0 then pq^[k]:=-z
  529. end; {k}
  530. for i:=1 to n do
  531. begin
  532. k:=i; p:=pq^[i];
  533. for j:=i+1 to n do
  534. if pq^[j] < p then
  535. begin
  536. k:=j; p:=pq^[j]
  537. end;
  538. if k <> i then
  539. begin
  540. pq^[k]:=pq^[i]; pq^[i]:=p
  541. end
  542. end; {i}
  543. freemem(e, ns); freemem(u, m*ns)
  544. end; {eigsv1}
  545. procedure eigsv3(var a: ArbFloat; m, n, rwidtha: ArbInt; var sig, u: ArbFloat;
  546. rwidthu: ArbInt; var v: ArbFloat; rwidthv: ArbInt;
  547. var term: ArbInt);
  548. var pa, pu, pq, pv, e : ^arfloat1;
  549. i, j, k, l, ns, ii, jj, kk : ArbInt;
  550. c, f, g, h, p, s, x, y, z, eps, tol : ArbFloat;
  551. conv, goon, cancel : boolean;
  552. begin
  553. if (n<1) or (m<n)
  554. then
  555. begin
  556. term:=3; exit
  557. end;
  558. pa:=@a; pu:=@u; pq:=@sig; pv:=@v; term:=1;
  559. ns:=n*sizeof(ArbFloat); getmem(e, ns);
  560. for i:=1 to m do move(pa^[(i-1)*rwidtha+1], pu^[(i-1)*rwidthu+1], ns);
  561. g:=0; x:=0; tol:=midget/macheps;
  562. for i:=1 to n do
  563. begin
  564. ii:=(i-1)*rwidthu;
  565. e^[i]:=g; s:=0;
  566. for j:=i to m do s:=s+sqr(pu^[(j-1)*rwidthu+i]);
  567. if s<tol then g:=0 else
  568. begin
  569. f:=pu^[ii+i]; if f<0 then g:=sqrt(s) else g:=-sqrt(s);
  570. h:=f*g-s; pu^[ii+i]:=f-g;
  571. for j:=i+1 to n do
  572. begin
  573. s:=0;
  574. for k:=i to m do
  575. begin
  576. kk:=(k-1)*rwidthu; s:=s+pu^[kk+i]*pu^[kk+j]
  577. end; {k}
  578. f:=s/h;
  579. for k:=i to m do
  580. begin
  581. kk:=(k-1)*rwidthu; pu^[kk+j]:=pu^[kk+j]+f*pu^[kk+i]
  582. end {k}
  583. end {j}
  584. end; {s}
  585. pq^[i]:=g; s:=0; for j:=i+1 to n do s:=s+sqr(pu^[ii+j]);
  586. if s < tol then g:=0 else
  587. begin
  588. f:=pu^[ii+i+1];
  589. if f < 0 then g:=sqrt(s) else g:=-sqrt(s);
  590. h:=f*g-s; pu^[ii+i+1]:=f-g;
  591. for j:=i+1 to n do e^[j]:=pu^[ii+j]/h;
  592. for j:=i+1 to m do
  593. begin
  594. s:=0; jj:=(j-1)*rwidthu;
  595. for k:=i+1 to n do s:=s+pu^[jj+k]*pu^[ii+k];
  596. for k:=i+1 to n do pu^[jj+k]:=pu^[jj+k]+s*e^[k]
  597. end {j}
  598. end; {s}
  599. y:=abs(pq^[i])+abs(e^[i]); if y > x then x:=y
  600. end; {i}
  601. for i:=n downto 1 do
  602. begin
  603. ii:=(i-1)*rwidthu;
  604. if g <> 0 then
  605. begin
  606. h:=pu^[ii+i+1]*g;
  607. for j:=i+1 to n do pv^[(j-1)*rwidthv+i]:=pu^[ii+j]/h;
  608. for j:=i+1 to n do
  609. begin
  610. s:=0;
  611. for k:=i+1 to n do s:=s+pu^[ii+k]*pv^[(k-1)*rwidthv+j];
  612. for k:=i+1 to n do
  613. begin
  614. kk:=(k-1)*rwidthv; pv^[kk+j]:=pv^[kk+j]+s*pv^[kk+i]
  615. end {k}
  616. end {j}
  617. end; {g}
  618. ii:=(i-1)*rwidthv;
  619. for j:=i+1 to n do
  620. begin
  621. pv^[ii+j]:=0; pv^[(j-1)*rwidthv+i]:=0
  622. end; {j}
  623. pv^[ii+i]:=1; g:=e^[i]
  624. end; {i}
  625. for i:=n downto 1 do
  626. begin
  627. g:=pq^[i]; ii:=(i-1)*rwidthu;
  628. for j:=i+1 to n do pu^[ii+j]:=0;
  629. if g <> 0 then
  630. begin
  631. h:=pu^[ii+i]*g;
  632. for j:=i+1 to n do
  633. begin
  634. s:=0;
  635. for k:=i+1 to m do
  636. begin
  637. kk:=(k-1)*rwidthu; s:=s+pu^[kk+i]*pu^[kk+j]
  638. end; {k}
  639. f:=s/h;
  640. for k:=i to m do
  641. begin
  642. kk:=(k-1)*rwidthu;
  643. pu^[kk+j]:=pu^[kk+j]+f*pu^[kk+i]
  644. end {k}
  645. end; {j}
  646. for j:=i to m do
  647. begin
  648. jj:=(j-1)*rwidthu+i; pu^[jj]:=pu^[jj]/g
  649. end {j}
  650. end {g}
  651. else
  652. for j:=i to m do pu^[(j-1)*rwidthu+i]:=0;
  653. pu^[ii+i]:=pu^[ii+i]+1
  654. end; {i}
  655. eps:=macheps*x;
  656. for k:=n downto 1 do
  657. begin
  658. conv:=false;
  659. repeat
  660. l:=k; goon:=true;
  661. while goon do
  662. begin
  663. if abs(e^[l]) <= eps then
  664. begin
  665. goon:=false; cancel:=false
  666. end else
  667. if abs(pq^[l-1]) <= eps then
  668. begin
  669. goon:=false; cancel:=true
  670. end else l:=l-1
  671. end; {goon}
  672. if cancel then
  673. begin
  674. c:=0; s:=1; i:=l; goon:=true;
  675. while goon do
  676. begin
  677. f:=s*e^[i]; e^[i]:=c*e^[i]; goon:=abs(f) > eps;
  678. if goon then
  679. begin
  680. g:=pq^[i]; h:=sqrt(f*f+g*g); pq^[i]:=h;
  681. c:=g/h; s:=-f/h;
  682. for j:=1 to m do
  683. begin
  684. jj:=(j-1)*rwidthu; y:=pu^[jj+l-1]; z:=pu^[jj+i];
  685. pu^[jj+l-1]:=y*c+z*s; pu^[jj+i]:=-y*s+z*c
  686. end; {j}
  687. i:=i+1; goon:=i <= k
  688. end {goon}
  689. end {while goon}
  690. end; {cancel}
  691. z:=pq^[k]; if k=l then conv:=true else
  692. begin
  693. x:=pq^[l]; y:=pq^[k-1]; g:=e^[k-1]; h:=e^[k];
  694. f:=((y-z)*(y+z)+(g-h)*(g+h))/(2*h*y); g:=sqrt(f*f+1);
  695. if f < 0 then s:=f-g else s:=f+g;
  696. f:=((x-z)*(x+z)+h*(y/s-h))/x;
  697. c:=1; s:=1;
  698. for i:=l+1 to k do
  699. begin
  700. g:=e^[i]; y:=pq^[i]; h:=s*g; g:=c*g;
  701. z:=sqrt(f*f+h*h); e^[i-1]:=z; c:=f/z; s:=h/z;
  702. f:=x*c+g*s; g:=-x*s+g*c; h:=y*s; y:=y*c;
  703. for j:=1 to n do
  704. begin
  705. jj:=(j-1)*rwidthv;
  706. x:=pv^[jj+i-1]; z:=pv^[jj+i];
  707. pv^[jj+i-1]:=x*c+z*s; pv^[jj+i]:=-x*s+z*c
  708. end; {j}
  709. z:=sqrt(f*f+h*h); pq^[i-1]:=z; c:=f/z; s:=h/z;
  710. f:=c*g+s*y; x:=-s*g+c*y;
  711. for j:=1 to m do
  712. begin
  713. jj:=(j-1)*rwidthu;
  714. y:=pu^[jj+i-1]; z:=pu^[jj+i];
  715. pu^[jj+i-1]:=y*c+z*s; pu^[jj+i]:=-y*s+z*c
  716. end {j}
  717. end; {i}
  718. e^[l]:=0; e^[k]:=f; pq^[k]:=x
  719. end {k <> l}
  720. until conv;
  721. if z < 0 then
  722. begin
  723. pq^[k]:=-z;
  724. for j:=1 to n do
  725. begin
  726. jj:=(j-1)*rwidthv+k; pv^[jj]:=-pv^[jj]
  727. end {j}
  728. end {z}
  729. end; {k}
  730. for i:=1 to n do
  731. begin
  732. k:=i; p:=pq^[i];
  733. for j:=i+1 to n do
  734. if pq^[j] < p then
  735. begin
  736. k:=j; p:=pq^[j]
  737. end;
  738. if k <> i then
  739. begin
  740. pq^[k]:=pq^[i]; pq^[i]:=p;
  741. for j:=1 to m do
  742. begin
  743. jj:=(j-1)*rwidthu;
  744. p:=pu^[jj+i]; pu^[jj+i]:=pu^[jj+k]; pu^[jj+k]:=p;
  745. end;
  746. for j:=1 to n do
  747. begin
  748. jj:=(j-1)*rwidthv;
  749. p:=pv^[jj+i]; pv^[jj+i]:=pv^[jj+k]; pv^[jj+k]:=p
  750. end { interchange in u and v column i with comlumn k }
  751. end
  752. end; {i}
  753. freemem(e, ns)
  754. end; {eigsv3}
  755. end.
  756. {
  757. $Log$
  758. Revision 1.2 2000-01-25 20:21:41 marco
  759. * small updates, crlf fix, and RTE 207 problem
  760. Revision 1.1 2000/01/24 22:08:58 marco
  761. * initial version
  762. }