roo.pas 39 KB

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