eig.pas 26 KB

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