eig.pas 26 KB

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