roo.pas 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435
  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. Unit to find roots of (various kinds of) equations
  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 roo;
  16. {$i direct.inc}
  17. interface
  18. uses typ, spe;
  19. {Find the all roots of the binomial eq. x^n=a, with "a" a complex number}
  20. Procedure roobin(n: ArbInt; a: complex; Var z: complex; Var term: ArbInt);
  21. {Find root point of f(x)=0 with f(x) a continuous function on domain [a,b]
  22. If f(a)*f(b)<=0 then there must be (at least) one rootpoint}
  23. Procedure roof1r(f: rfunc1r; a, b, ae, re: ArbFloat; Var x: ArbFloat;
  24. Var term: ArbInt);
  25. {Determine all zeropoints for a given n'th degree polynomal with real
  26. coefficients}
  27. Procedure roopol(Var a: ArbFloat; n: ArbInt; Var z: complex;
  28. Var k, term: ArbInt);
  29. {Find roots for a simple 2th degree eq x^2+px+q=0 with p and q real}
  30. Procedure rooqua(p, q: ArbFloat; Var z1, z2: complex);
  31. {Roofnr is undocumented, but verry big}
  32. Procedure roofnr(f: roofnrfunc; n: ArbInt; Var x, residu: ArbFloat; re: ArbFloat;
  33. Var term: ArbInt);
  34. { term : 1 succesful termination
  35. 2 Couldn't reach the specified precision
  36. Value X is the best one which could be found.
  37. 3 Wrong input
  38. 4 Too many functionvalues calculated, try to recalc with the
  39. calculated X
  40. 5 Not enough progress. Possibly there is no solution, or the
  41. solution is too close to 0. Try to choose a different
  42. initial startingvalue
  43. 6 Process wants to calculate a function value outside the by
  44. "deff" defined area.
  45. }
  46. implementation
  47. Procedure roobin(n: ArbInt; a: complex; Var z: complex; Var term: ArbInt);
  48. { This procedure solves the binomial equation z**n = a, with a complex}
  49. Var i, j, k : ArbInt;
  50. w, fie, dfie, r : ArbFloat;
  51. pz : ^arcomp1;
  52. Begin
  53. If n<1 Then
  54. Begin
  55. term := 2;
  56. exit
  57. End;
  58. term := 1;
  59. pz := @z;
  60. dfie := 2*pi/n;
  61. k := 1;
  62. If a.im=0 Then
  63. Begin
  64. If a.re>0 Then
  65. Begin
  66. r := spepow(a.re, 1/n);
  67. pz^[1].Init(r, 0);
  68. k := k+1;
  69. i := (n-1) Div 2;
  70. If Not odd(n) Then
  71. Begin
  72. pz^[k].Init(-r, 0);
  73. k := k+1
  74. End;
  75. For j:=1 To i Do
  76. Begin
  77. w := j*dfie;
  78. pz^[k].Init(r*cos(w), r*sin(w));
  79. pz^[k+1] := pz^[k];
  80. pz^[k+1].Conjugate;
  81. k := k+2
  82. End
  83. End
  84. Else
  85. Begin
  86. fie := pi/n;
  87. r := spepow(-a.re, 1/n);
  88. i := n Div 2-1;
  89. If odd(n) Then
  90. Begin
  91. pz^[k].Init(-r, 0);
  92. k := k+1
  93. End;
  94. For j:=0 To i Do
  95. Begin
  96. w := fie+j*dfie;
  97. pz^[k].Init(r*cos(w), r*sin(w));
  98. pz^[k+1] := pz^[k];
  99. pz^[k+1].Conjugate;
  100. k := k+2
  101. End
  102. End
  103. End
  104. Else
  105. Begin
  106. If abs(a.re)>=abs(a.im) Then
  107. r := spepow(abs(a.re)*sqrt(1+sqr(a.im/a.re)), 1/n)
  108. Else r := spepow(abs(a.im)*sqrt(1+sqr(a.re/a.im)), 1/n);
  109. fie := a.arg/n;
  110. i := n Div 2;
  111. For j:=0 To n-1 Do
  112. Begin
  113. w := fie+(j-i)*dfie;
  114. pz^[j+1].Init(r*cos(w), r*sin(w))
  115. End
  116. End
  117. End {roobin};
  118. Procedure roof1r(f: rfunc1r; a, b, ae, re: ArbFloat; Var x: ArbFloat;
  119. Var term: ArbInt);
  120. Var fa, fb, c, fc, m, tol, w1, w2 : ArbFloat;
  121. k : ArbInt;
  122. stop : boolean;
  123. Begin
  124. fa := f(a);
  125. fb := f(b);
  126. If (spesgn(fa)*spesgn(fb)=1) Or (ae<0) Or (re<0)
  127. Then {wrong input}
  128. Begin
  129. term := 3;
  130. exit
  131. End;
  132. If abs(fb)>abs(fa) Then
  133. Begin
  134. c := b;
  135. fc := fb;
  136. x := a;
  137. b := a;
  138. fb := fa;
  139. a := c;
  140. fa := fc
  141. End
  142. Else
  143. Begin
  144. c := a;
  145. fc := fa;
  146. x := b
  147. End;
  148. k := 0;
  149. tol := ae+re*spemax(abs(a), abs(b));
  150. w1 := abs(b-a);
  151. stop := false;
  152. while (abs(b-a)>tol) and (fb<>0) and (Not stop) Do
  153. Begin
  154. m := (a+b)/2;
  155. If (k>=2) Or (fb=fc) Then x := m
  156. Else
  157. Begin
  158. x := (b*fc-c*fb)/(fc-fb);
  159. If abs(b-x)<tol Then x := b-tol*spesgn(b-a);
  160. If spesgn(x-m)=spesgn(x-b) Then x := m
  161. End;
  162. c := b;
  163. fc := fb;
  164. b := x;
  165. fb := f(x);
  166. If spesgn(fa)*spesgn(fb)>0 Then
  167. Begin
  168. a := c;
  169. fa := fc;
  170. k := 0
  171. End
  172. Else k := k+1;
  173. If abs(fb)>=abs(fa) Then
  174. Begin
  175. c := b;
  176. fc := fb;
  177. x := a;
  178. b := a;
  179. fb := fa;
  180. a := c;
  181. fa := fc;
  182. k := 0
  183. End;
  184. tol := ae+re*spemax(abs(a), abs(b));
  185. w2 := abs(b-a);
  186. If w2>=w1 Then
  187. Begin
  188. stop := true;
  189. term := 2
  190. End;
  191. w1 := w2
  192. End;
  193. If Not stop Then term := 1
  194. End {roof1r};
  195. Procedure roopol(Var a: ArbFloat; n: ArbInt; Var z: complex;
  196. Var k, term: ArbInt);
  197. Const max = 50;
  198. Type rnep2 = array[-2..$ffe0 div SizeOf(ArbFloat)] Of ArbFloat;
  199. Var rk, i, j, l, m, length, term1 : ArbInt;
  200. p, q, r, s, f, df, delp, delq, delr, telp, telq, sn, sn1,
  201. sn2, noise, noise1, noise2, g, absr, maxcoef, coef, d, t,
  202. maxx, fac, meps : ArbFloat;
  203. convergent, linear, quadratic : boolean;
  204. u, v : complex;
  205. pa : ^arfloat1;
  206. pb, pc, ph : ^rnep2;
  207. pz : ^arcomp1;
  208. Function gcd(n, m: ArbInt): ArbInt;
  209. { This function computes the greatest common divisor of m and n}
  210. Var r : ArbInt;
  211. Begin
  212. r := n Mod m;
  213. while r>0 Do
  214. Begin
  215. n := m;
  216. m := r;
  217. r := n Mod m
  218. End;
  219. gcd := m
  220. End {gcd};
  221. Begin
  222. If n<1 Then
  223. Begin
  224. term := 3;
  225. exit
  226. End;
  227. length := (n+3)*sizeof(ArbFloat);
  228. getmem(pb, length);
  229. getmem(pc, length);
  230. getmem(ph, length);
  231. meps := macheps;
  232. pa := @a;
  233. pz := @z;
  234. pb^[-2] := 0;
  235. pb^[-1] := 0;
  236. pc^[-2] := 0;
  237. pc^[-1] := 0;
  238. ph^[-1] := 0;
  239. ph^[0] := 1;
  240. For i:=1 To n Do
  241. ph^[i] := pa^[i];
  242. k := 0;
  243. while (n>0) and (ph^[n]=0) Do
  244. Begin
  245. k := k+1;
  246. pz^[k].Init(0, 0);
  247. n := n-1
  248. End;
  249. If n>0 Then
  250. Begin
  251. l := n;
  252. i := 1;
  253. while (l>1) and (i<n) Do
  254. Begin
  255. If ph^[i] <> 0 Then l := gcd(l, n-i);
  256. i := i+1
  257. End;
  258. If l>1 Then
  259. Begin
  260. n := n Div l;
  261. For i:=1 To n Do
  262. ph^[i] := ph^[l*i]
  263. End
  264. End;
  265. convergent := true ;
  266. while (n>0) and convergent Do
  267. Begin
  268. linear := false;
  269. quadratic := false ;
  270. If n=1 Then
  271. Begin
  272. r := -ph^[1]/ph^[0];
  273. linear := true
  274. End;
  275. If n=2 Then
  276. Begin
  277. p := ph^[1]/ph^[0];
  278. q := ph^[2]/ph^[0];
  279. quadratic := true
  280. End;
  281. If n>2 Then
  282. Begin
  283. If (ph^[n-1]=0) Or (ph^[n-2]=0) Then
  284. Begin
  285. maxcoef := abs(ph^[n-1]/ph^[n]);
  286. For i:=2 To n Do
  287. Begin
  288. coef := spepow(abs(ph^[n-i]/ph^[n]),1/i);
  289. If maxcoef<coef Then maxcoef := coef
  290. End;
  291. maxcoef := 2*maxcoef
  292. End;
  293. If ph^[n-1]=0 Then r := -spesgn(ph^[0])*spesgn(ph^[n])/maxcoef
  294. Else r := -ph^[n]/ph^[n-1];
  295. If ph^[n-2]=0 Then
  296. Begin
  297. p := 0;
  298. q := -1/sqr(maxcoef)
  299. End
  300. Else
  301. Begin
  302. q := ph^[n]/ph^[n-2];
  303. p := (ph^[n-1]-q*ph^[n-3])/ph^[n-2]
  304. End;
  305. m := 0;
  306. while (m<max) and (Not linear) and (Not quadratic) Do
  307. Begin
  308. m := m+1;
  309. For j:=0 To n Do
  310. pb^[j] := ph^[j]-p*pb^[j-1]-q*pb^[j-2];
  311. For j:=0 To n-2 Do
  312. pc^[j] := pb^[j]-p*pc^[j-1]-q*pc^[j-2];
  313. pc^[n-1] := -p*pc^[n-2]-q*pc^[n-3];
  314. s := sqr(pc^[n-2])-pc^[n-1]*pc^[n-3];
  315. telp := pb^[n-1]*pc^[n-2]-pb^[n]*pc^[n-3];
  316. telq := pb^[n]*pc^[n-2]-pb^[n-1]*pc^[n-1];
  317. If s=0 Then
  318. Begin
  319. delp := telp;
  320. delq := telq
  321. End
  322. Else
  323. Begin
  324. delp := telp/s;
  325. delq := telq/s
  326. End;
  327. noise1 := 0;
  328. sn1 := 0;
  329. sn := 1;
  330. noise2 := 4*abs(pb^[n])+3*abs(p*pb^[n-1]);
  331. For j:=n-1 Downto 0 Do
  332. Begin
  333. g := 4*abs(pb^[j])+3*abs(p*pb^[j-1]);
  334. noise1 := noise1+g*abs(sn);
  335. sn2 := sn1;
  336. sn1 := sn;
  337. sn := -p*sn1-q*sn2;
  338. noise2 := noise2+g*abs(sn)
  339. End;
  340. d := p*p-4*q;
  341. absr := abs(r);
  342. f := ph^[0];
  343. df := 0;
  344. noise := abs(f)/2;
  345. For j:=1 To n Do
  346. Begin
  347. df := f+r*df;
  348. f := ph^[j]+r*f;
  349. noise := abs(f)+absr*noise
  350. End;
  351. If df=0 Then delr := f
  352. Else delr := f/df;
  353. If (abs(telp)<=meps*(noise1*abs(pc^[n-2])+
  354. noise2*abs(pc^[n-3])))
  355. And
  356. (abs(telq)<=meps*(noise1* abs(pc^[n-1])+
  357. noise2*abs(pc^[n-2])))
  358. Then quadratic := true
  359. Else
  360. Begin
  361. p := p+delp;
  362. q := q+delq
  363. End;
  364. If abs(f)<=2*meps*noise Then linear := true
  365. Else r := r-delr
  366. End
  367. End;
  368. convergent := linear Or quadratic;
  369. If linear Then
  370. Begin
  371. If l=1 Then
  372. Begin
  373. k := k+1;
  374. pz^[k].xreal := r;
  375. pz^[k].imag := 0
  376. End
  377. Else
  378. Begin
  379. u.init(r, 0);
  380. roobin(l, u, pz^[k+1], term1);
  381. k := k+l
  382. End;
  383. maxx := 0;
  384. rk := 0;
  385. fac := 1;
  386. For j:=n Downto 0 Do
  387. Begin
  388. s := abs(ph^[j]*fac);
  389. fac := fac*r;
  390. If s>maxx Then
  391. Begin
  392. maxx := s;
  393. rk := j-1
  394. End
  395. End;
  396. For j:=1 To rk Do
  397. ph^[j] := ph^[j]+r*ph^[j-1];
  398. If rk<n-1 Then
  399. Begin
  400. s := ph^[n-1];
  401. ph^[n-1] := -ph^[n]/r;
  402. For j:=n-2 Downto rk+1 Do
  403. Begin
  404. t := ph^[j];
  405. ph^[j] := (ph^[j+1]-s)/r;
  406. s := t
  407. End
  408. End;
  409. n := n-1;
  410. End
  411. Else
  412. If quadratic Then
  413. Begin
  414. If l=1 Then
  415. Begin
  416. rooqua(p,q,pz^[k+1],pz^[k+2]);
  417. k := k+2
  418. End
  419. Else
  420. Begin
  421. rooqua(p,q,u,v);
  422. roobin(l,u,pz^[k+1],term1);
  423. roobin(l,v,pz^[k+l+1],term1);
  424. k := k+2*l
  425. End;
  426. n := n-2;
  427. For j:=1 To n Do
  428. ph^[j] := ph^[j]-p*ph^[j-1]-q*ph^[j-2]
  429. End
  430. End;
  431. If k<n Then term := 2
  432. Else term := 1;
  433. freemem(pb, length);
  434. freemem(pc, length);
  435. freemem(ph, length);
  436. End {roopol};
  437. Procedure rooqua(p, q: ArbFloat; Var z1, z2: complex);
  438. Var s, d : ArbFloat;
  439. Begin
  440. p := -p/2;
  441. d := sqr(p)-q;
  442. If d<0 Then
  443. Begin
  444. z1.Init(p, sqrt(-d));
  445. z2 := z1;
  446. z2.conjugate
  447. End
  448. Else
  449. Begin
  450. If p>0 Then s := p+sqrt(d)
  451. Else s := p-sqrt(d);
  452. If s=0 Then
  453. Begin
  454. z1.Init(0, 0);
  455. z2 := z1
  456. End
  457. Else
  458. Begin
  459. z1.Init(s, 0);
  460. z2.Init(q/s, 0)
  461. End
  462. End
  463. End {rooqua};
  464. Procedure roo001(uplo, trans, diag: char; n: ArbInt; Var ap1, x1: ArbFloat;
  465. incx: ArbInt);
  466. Var
  467. ap : arfloat1 absolute ap1;
  468. x : arfloat1 absolute x1;
  469. temp : ArbFloat;
  470. i, info, ix, j, jx, k, kk, kx: ArbInt;
  471. nounit: boolean;
  472. Begin
  473. info := 0;
  474. uplo := upcase(uplo);
  475. trans := upcase(trans);
  476. diag := upcase(diag);
  477. If n=0 Then exit;
  478. nounit := diag='N';
  479. If incx<=0 Then kx := 1-(n-1)*incx
  480. Else kx := 1;
  481. If trans='N' Then
  482. Begin
  483. If uplo='U' Then
  484. Begin
  485. kk := 1;
  486. jx := kx;
  487. For j:=1 To n Do
  488. Begin
  489. If x[jx]<>0 Then
  490. Begin
  491. temp := x[jx];
  492. ix := kx;
  493. For k:=kk To kk+j-2 Do
  494. Begin
  495. x[ix] := x[ix]+temp*ap[k];
  496. inc(ix, incx)
  497. End;
  498. If nounit Then x[jx] := x[jx]*ap[kk+j-1]
  499. End;
  500. inc(jx, incx);
  501. inc(kk, j)
  502. End
  503. End
  504. Else
  505. Begin
  506. kk := n*(n+1) Div 2;
  507. inc(kx, (n-1)*incx);
  508. jx := kx;
  509. For j:=n Downto 1 Do
  510. Begin
  511. If x[jx]<>0 Then
  512. Begin
  513. temp := x[jx];
  514. ix := kx;
  515. For k:=kk Downto kk-(n-(j+1)) Do
  516. Begin
  517. x[ix] := x[ix]+temp*ap[k];
  518. dec(ix, incx)
  519. End;
  520. If nounit Then x[jx] := x[jx]*ap[kk-n+j]
  521. End;
  522. dec(jx, incx);
  523. dec(kk, n-j+1)
  524. End
  525. End
  526. End
  527. Else
  528. Begin
  529. If uplo='U' Then
  530. Begin
  531. kk := n*(n+1) Div 2;
  532. jx := kx+(n-1)*incx;
  533. For j:= n Downto 1 Do
  534. Begin
  535. temp := x[jx];
  536. ix := jx;
  537. If nounit Then temp := temp*ap[kk];
  538. For k:= kk-1 Downto kk-j+1 Do
  539. Begin
  540. dec(ix, incx);
  541. temp := temp+ap[k]*x[ix]
  542. End;
  543. x[jx] := temp;
  544. dec(jx, incx);
  545. dec(kk, j)
  546. End
  547. End
  548. Else
  549. Begin
  550. kk := 1;
  551. jx := kx;
  552. For j:=1 To n Do
  553. Begin
  554. temp := x[jx];
  555. ix := jx;
  556. If nounit Then temp := temp*ap[kk];
  557. For k:=kk+1 To kk+n-j Do
  558. Begin
  559. inc(ix, incx);
  560. temp := temp+ap[k]*x[ix]
  561. End;
  562. x[jx] := temp;
  563. inc(jx, incx);
  564. inc(kk, n-j+1)
  565. End
  566. End
  567. End
  568. End;
  569. Procedure roo002(uplo, trans, diag: char; n: ArbInt;
  570. Var ap1, x1: ArbFloat; incx: ArbInt );
  571. Var ap : arfloat1 absolute ap1;
  572. x : arfloat1 absolute x1;
  573. temp : ArbFloat;
  574. i, info, ix, j, jx, k, kk, kx: ArbInt;
  575. nounit: boolean;
  576. Begin
  577. info := 0;
  578. uplo := upcase(uplo);
  579. trans := upcase(trans);
  580. diag := upcase(diag);
  581. If n=0 Then exit;
  582. nounit := diag='N';
  583. If incx<=0 Then kx := 1-(n-1)*incx
  584. Else kx := 1;
  585. If trans='N' Then
  586. Begin
  587. If uplo='U' Then
  588. Begin
  589. kk := n*(n+1) Div 2;
  590. jx := kx+(n-1)*incx;
  591. For j:=n Downto 1 Do
  592. Begin
  593. If x[jx]<>0 Then
  594. Begin
  595. If nounit Then x[jx] := x[jx]/ap[kk];
  596. temp := x[jx];
  597. ix := jx;
  598. For k:=kk-1 Downto kk-j+1 Do
  599. Begin
  600. dec(ix, incx);
  601. x[ix] := x[ix]-temp*ap[k];
  602. End
  603. End;
  604. dec(jx, incx);
  605. dec(kk, j)
  606. End
  607. End
  608. Else
  609. Begin
  610. kk := 1;
  611. jx := kx;
  612. For j:=1 To n Do
  613. Begin
  614. If x[jx]<>0 Then
  615. Begin
  616. If nounit Then x[jx] := x[jx]/ap[kk];
  617. temp := x[jx];
  618. ix := jx;
  619. For k:= kk+1 To kk+n-j Do
  620. Begin
  621. inc(ix, incx);
  622. x[ix] := x[ix]-temp*ap[k]
  623. End;
  624. End;
  625. inc(jx, incx);
  626. inc(kk, n-j+1)
  627. End
  628. End
  629. End
  630. Else
  631. Begin
  632. If uplo='U' Then
  633. Begin
  634. kk := 1;
  635. jx := kx;
  636. For j:= 1 To n Do
  637. Begin
  638. temp := x[jx];
  639. ix := kx;
  640. For k:= kk To kk+j-2 Do
  641. Begin
  642. temp := temp-ap[k]*x[ix];
  643. inc(ix, incx);
  644. End;
  645. If nounit Then temp := temp/ap[kk+j-1];
  646. x[jx] := temp;
  647. inc(jx, incx);
  648. inc(kk, j)
  649. End
  650. End
  651. Else
  652. Begin
  653. kk := n*(n+1) Div 2;
  654. kx := kx+(n-1)*incx;
  655. jx := kx;
  656. For j:=n Downto 1 Do
  657. Begin
  658. temp := x[jx];
  659. ix := kx;
  660. For k:= kk Downto kk-(n-(j+1)) Do
  661. Begin
  662. temp := temp-ap[k]*x[ix];
  663. dec(ix, incx)
  664. End;
  665. If nounit Then temp := temp/ap[kk-n+j];
  666. x[jx] := temp;
  667. dec(jx, incx);
  668. dec(kk, n-j+1)
  669. End
  670. End
  671. End
  672. End;
  673. Procedure roo003( n: ArbInt; Var x1: ArbFloat; incx: ArbInt;
  674. Var scale, sumsq: ArbFloat );
  675. Var absxi : ArbFloat;
  676. i, ix : ArbInt;
  677. x : arfloat1 absolute x1;
  678. Begin
  679. ix := 1;
  680. If n>0 Then
  681. For i:=1 To n Do
  682. Begin
  683. If x[ix]<>0 Then
  684. Begin
  685. absxi := abs(x[ix]);
  686. If (scale<absxi) Then
  687. Begin
  688. sumsq := 1+sumsq*sqr(scale/absxi);
  689. scale := absxi
  690. End
  691. Else sumsq := sumsq + sqr(absxi/scale)
  692. End;
  693. inc(ix, incx)
  694. End
  695. End;
  696. Function norm2( n: ArbInt; Var x1: ArbFloat; incx: ArbInt): ArbFloat;
  697. Var scale, ssq : ArbFloat;
  698. sqt: ArbFloat;
  699. Begin
  700. If n<1 Then norm2 := 0
  701. Else
  702. If n=1 Then norm2 := abs(x1)
  703. Else
  704. Begin
  705. scale := 0;
  706. ssq := 1;
  707. roo003(n, x1, incx, scale, ssq );
  708. sqt := sqrt( ssq );
  709. If scale<(giant/sqt) Then norm2 := scale*sqt
  710. Else norm2 := giant
  711. End
  712. End;
  713. Procedure roo004(n: ArbInt; Var r1, diag1, qtb1: ArbFloat;
  714. delta: ArbFloat; Var x1: ArbFloat);
  715. Var
  716. r : arfloat1 absolute r1;
  717. diag : arfloat1 absolute diag1;
  718. qtb : arfloat1 absolute qtb1;
  719. x : arfloat1 absolute x1;
  720. wa1, wa2 : ^arfloat1;
  721. alpha, bnorm, gnorm, qnorm, sgnorm, temp: ArbFloat;
  722. i, j, jj, l : ArbInt;
  723. Begin
  724. getmem(wa1, n*sizeof(ArbFloat));
  725. getmem(wa2, n*sizeof(ArbFloat));
  726. jj := 1;
  727. For j:=1 To n Do
  728. Begin
  729. wa1^[j] := r[jj];
  730. If r[jj]=0 Then
  731. Begin
  732. temp := 0;
  733. l := j;
  734. For i:=1 To j-1 Do
  735. Begin
  736. If abs(r[l])>temp Then temp := abs(r[l]);
  737. inc(l, n-i)
  738. End;
  739. If temp=0 Then r[jj] := macheps
  740. Else r[jj] := macheps*temp
  741. End;
  742. inc(jj, n-j+1)
  743. End;
  744. move(qtb, x, n*sizeof(ArbFloat));
  745. roo002('l','t','n', n, r1, x1, 1);
  746. jj := 1;
  747. For j:=1 To n Do
  748. Begin
  749. r[jj] := wa1^[j];
  750. inc(jj, n - j + 1)
  751. End;
  752. For j:=1 To n Do
  753. wa2^[j] := diag[j]*x[j];
  754. qnorm := norm2(n, wa2^[1], 1);
  755. If qnorm>delta Then
  756. Begin
  757. move(qtb, wa1^, n*sizeof(ArbFloat));
  758. roo001('l','n','n', n, r1, wa1^[1], 1);
  759. For i:=1 To n Do
  760. wa1^[i] := wa1^[i]/diag[i];
  761. gnorm := norm2(n, wa1^[1], 1);
  762. sgnorm := 0;
  763. alpha := delta/qnorm;
  764. If gnorm<>0 Then
  765. Begin
  766. For j:=1 To n Do
  767. wa1^[j] := (wa1^[j]/gnorm)/diag[j];
  768. move(wa1^, wa2^, n*sizeof(ArbFloat));
  769. roo001('l','t','n',n,r1,wa2^[1],1);
  770. temp := norm2(n, wa2^[1],1);
  771. sgnorm := (gnorm/temp)/temp;
  772. alpha := 0;
  773. If sgnorm<delta Then
  774. Begin
  775. bnorm := norm2(n, qtb1, 1);
  776. temp := (bnorm/gnorm)*(bnorm/qnorm)*(sgnorm/delta);
  777. temp := temp-(delta/qnorm)*sqr(sgnorm/delta) +
  778. sqrt(sqr(temp-delta/qnorm) +
  779. (1-sqr(delta/qnorm))*(1-sqr(sgnorm/delta)));
  780. alpha := ((delta/qnorm)*(1-sqr(sgnorm/delta)))/temp
  781. End
  782. End;
  783. If sgnorm<delta Then temp := (1-alpha)*sgnorm
  784. Else temp := (1-alpha)*delta;
  785. For j:=1 To n Do
  786. x[j] := temp*wa1^[j] + alpha*x[j]
  787. End;
  788. freemem(wa2, n*sizeof(ArbFloat));
  789. freemem(wa1, n*sizeof(ArbFloat));
  790. End;
  791. Procedure roo005(fcn: roofnrfunc; n: ArbInt; Var x1, fvec1, fjac1: ArbFloat;
  792. ldfjac: ArbInt; Var iflag: ArbInt; ml, mu: ArbInt;
  793. epsfcn: ArbFloat; Var wa1, wa2: arfloat1);
  794. Var eps, h, temp: ArbFloat;
  795. i, j, k, msum: ArbInt;
  796. x : arfloat1 absolute x1;
  797. fvec : arfloat1 absolute fvec1;
  798. fjac : arfloat1 absolute fjac1;
  799. deff : boolean;
  800. Begin
  801. If epsfcn>macheps Then eps := sqrt(epsfcn)
  802. Else eps := sqrt(macheps);
  803. msum := ml+mu+1;
  804. If msum>=n Then
  805. Begin
  806. For j:=1 To n Do
  807. Begin
  808. temp := x[j];
  809. h := eps*abs(temp);
  810. If h=0 Then h := eps;
  811. x[j] := temp+h;
  812. deff := true;
  813. fcn(x1, wa1[1], deff);
  814. If Not deff Then iflag := -1;
  815. If iflag<0 Then exit;
  816. x[j] := temp;
  817. For i:= 1 To n Do
  818. fjac[j+(i-1)*ldfjac] := (wa1[i]-fvec[i])/h
  819. End
  820. End
  821. Else
  822. Begin
  823. For k:=1 To msum Do
  824. Begin
  825. j := k;
  826. while j <= n Do
  827. Begin
  828. wa2[j] := x[j];
  829. h := eps*abs(wa2[j]);
  830. If h=0 Then h := eps;
  831. x[j] := wa2[j]+h;
  832. inc(j, msum)
  833. End;
  834. deff := true;
  835. fcn(x1, wa1[1], deff);
  836. If Not deff Then iflag := -1;
  837. If iflag<0 Then exit;
  838. j := k;
  839. while j<= n Do
  840. Begin
  841. x[j] := wa2[j];
  842. h := eps*abs(wa2[j]);
  843. If h=0 Then h := eps;
  844. For i:=1 To n Do
  845. Begin
  846. fjac[j+(i-1)*ldfjac] := 0;
  847. If (i>=(j-mu)) And (i<=(j+ml))
  848. Then fjac[j+(i-1)*ldfjac] := (wa1[i]-fvec[i])/h
  849. End;
  850. inc(j, msum)
  851. End
  852. End
  853. End
  854. End;
  855. Procedure roo006(trans: char; m, n: ArbInt; alpha: ArbFloat; Var a1: ArbFloat;
  856. lda: ArbInt; Var x1: ArbFloat; incx : ArbInt; beta: ArbFloat;
  857. Var y1: ArbFloat; incy : ArbInt);
  858. Var temp : ArbFloat;
  859. i, info, ix, iy, j, jx, jy, kx, ky, lenx, leny: ArbInt;
  860. x : arfloat1 absolute x1;
  861. y : arfloat1 absolute y1;
  862. a : arfloat1 absolute a1;
  863. Begin
  864. info := 0;
  865. trans := upcase(trans);
  866. If (m=0) Or (n=0) Or ((alpha=0) And (beta=1)) Then exit;
  867. If trans='N' Then
  868. Begin
  869. lenx := n;
  870. leny := m
  871. End
  872. Else
  873. Begin
  874. lenx := m;
  875. leny := n
  876. End;
  877. If incx>0 Then kx := 1
  878. Else kx := 1-(lenx-1)*incx;
  879. If incy>0 Then ky := 1
  880. Else ky := 1-(leny-1)*incy;
  881. If (beta<>1) Then
  882. Begin
  883. iy := ky;
  884. If beta=0 Then
  885. For i:=1 To leny Do
  886. Begin
  887. y[iy] := 0;
  888. inc(iy, incy)
  889. End
  890. Else
  891. For i:=1 To leny Do
  892. Begin
  893. y[iy] := beta*y[iy];
  894. inc(iy, incy)
  895. End;
  896. End;
  897. If alpha=0 Then exit;
  898. If trans='N' Then
  899. Begin
  900. jx := kx;
  901. For j:=1 To n Do
  902. Begin
  903. If x[jx]<>0 Then
  904. Begin
  905. temp := alpha*x[jx];
  906. iy := ky;
  907. For i:=1 To m Do
  908. Begin
  909. y[iy] := y[iy]+temp*a[j+(i-1)*lda];
  910. inc(iy, incy)
  911. End
  912. End;
  913. inc(jx, incx)
  914. End
  915. End
  916. Else
  917. Begin
  918. jy := ky;
  919. For j:=1 To n Do
  920. Begin
  921. temp := 0;
  922. ix := kx;
  923. For i:=1 To m Do
  924. Begin
  925. temp := temp+a[j+(i-1)*lda]*x[ix];
  926. inc(ix, incx)
  927. End;
  928. y[jy] := y[jy]+alpha*temp;
  929. inc(jy, incy)
  930. End
  931. End
  932. End;
  933. Procedure roo007(m, n: ArbInt; alpha: ArbFloat; Var x1: ArbFloat; incx: ArbInt;
  934. Var y1: ArbFloat; incy: ArbInt; Var a1: ArbFloat; lda: ArbInt);
  935. Var temp: ArbFloat;
  936. i, info, ix, j, jy, kx: ArbInt;
  937. x : arfloat1 absolute x1;
  938. y : arfloat1 absolute y1;
  939. a : arfloat1 absolute a1;
  940. Begin
  941. info := 0;
  942. If (m=0) Or (n=0) Or (alpha=0) Then exit;
  943. If incy>0 Then jy := 1
  944. Else jy := 1-(n-1)*incy;
  945. If incx>0 Then kx := 1
  946. Else kx := 1-(m-1)*incx;
  947. For j:=1 To n Do
  948. Begin
  949. If y[jy]<>0 Then
  950. Begin
  951. temp := alpha*y[jy];
  952. ix := kx;
  953. For i:=1 To m Do
  954. Begin
  955. a[j +(i-1)*lda] := a[j + (i-1)*lda] + x[ix]*temp;
  956. inc(ix, incx)
  957. End
  958. End;
  959. inc(jy, incy)
  960. End
  961. End;
  962. Procedure roo008(n: ArbInt; Var q1: ArbFloat; ldq: ArbInt; Var wa: arfloat1);
  963. Var q: arfloat1 absolute q1;
  964. i, j, k: ArbInt;
  965. Begin
  966. For j:=2 To n Do
  967. For i:=1 To j-1 Do
  968. q[j+(i-1)*ldq] := 0;
  969. For k:=n Downto 1 Do
  970. Begin
  971. If (q[k+(k-1)*ldq]<>0) And (k<>n) Then
  972. Begin
  973. roo006('t', n-k+1, n-k, 1, q[k+1+(k-1)*ldq], ldq,
  974. q[k +(k-1)*ldq], ldq, 0, wa[k+1], 1);
  975. roo007(n-k+1, n-k, -1/q[k+(k-1)*ldq], q[k+(k-1)*ldq], ldq,
  976. wa[k+1], 1, q[k+1+(k-1)*ldq], ldq)
  977. End;
  978. For i:=k + 1 To n Do
  979. q[k+(i-1)*ldq] := -q[k+(i-1)*ldq];
  980. q[k+(k-1)*ldq] := 1-q[k+(k-1)*ldq]
  981. End;
  982. End;
  983. Procedure roo009(n: ArbInt; Var a1: ArbFloat; lda: ArbInt;
  984. Var rdiag1, acnorm1: ArbFloat);
  985. Var a : arfloat1 absolute a1;
  986. rdiag : arfloat1 absolute rdiag1;
  987. acnorm : arfloat1 absolute acnorm1;
  988. ajnorm : ArbFloat;
  989. i, j : ArbInt;
  990. Begin
  991. For j:=1 To n Do
  992. acnorm[j] := norm2(n, a[j], lda);
  993. For j:=1 To n Do
  994. Begin
  995. ajnorm := norm2(n-j+1, a[j+(j-1)*lda], lda);
  996. If ajnorm<>0 Then
  997. Begin
  998. If a[j+(j-1)*lda]<0 Then ajnorm := -ajnorm;
  999. For i:=j To n Do
  1000. a[j+(i-1)*lda] := a[j+(i-1)*lda]/ajnorm;
  1001. a[j+(j-1)*lda] := a[j+(j-1)*lda]+1;
  1002. If j<>n Then
  1003. Begin
  1004. roo006('t', n-j+1, n-j, 1, a[j+1+(j-1)*lda], lda,
  1005. a[j+(j-1)*lda], lda, 0, rdiag[j+1], 1);
  1006. roo007(n-j+1, n-j, -1/a[j+(j-1)*lda], a[j+(j-1)*lda], lda,
  1007. rdiag[j+1], 1, a[j+1+(j-1)*lda], lda)
  1008. End
  1009. End;
  1010. rdiag[j] := -ajnorm
  1011. End
  1012. End;
  1013. Procedure roo010(n: ArbInt; Var x1: ArbFloat; incx: ArbInt;
  1014. Var y1: ArbFloat; incy: ArbInt; c, s:ArbFloat );
  1015. Var temp1: ArbFloat;
  1016. x : arfloat1 absolute x1;
  1017. y : arfloat1 absolute y1;
  1018. i, ix, iy: ArbInt;
  1019. Begin
  1020. If incy>=0 Then iy := 1
  1021. Else iy := 1-(n-1)*incy;
  1022. If incx>=0 Then ix := 1
  1023. Else ix := 1-(n-1)*incx;
  1024. For i:=1 To n Do
  1025. Begin
  1026. temp1 := x[ix];
  1027. x[ix] := s*y[iy]+c*temp1;
  1028. y[iy] := c*y[iy]-s*temp1;
  1029. inc(ix, incx);
  1030. inc(iy, incy)
  1031. End
  1032. End;
  1033. Procedure roo011(m, n: ArbInt; Var a1: ArbFloat; lda: ArbInt; Var v1, w1: ArbFloat);
  1034. Var a: arfloat1 absolute a1;
  1035. v: arfloat1 absolute v1;
  1036. w: arfloat1 absolute w1;
  1037. sine, cosine: ArbFloat;
  1038. j, nm1, nmj: ArbInt;
  1039. Begin
  1040. nm1 := n-1;
  1041. For nmj:=1 To nm1 Do
  1042. Begin
  1043. j := n-nmj;
  1044. If (abs(v[j])>1) Then
  1045. Begin
  1046. cosine := 1/v[j];
  1047. sine := sqrt(1-sqr(cosine))
  1048. End
  1049. Else
  1050. Begin
  1051. sine := v[j];
  1052. cosine := sqrt(1-sqr(sine))
  1053. End;
  1054. roo010(m, a[n], lda, a[j], lda, cosine, sine)
  1055. End;
  1056. For j:=1 To nm1 Do
  1057. Begin
  1058. If (abs(w[j])>1) Then
  1059. Begin
  1060. cosine := 1/w[j];
  1061. sine := sqrt(1-sqr(cosine))
  1062. End
  1063. Else
  1064. Begin
  1065. sine := w[j];
  1066. cosine := sqrt(1-sqr(sine))
  1067. End;
  1068. roo010(m, a[j], lda, a[n], lda, cosine, sine)
  1069. End
  1070. End;
  1071. Procedure roo012(m, n: ArbInt; Var s1: ArbFloat; ls: ArbInt;
  1072. Var u1, v1, w1: ArbFloat; Var sing: boolean);
  1073. Const one = 1.0;
  1074. p5 = 0.5;
  1075. p25 = 0.25;
  1076. zero = 0.0;
  1077. Var cosine, cotan, sine, tangnt, tau: ArbFloat;
  1078. i, j, jj, l, nm1, nmj: ArbInt;
  1079. s : arfloat1 absolute s1;
  1080. u : arfloat1 absolute u1;
  1081. v : arfloat1 absolute v1;
  1082. w : arfloat1 absolute w1;
  1083. Begin
  1084. jj := (n*(2*m-n+1)) Div 2 - (m-n);
  1085. If m>=n Then move(s[jj], w[n], (m-n+1)*sizeof(ArbFloat));
  1086. nm1 := n-1;
  1087. For nmj:=1 To nm1 Do
  1088. Begin
  1089. j := n-nmj;
  1090. jj := jj-(m-j+1);
  1091. w[j] := zero;
  1092. If (v[j]<>zero) Then
  1093. Begin
  1094. If (abs(v[n])<abs(v[j])) Then
  1095. Begin
  1096. cotan := v[n]/v[j];
  1097. sine := p5/sqrt(p25+p25*sqr(cotan));
  1098. cosine := sine*cotan;
  1099. If (abs(cosine)*giant)>one
  1100. Then tau := one/cosine
  1101. Else tau := one
  1102. End
  1103. Else
  1104. Begin
  1105. tangnt := v[j]/v[n];
  1106. cosine := p5/sqrt(p25+p25*sqr(tangnt));
  1107. sine := cosine*tangnt;
  1108. tau := sine;
  1109. End;
  1110. v[n] := sine*v[j]+cosine*v[n];
  1111. v[j] := tau;
  1112. roo010(m-j+1, w[j], 1, s[jj], 1, cosine, sine)
  1113. End
  1114. End;
  1115. For i:=1 To m Do
  1116. w[i] := w[i]+v[n]*u[i];
  1117. sing := false;
  1118. For j:=1 To nm1 Do
  1119. Begin
  1120. If w[j]<>zero Then
  1121. Begin
  1122. If abs(s[jj])<abs(w[j]) Then
  1123. Begin
  1124. cotan := s[jj]/w[j];
  1125. sine := p5/sqrt(p25+p25*sqr(cotan));
  1126. cosine := sine*cotan;
  1127. If (abs(cosine)*giant)>one Then tau := one/cosine
  1128. Else tau := one
  1129. End
  1130. Else
  1131. Begin
  1132. tangnt := w[j]/s[jj];
  1133. cosine := p5/sqrt(p25+p25*sqr(tangnt));
  1134. sine := cosine*tangnt;
  1135. tau := sine
  1136. End;
  1137. roo010(m-j+1, s[jj], 1, w[j], 1, cosine, sine);
  1138. w[j] := tau
  1139. End;
  1140. If (s[jj]=zero) Then sing := true;
  1141. inc(jj, m-j+1)
  1142. End;
  1143. If m>=n Then move(w[n], s[jj], (m-n+1)*sizeof(ArbFloat));
  1144. If s[jj]=zero Then sing := true
  1145. End;
  1146. Procedure roo013(fcn: roofnrfunc; n: ArbInt; Var x1, fvec1: ArbFloat;
  1147. xtol: ArbFloat; maxfev, ml, mu: ArbInt; epsfcn: ArbFloat;
  1148. Var diag1: ArbFloat; factor: ArbFloat; Var info: ArbInt;
  1149. Var fjac1: ArbFloat; ldfjac: ArbInt;
  1150. Var r1: ArbFloat; lr: ArbInt; Var qtf1: ArbFloat);
  1151. Const p1 = 0.1;
  1152. p5 = 0.5;
  1153. p001 = 0.001;
  1154. p0001 = 0.0001;
  1155. Var diag : arfloat1 absolute diag1;
  1156. fjac : arfloat1 absolute fjac1;
  1157. fvec : arfloat1 absolute fvec1;
  1158. qtf : arfloat1 absolute qtf1;
  1159. r : arfloat1 absolute r1;
  1160. wa1, wa2, wa3, wa4: ^arfloat1;
  1161. x : arfloat1 absolute x1;
  1162. actred, delta, fnorm, fnorm1, pnorm,
  1163. prered, ratio, sum, temp, xnorm : ArbFloat;
  1164. i, iflag, iter, j, jm1, l, msum, ncfail, ncsuc, nfev,
  1165. nslow1, nslow2, ns : ArbInt;
  1166. jeval, sing, deff: boolean;
  1167. Begin
  1168. info := 1;
  1169. iflag := 0;
  1170. nfev := 0;
  1171. ns := n*sizeof(ArbFloat);
  1172. For j:=1 To n Do
  1173. If diag[j]<=0 Then exit;
  1174. iflag := 1;
  1175. deff := true;
  1176. fcn(x1, fvec1, deff);
  1177. If Not deff Then iflag := -1;
  1178. nfev := 1;
  1179. If iflag<0 Then
  1180. Begin
  1181. info := iflag;
  1182. exit
  1183. End;
  1184. fnorm := norm2(n, fvec1, 1);
  1185. msum := ml+mu+1;
  1186. If msum>n Then msum := n;
  1187. getmem(wa1, ns);
  1188. getmem(wa2, ns);
  1189. getmem(wa3, ns);
  1190. getmem(wa4, ns);
  1191. iter := 1;
  1192. ncsuc := 0;
  1193. ncfail := 0;
  1194. nslow1 := 0;
  1195. nslow2 := 0;
  1196. while (info=1) and (iflag>=0) Do
  1197. Begin
  1198. jeval := true;
  1199. iflag := 2;
  1200. roo005(fcn, n, x1, fvec1, fjac1, ldfjac, iflag, ml, mu, epsfcn,
  1201. wa1^, wa2^);
  1202. inc(nfev, msum);
  1203. If iflag>=0 Then
  1204. Begin
  1205. roo009(n, fjac1, ldfjac, wa1^[1], wa2^[1]);
  1206. If iter=1 Then
  1207. Begin
  1208. For j:=1 To n Do
  1209. wa3^[j] := diag[j]*x[j];
  1210. xnorm := norm2(n, wa3^[1], 1);
  1211. delta := factor*xnorm;
  1212. If delta=0 Then delta := factor;
  1213. End;
  1214. For i:=1 To n Do
  1215. qtf[i] := fvec[i];
  1216. For j:=1 To n Do
  1217. If fjac[j+(j-1)*ldfjac]<>0 Then
  1218. Begin
  1219. sum := 0;
  1220. For i:=j To n Do
  1221. sum := sum+fjac[j+(i-1)*ldfjac]*qtf[i];
  1222. temp := -sum/fjac[j+(j-1)*ldfjac];
  1223. For i:=j To n Do
  1224. qtf[i] := qtf[i]+fjac[j+(i-1)*ldfjac]*temp
  1225. End;
  1226. sing := false;
  1227. For j:=1 To n Do
  1228. Begin
  1229. l := j;
  1230. jm1 := j-1;
  1231. For i:=1 To jm1 Do
  1232. Begin
  1233. r[l] := fjac[j+(i-1)*ldfjac];
  1234. inc(l, n-i)
  1235. End;
  1236. r[l] := wa1^[j];
  1237. If wa1^[j]=0 Then sing := true
  1238. End;
  1239. roo008(n, fjac1, ldfjac, wa1^);
  1240. Repeat
  1241. roo004(n, r1, diag1, qtf1, delta, wa1^[1]);
  1242. For j:=1 To n Do
  1243. Begin
  1244. wa1^[j] := -wa1^[j];
  1245. wa2^[j] := x[j]+wa1^[j];
  1246. wa3^[j] := diag[j]*wa1^[j]
  1247. End;
  1248. pnorm := norm2(n, wa3^[1], 1);
  1249. If iter=1 Then If pnorm<delta Then delta := pnorm;
  1250. iflag := 1;
  1251. deff := true;
  1252. fcn(wa2^[1], wa4^[1], deff);
  1253. If Not deff Then iflag := -1;
  1254. inc(nfev);
  1255. If iflag>0 Then
  1256. Begin
  1257. fnorm1 := norm2(n, wa4^[1], 1);
  1258. If fnorm1<fnorm Then actred := 1-sqr(fnorm1/fnorm)
  1259. Else actred := -1;
  1260. move(wa1^, wa3^, n*sizeof(ArbFloat));
  1261. roo001('l','t','n', n, r1, wa3^[1], 1);
  1262. For i:=1 To n Do
  1263. wa3^[i] := wa3^[i] + qtf[i];
  1264. temp := norm2(n, wa3^[1], 1);
  1265. If temp<fnorm
  1266. Then prered := 1 - sqr(temp/fnorm)
  1267. Else prered := 1;
  1268. If prered>0 Then ratio := actred/prered
  1269. Else ratio := 0;
  1270. If ratio<p1 Then
  1271. Begin
  1272. ncsuc := 0;
  1273. inc(ncfail);
  1274. delta := p5*delta
  1275. End
  1276. Else
  1277. Begin
  1278. ncfail := 0;
  1279. inc(ncsuc);
  1280. If (ratio>=p5) Or (ncsuc>1)
  1281. Then If delta<pnorm/p5 Then delta := pnorm/p5;
  1282. If abs(ratio-1)<=p1 Then delta := pnorm/p5
  1283. End;
  1284. If ratio>=p0001 Then
  1285. Begin
  1286. For j:=1 To n Do
  1287. Begin
  1288. x[j] := wa2^[j];
  1289. wa2^[j] := diag[j]*x[j];
  1290. fvec[j] := wa4^[j]
  1291. End;
  1292. xnorm := norm2(n, wa2^[1], 1);
  1293. fnorm := fnorm1;
  1294. inc(iter)
  1295. End;
  1296. inc(nslow1);
  1297. If actred>=p001 Then nslow1 := 0;
  1298. If jeval Then inc(nslow2);
  1299. If actred>=p1 Then nslow2 := 0;
  1300. If (delta<=xtol*xnorm) Or
  1301. (fnorm=0) Or (pnorm=0) Then info := 0
  1302. Else If nfev>=maxfev Then info := 2
  1303. Else If delta<=macheps*xnorm Then info := 3
  1304. Else If nslow2=5 Then info := 4
  1305. Else If nslow1=10 Then info := 5;
  1306. If (info=1) And (ncfail<>2) Then
  1307. Begin
  1308. roo006('t', n, n, 1, fjac1, ldfjac, wa4^[1], 1, 0,
  1309. wa2^[1], 1);
  1310. If ratio>=p0001 Then move(wa2^, qtf, ns);
  1311. For j:=1 To n Do
  1312. Begin
  1313. wa2^[j] := (wa2^[j]-wa3^[j])/pnorm;
  1314. wa1^[j] := diag[j]*((diag[j]*wa1^[j])/pnorm)
  1315. End;
  1316. roo012(n, n, r1, lr, wa1^[1], wa2^[1], wa3^[1], sing);
  1317. roo011(n, n, fjac1, ldfjac, wa2^[1], wa3^[1]);
  1318. roo011(1, n, qtf1, 1, wa2^[1], wa3^[1]);
  1319. jeval := false
  1320. End
  1321. End
  1322. Until (iflag<0) Or (ncfail=2) Or (info<>1)
  1323. End
  1324. End;
  1325. freemem(wa4, ns);
  1326. freemem(wa3, ns);
  1327. freemem(wa2, ns);
  1328. freemem(wa1, ns);
  1329. If iflag<0 Then info := iflag;
  1330. End;
  1331. Procedure roofnr(f: roofnrfunc; n: ArbInt; Var x, residu: ArbFloat; re: ArbFloat;
  1332. Var term: ArbInt);
  1333. Var j, lr, ns : ArbInt;
  1334. wa1, wa2, wa3, wa4, fx : ^arfloat1;
  1335. Begin
  1336. ns := n*sizeof(ArbFloat);
  1337. If n<=0 Then term := 3
  1338. Else
  1339. Begin
  1340. If re<0 Then term := 3
  1341. Else
  1342. Begin
  1343. lr := (n*(n+1)) Div 2;
  1344. getmem(wa1, ns);
  1345. getmem(wa2, ns);
  1346. getmem(wa3, lr*sizeof(ArbFloat));
  1347. getmem(wa4, n*ns);
  1348. getmem(fx, ns);
  1349. For j:=1 To n Do
  1350. wa1^[j] := 1;
  1351. roo013(f, n, x, fx^[1], re, 200*(n+1), n-1, n-1, 0, wa1^[1],
  1352. 100.0, term, wa4^[1], n, wa3^[1], lr, wa2^[1]);
  1353. residu := Norm2(n, fx^[1], 1);
  1354. freemem(fx, ns);
  1355. freemem(wa4, n*ns);
  1356. freemem(wa3, lr*sizeof(ArbFloat));
  1357. freemem(wa2, ns);
  1358. freemem(wa1, ns);
  1359. If term<0 Then term := 6
  1360. Else
  1361. Case term Of
  1362. 0: term := 1;
  1363. 2: term := 4;
  1364. 3: term := 2;
  1365. 4, 5: term := 5;
  1366. End
  1367. End
  1368. End
  1369. End;
  1370. End.