int.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  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. Integration. This routine is fit for smooth "integrand" so no singularities,
  10. sharp edges, or quickly oscillating behaviour.
  11. See the file COPYING.FPC, included in this distribution,
  12. for details about the copyright.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. **********************************************************************}
  17. Unit int;
  18. {$I DIRECT.INC}
  19. interface
  20. uses typ;
  21. Var
  22. limit : ArbInt;
  23. epsrel : ArbFloat;
  24. {calc int(x,a,b,f(x)) for a function with a nice behaviour in the
  25. interval [A,B]}
  26. Procedure int1fr(f: rfunc1r; a, b, ae: ArbFloat; Var integral, err: ArbFloat;
  27. Var term: ArbInt);
  28. implementation
  29. Function amin1(x, y: ArbFloat): ArbFloat;
  30. Begin
  31. If x<y Then amin1 := x
  32. Else amin1 := y
  33. End;
  34. Function amax1(x, y: ArbFloat): ArbFloat;
  35. Begin
  36. If x>y Then amax1 := x
  37. Else amax1 := y
  38. End;
  39. Procedure qk21(f: rfunc1r; a, b: ArbFloat;
  40. Var result, abserr, resabs, resasc: ArbFloat);
  41. Const
  42. xgk: array[1..11] Of ArbFloat =
  43. ( 0.9956571630258081, 0.9739065285171717,
  44. 0.9301574913557082, 0.8650633666889845,
  45. 0.7808177265864169, 0.6794095682990244,
  46. 0.5627571346686047, 0.4333953941292472,
  47. 0.2943928627014602, 0.1488743389816312, 0);
  48. wgk: array[1..11] Of ArbFloat =
  49. ( 0.1169463886737187e-1, 0.3255816230796473e-1,
  50. 0.5475589657435200e-1, 0.7503967481091995e-1,
  51. 0.9312545458369761e-1, 0.1093871588022976,
  52. 0.1234919762620659, 0.1347092173114733,
  53. 0.1427759385770601, 0.1477391049013385,
  54. 0.1494455540029169);
  55. wg: array[1..5] Of ArbFloat =
  56. ( 0.6667134430868814e-1, 0.1494513491505806,
  57. 0.2190863625159820, 0.2692667193099964,
  58. 0.2955242247147529);
  59. Var absc, centr, dhlgth, fc, fsum, fval1, fval2,
  60. hlgth, resg, resk, reskh: ArbFloat;
  61. j, jtw, jtwm1: ArbInt;
  62. fv1, fv2: ^arfloat1;
  63. Begin
  64. getmem(fv1, 10*sizeof(ArbFloat));
  65. getmem(fv2, 10*sizeof(ArbFloat));
  66. centr := (a+b)/2;
  67. hlgth := (b-a)/2;
  68. dhlgth := abs(hlgth);
  69. resg := 0;
  70. fc := f(centr);
  71. resk := wgk[11]*fc;
  72. resabs := abs(resk);
  73. For j:=1 To 5 Do
  74. Begin
  75. jtw := 2*j;
  76. absc := hlgth*xgk[jtw];
  77. fval1 := f(centr-absc);
  78. fval2 := f(centr+absc);
  79. fv1^[jtw] := fval1;
  80. fv2^[jtw] := fval2;
  81. fsum := fval1+fval2;
  82. resg := resg+wg[j]*fsum;
  83. resk := resk+wgk[jtw]*fsum;
  84. resabs := resabs+wgk[jtw]*(abs(fval1)+abs(fval2))
  85. End;
  86. For j:=1 To 5 Do
  87. Begin
  88. jtwm1 := 2*j-1;
  89. absc := hlgth*xgk[jtwm1];
  90. fval1 := f(centr-absc);
  91. fval2 := f(centr+absc);
  92. fv1^[jtwm1] := fval1;
  93. fv2^[jtwm1] := fval2;
  94. fsum := fval1+fval2;
  95. resk := resk+wgk[jtwm1]*fsum;
  96. resabs := resabs+wgk[jtwm1]*(abs(fval1)+abs(fval2))
  97. End;
  98. reskh := resk/2;
  99. resasc := wgk[11]*abs(fc-reskh);
  100. For j:=1 To 10 Do
  101. resasc := resasc+wgk[j]*(abs(fv1^[j]-reskh)+abs(fv2^[j]-reskh));
  102. result := resk*hlgth;
  103. resabs := resabs*dhlgth;
  104. resasc := resasc*dhlgth;
  105. abserr := abs((resk-resg)*hlgth);
  106. If (resasc <> 0) And (abserr <> 0)
  107. Then abserr := resasc*amin1(1,exp(1.5*ln(200*abserr/resasc)));
  108. If resabs > midget/(50*macheps)
  109. Then abserr := amax1((50*macheps)*resabs, abserr);
  110. freemem(fv1, 10*sizeof(ArbFloat));
  111. freemem(fv2, 10*sizeof(ArbFloat));
  112. End;
  113. Procedure qpsrt(limit: ArbInt;
  114. Var last, maxerr: ArbInt;
  115. Var ermax, elist1: ArbFloat;
  116. Var iord1, nrmax: ArbInt);
  117. Var errmax, errmin: ArbFloat;
  118. i, ibeg, ido, isucc,
  119. j, jbnd, jupbn, k : ArbInt;
  120. continue : boolean;
  121. elist : arfloat1 absolute elist1;
  122. iord : arint1 absolute iord1;
  123. Begin
  124. If (last<=2)
  125. Then
  126. Begin
  127. iord[1] := 1;
  128. iord[2] := 2;
  129. maxerr := iord[nrmax];
  130. ermax := elist[maxerr];
  131. exit
  132. End;
  133. errmax := elist[maxerr];
  134. ido := nrmax-1;
  135. i := 0;
  136. If ido>0 Then
  137. Repeat
  138. Inc(i);
  139. isucc := iord[nrmax-1];
  140. If errmax>elist[isucc]
  141. Then
  142. Begin
  143. iord[nrmax] := isucc;
  144. nrmax := nrmax-1
  145. End
  146. Else i := ido
  147. Until (i=ido);
  148. jupbn := last;
  149. If (last>(limit Div 2+2)) Then jupbn := limit+3-last;
  150. errmin := elist[last];
  151. jbnd := jupbn-1;
  152. ibeg := nrmax+1;
  153. If (ibeg>jbnd)
  154. Then
  155. Begin
  156. iord[jbnd] := maxerr;
  157. iord[jupbn] := last;
  158. maxerr := iord[nrmax];
  159. ermax := elist[maxerr];
  160. exit
  161. End;
  162. i := ibeg-1;
  163. continue := true;
  164. while (i<jbnd) and continue Do
  165. Begin
  166. Inc(i);
  167. isucc := iord[i];
  168. If (errmax<elist[isucc])
  169. Then iord[i-1] := isucc
  170. Else continue := false
  171. End;
  172. If continue
  173. Then
  174. Begin
  175. iord[jbnd] := maxerr;
  176. iord[jupbn] := last
  177. End
  178. Else
  179. Begin
  180. iord[i-1] := maxerr;
  181. k := jbnd;
  182. continue := true;
  183. j := i-1;
  184. while (j<jbnd) and continue Do
  185. Begin
  186. Inc(j);
  187. isucc := iord[k];
  188. If errmin<elist[isucc]
  189. Then continue := false
  190. Else
  191. Begin
  192. iord[k+1] := isucc;
  193. Dec(k)
  194. End
  195. End;
  196. If continue Then iord[i] := last
  197. Else iord[k+1] := last
  198. End;
  199. maxerr := iord[nrmax];
  200. ermax := elist[maxerr]
  201. End;
  202. Type
  203. stock = array[1..52] Of ArbFloat;
  204. hulpar = array[1..3] Of ArbFloat;
  205. Procedure qelg(Var n: ArbInt;
  206. Var epstab: stock;
  207. Var result, abserr: ArbFloat;
  208. Var res3la: hulpar;
  209. Var nres: ArbInt);
  210. Var
  211. delta1, delta2, delta3,
  212. epsinf, error, err1, err2, err3,
  213. e0, e1, e2, e3, e0abs, e1abs, e2abs, e3abs,
  214. res, ss, tol1, tol2, tol3: ArbFloat;
  215. i, ib, ib2, k1, k2, k3,
  216. limexp, num, newelm: ArbInt;
  217. continue: boolean;
  218. Begin
  219. Inc(nres);
  220. abserr := giant;
  221. result := epstab[n];
  222. If (n<3) Then exit;
  223. limexp := 50;
  224. epstab[n+2] := epstab[n];
  225. epstab[n] := giant;
  226. num := n;
  227. k1 := n;
  228. continue := true;
  229. i := 1;
  230. newelm := (n-1) Div 2;
  231. while (i<=newelm) and continue Do
  232. Begin
  233. k2 := k1-1;
  234. k3 := k1-2;
  235. res := epstab[k1+2];
  236. e0 := epstab[k3];
  237. e1 := epstab[k2];
  238. e2 := res;
  239. e0abs := abs(e0);
  240. e1abs := abs(e1);
  241. e2abs := abs(e2);
  242. delta2 := e2-e1;
  243. err2 := abs(delta2);
  244. If e1abs>e2abs
  245. Then tol2 := e1abs*macheps
  246. Else tol2 := e2abs*macheps;
  247. delta3 := e1-e0;
  248. err3 := abs(delta3);
  249. If e1abs>e0abs
  250. Then tol3 := e1abs*macheps
  251. Else tol3 := e0abs*macheps;
  252. If (err2<=tol2) And (err3<=tol3)
  253. Then
  254. Begin
  255. result := res;
  256. abserr := err2+err3;
  257. If abserr<5*macheps*abs(result)
  258. Then abserr := 5*macheps*abs(result);
  259. exit
  260. End;
  261. e3 := epstab[k1];
  262. epstab[k1] := e1;
  263. delta1 := e1-e3;
  264. err1 := abs(delta1);
  265. e3abs := abs(e3);
  266. If e1abs<e3abs
  267. Then tol1 := e3abs*macheps
  268. Else tol1 := e1abs*macheps;
  269. continue := false;
  270. If (err1<=tol1) Or (err2<=tol2) Or (err3<=tol3)
  271. Then n := 2*i-1
  272. Else
  273. Begin
  274. ss := 1/delta1 + 1/delta2 - 1/delta3;
  275. epsinf := abs(ss*e1);
  276. If (epsinf>1e-4)
  277. Then
  278. Begin
  279. continue := true;
  280. res := e1+1/ss;
  281. epstab[k1] := res;
  282. k1 := k1-2;
  283. error := err2+abs(res-e2)+err3;
  284. If (error<=abserr)
  285. Then
  286. Begin
  287. abserr := error;
  288. result := res
  289. End
  290. End
  291. Else n := 2*i-1
  292. End;
  293. Inc(i)
  294. End;
  295. If n=limexp Then n := 2*(limexp Div 2)-1;
  296. If Odd(Num) Then ib := 1
  297. Else ib := 2;
  298. For i:=1 To newelm+1 Do
  299. Begin
  300. ib2 := ib+2;
  301. epstab[ib] := epstab[ib2];
  302. ib := ib2
  303. End;
  304. Move(epstab[num-n+1], epstab[1], n*SizeOf(ArbFloat));
  305. If (nres<4)
  306. Then
  307. Begin
  308. res3la[nres] := result;
  309. abserr := giant
  310. End
  311. Else
  312. Begin
  313. abserr := abs(result-res3la[3]) +
  314. abs(result-res3la[2]) +
  315. abs(result-res3la[1]);
  316. res3la[1] := res3la[2];
  317. res3la[2] := res3la[3];
  318. res3la[3] := result;
  319. If abserr<5*macheps*abs(result)
  320. Then abserr := 5*macheps*abs(result)
  321. End
  322. End;
  323. Procedure qagse(f: rfunc1r; a, b, epsabs, epsrel: ArbFloat;
  324. limit: ArbInt; Var result, abserr: ArbFloat;
  325. Var neval, ier, last: ArbInt);
  326. Var abseps, area, area1, area12, area2, a1, a2, b1, b2, correc, defabs,
  327. defab1, defab2, dres, erlarg, erlast, errbnd, errmax,
  328. error1, error2, erro12, errsum, ertest, resabs, reseps, small: ArbFloat;
  329. id, ierro, iroff1, iroff2, iroff3, jupbnd, k, ksgn,
  330. ktmin, maxerr, nres, nrmax, numrl2, sr, lsr: ArbInt;
  331. extrap, noext, go_on, jump, smallers, p0, p1, p2, p3: boolean;
  332. alist, blist, elist, rlist: ^arfloat1;
  333. res3la: hulpar;
  334. rlist2: stock;
  335. iord: ^arint1;
  336. Begin
  337. sr := sizeof(ArbFloat);
  338. lsr := limit*sr;
  339. getmem(alist, lsr);
  340. getmem(blist, lsr);
  341. getmem(elist, lsr);
  342. getmem(iord, limit*sizeof(ArbInt));
  343. getmem(rlist, lsr);
  344. ier := 0;
  345. neval := 0;
  346. last := 0;
  347. result := 0;
  348. abserr := 0;
  349. alist^[1] := a;
  350. blist^[1] := b;
  351. rlist^[1] := 0;
  352. elist^[1] := 0;
  353. If (epsabs <= 0) And (epsrel < amax1(0.5e+02*macheps, 0.5e-14)) Then
  354. Begin
  355. ier := 6;
  356. freemem(rlist, lsr);
  357. freemem(iord, limit*sizeof(ArbInt));
  358. freemem(elist, lsr);
  359. freemem(blist, lsr);
  360. freemem(alist, lsr);
  361. exit
  362. End;
  363. ierro := 0;
  364. qk21(f, a, b, result, abserr, defabs, resabs);
  365. dres := abs(result);
  366. errbnd := amax1(epsabs, epsrel*dres);
  367. last := 1;
  368. rlist^[1] := result;
  369. elist^[1] := abserr;
  370. iord^[1] := 1;
  371. If (abserr <= 100*macheps*defabs) And (abserr>errbnd) Then ier := 2;
  372. If limit=1 Then ier := 1;
  373. If (ier <> 0) Or ((abserr <= errbnd) And (abserr <> resabs)) Or (abserr=0)
  374. Then
  375. Begin
  376. neval := 21;
  377. freemem(rlist, lsr);
  378. freemem(iord, limit*sizeof(ArbInt));
  379. freemem(elist, lsr);
  380. freemem(blist, lsr);
  381. freemem(alist, lsr);
  382. exit
  383. End;
  384. rlist2[1] := result;
  385. errmax := abserr;
  386. maxerr := 1;
  387. area := result;
  388. errsum := abserr;
  389. abserr := giant;
  390. nrmax := 1;
  391. nres := 0;
  392. numrl2 := 2;
  393. ktmin := 0;
  394. extrap := false;
  395. noext := false;
  396. iroff1 := 0;
  397. iroff2 := 0;
  398. iroff3 := 0;
  399. ksgn := -1;
  400. If dres >= (1-50*macheps)*defabs Then ksgn := 1;
  401. go_on := limit > 1;
  402. smallers := false;
  403. while go_on Do
  404. Begin
  405. inc(last);
  406. a1 := alist^[maxerr];
  407. b1 := (alist^[maxerr]+blist^[maxerr])/2;
  408. a2 := b1;
  409. b2 := blist^[maxerr];
  410. erlast := errmax;
  411. qk21(f, a1, b1, area1, error1, resabs, defab1);
  412. qk21(f, a2, b2, area2, error2, resabs, defab2);
  413. area12 := area1+area2;
  414. erro12 := error1+error2;
  415. errsum := errsum+erro12-errmax;
  416. area := area+area12-rlist^[maxerr];
  417. If (defab1 <> error1) And (defab2 <> error2) Then
  418. Begin
  419. If (abs(rlist^[maxerr]-area12) <= 1e-5*abs(area12))
  420. And (erro12 >= 0.99*errmax) Then
  421. Begin
  422. If extrap Then inc(iroff2)
  423. Else inc(iroff1)
  424. End;
  425. If (last > 10) And (erro12 > errmax) Then inc(iroff3)
  426. End;
  427. rlist^[maxerr] := area1;
  428. rlist^[last] := area2;
  429. errbnd := amax1(epsabs, epsrel*abs(area));
  430. If (iroff1+iroff2 >= 10) Or (iroff3>=20) Then ier := 2;
  431. If iroff2>=5 Then ierro := 3;
  432. If last=limit Then ier := 1;
  433. If amax1(abs(a1),abs(b2)) <= (1+100*macheps)*(abs(a2)+1000*midget)
  434. Then ier := 4;
  435. If error2 <= error1 Then
  436. Begin
  437. alist^[last] := a2;
  438. blist^[maxerr] := b1;
  439. blist^[last] := b2;
  440. elist^[maxerr] := error1;
  441. elist^[last] := error2
  442. End
  443. Else
  444. Begin
  445. alist^[maxerr] := a2;
  446. alist^[last] := a1;
  447. blist^[last] := b1;
  448. rlist^[maxerr] := area2;
  449. rlist^[last] := area1;
  450. elist^[maxerr] := error2;
  451. elist^[last] := error1
  452. End;
  453. qpsrt(limit, last, maxerr, errmax, elist^[1], iord^[1], nrmax);
  454. If errsum <= errbnd Then
  455. Begin
  456. smallers := true;
  457. go_on := false
  458. End
  459. Else
  460. Begin
  461. If ier <> 0 Then go_on := false
  462. Else
  463. Begin
  464. If (last=2) Or (Not noext) Then
  465. Begin
  466. If last <> 2 Then
  467. Begin
  468. erlarg := erlarg-erlast;
  469. If abs(b1-a1) > small Then erlarg := erlarg+erro12;
  470. If extrap Or
  471. (abs(blist^[maxerr]-alist^[maxerr]) <= small) Then
  472. Begin
  473. If Not extrap Then nrmax := 2;
  474. extrap := true;
  475. jump := false;
  476. If (ierro <> 3) And (erlarg>=ertest) Then
  477. Begin
  478. id := nrmax;
  479. jupbnd := last;
  480. If last > 2+limit/2 Then jupbnd := limit+3-last;
  481. k := id;
  482. while (k <= jupbnd) and (Not jump) Do
  483. Begin
  484. maxerr := iord^[nrmax];
  485. errmax := elist^[maxerr];
  486. If abs(blist^[maxerr]-alist^[maxerr]) > small
  487. Then jump := true
  488. Else
  489. Begin
  490. nrmax := nrmax+1;
  491. k := k+1
  492. End
  493. End;
  494. End; {(ierro <> 3) and (erlarg>=ertest)}
  495. If Not jump Then
  496. Begin
  497. numrl2 := numrl2+1;
  498. rlist2[numrl2] := area;
  499. qelg(numrl2, rlist2, reseps, abseps,
  500. res3la, nres);
  501. ktmin := ktmin+1;
  502. If (ktmin > 5) And (abserr < 1e-3*errsum)
  503. Then ier := 5;
  504. If abseps < abserr Then
  505. Begin
  506. ktmin := 0;
  507. abserr := abseps;
  508. result := reseps;
  509. correc := erlarg;
  510. ertest := amax1(epsabs,epsrel*abs(reseps));
  511. If abserr <= ertest Then go_on := false
  512. End;
  513. If go_on Then
  514. Begin
  515. If numrl2=1 Then noext := true;
  516. If ier=5 Then go_on := false
  517. Else
  518. Begin
  519. maxerr := iord^[1];
  520. errmax := elist^[maxerr];
  521. nrmax := 1;
  522. extrap := false;
  523. small := small/2;
  524. erlarg := errsum
  525. End; {ier <> 5}
  526. End; {go_on}
  527. End; {not jump}
  528. End; { abs(blist^[maxerr]-alist^[maxerr]) <= small }
  529. End
  530. Else {last=2}
  531. Begin
  532. small := abs(b-a)*0.375;
  533. erlarg := errsum;
  534. ertest := errbnd;
  535. rlist2[2] := area
  536. End
  537. End; {last=2 or not noext}
  538. End; {ier <> 0}
  539. End; {errsum <= errbnd}
  540. If go_on Then go_on := last < limit
  541. End; {while go_on}
  542. p0 := false;
  543. p1 := false;
  544. p2 := false;
  545. p3 := false;
  546. If (abserr=giant) Or smallers Then p0 := true
  547. Else
  548. If ier+ierro=0 Then p1 := true;
  549. If Not (p0 Or p1) Then
  550. Begin
  551. If ierro=3 Then abserr := abserr+correc;
  552. If ier=0 Then ier := 3;
  553. If (result <> 0) And (area <> 0) Then p2 := true
  554. Else
  555. If abserr > errsum Then p0 := true
  556. Else
  557. If area=0 Then p3 := true
  558. Else p1 := true
  559. End;
  560. If p2 Then
  561. Begin
  562. If abserr/abs(result) > errsum/abs(area) Then p0 := true
  563. Else p1 := true
  564. End;
  565. If p1 Then
  566. Begin
  567. If (ksgn=-1) And (amax1(abs(result),abs(area)) <= defabs*0.01)
  568. Then p3 := true
  569. Else
  570. If (0.01 > result/area) Or (result/area > 100) Or (errsum>abs(area))
  571. Then ier := 6;
  572. p3 := true
  573. End;
  574. If p0 Then
  575. Begin
  576. result := 0;
  577. For k:=1 To last Do
  578. result := result+rlist^[k]
  579. End;
  580. If Not p3 Then abserr := errsum;
  581. If ier>2 Then ier := ier-1;
  582. neval := 42*last-21;
  583. freemem(alist, lsr);
  584. freemem(blist, lsr);
  585. freemem(elist, lsr);
  586. freemem(rlist, lsr);
  587. freemem(iord, limit*sizeof(ArbInt));
  588. End;
  589. { single-precision machine constants
  590. r1mach(1) = b**(emin-1), the midget positive magnitude..
  591. r1mach(2) = b**emax*(1 - b**(-t)), the largest magnitude.
  592. r1mach(3) = b**(-t), the midget relative spacing.
  593. r1mach(4) = b**(1-t), the largest relative spacing.
  594. r1mach(5) = log10(b)
  595. }
  596. Procedure qk15i(f: rfunc1r; boun: ArbFloat;
  597. inf: ArbInt;
  598. a, b: ArbFloat;
  599. Var result, abserr, resabs, resasc: ArbFloat);
  600. Const xgk : array[1..8] Of ArbFloat = (
  601. 0.9914553711208126, 0.9491079123427585,
  602. 0.8648644233597691, 0.7415311855993944,
  603. 0.5860872354676911, 0.4058451513773972,
  604. 0.2077849550078985, 0.0000000000000000);
  605. wgk : array[1..8] Of ArbFloat = (
  606. 0.02293532201052922,0.06309209262997855,
  607. 0.1047900103222502, 0.1406532597155259,
  608. 0.1690047266392679, 0.1903505780647854,
  609. 0.2044329400752989, 0.2094821410847278);
  610. wg : array[1..8] Of ArbFloat = (
  611. 0, 0.1294849661688697,
  612. 0, 0.2797053914892767,
  613. 0, 0.3818300505051189,
  614. 0, 0.4179591836734694);
  615. Var absc, absc1, absc2, centr,
  616. dinf, fc, fsum, fval1, fval2,
  617. hlgth, resg, resk, reskh,
  618. tabsc1, tabsc2: ArbFloat;
  619. fv1, fv2: array[1..7] Of ArbFloat;
  620. j, min0: ArbInt;
  621. Begin
  622. If inf<1 Then dinf := inf
  623. Else dinf := 1;
  624. centr := 0.5*(a+b);
  625. hlgth := 0.5*(b-a);
  626. tabsc1 := boun+dinf*(1-centr)/centr;
  627. fval1 := f(tabsc1);
  628. If (inf=2) Then fval1 := fval1+f(-tabsc1);
  629. fc := (fval1/centr)/centr;
  630. resg := wg[8]*fc;
  631. resk := wgk[8]*fc;
  632. resabs := abs(resk);
  633. For j:=1 To 7 Do
  634. Begin
  635. absc := hlgth*xgk[j];
  636. absc1 := centr-absc;
  637. absc2 := centr+absc;
  638. tabsc1 := boun+dinf*(1-absc1)/absc1;
  639. tabsc2 := boun+dinf*(1-absc2)/absc2;
  640. fval1 := f(tabsc1);
  641. fval2 := f(tabsc2);
  642. If (inf=2) Then fval1 := fval1+f(-tabsc1);
  643. If (inf=2) Then fval2 := fval2+f(-tabsc2);
  644. fval1 := (fval1/absc1)/absc1;
  645. fval2 := (fval2/absc2)/absc2;
  646. fv1[j] := fval1;
  647. fv2[j] := fval2;
  648. fsum := fval1+fval2;
  649. resg := resg+wg[j]*fsum;
  650. resk := resk+wgk[j]*fsum;
  651. resabs := resabs+wgk[j]*(abs(fval1)+abs(fval2))
  652. End;
  653. reskh := resk*0.5;
  654. resasc := wgk[8]*abs(fc-reskh);
  655. For j:=1 To 7
  656. Do
  657. resasc := resasc+wgk[j]*(abs(fv1[j]-reskh)+abs(fv2[j]-reskh));
  658. result := resk*hlgth;
  659. resasc := resasc*hlgth;
  660. resabs := resabs*hlgth;
  661. abserr := abs((resk-resg)*hlgth);
  662. If (resasc<>0) And (abserr<>0)
  663. Then
  664. Begin
  665. reskh := 200*abserr/resasc;
  666. If reskh<1
  667. Then abserr := resasc*reskh*sqrt(reskh)
  668. Else abserr := resasc
  669. End;
  670. If (resabs>midget/(50*macheps))
  671. Then
  672. Begin
  673. reskh := macheps*50*resabs;
  674. If abserr<reskh Then abserr := reskh
  675. End
  676. End;
  677. Procedure qagie(f: rfunc1r;
  678. bound: ArbFloat;
  679. inf: ArbInt;
  680. epsabs, epsrel: ArbFloat;
  681. Var result, abserr: ArbFloat;
  682. Var ier: ArbInt);
  683. { procedure qagie is vertaald vanuit de PD-quadpack-Fortran-routine QAGIE
  684. naar Turbo Pascal, waarbij de volgende parameters uit de parameterlijst
  685. verdwenen zijn:
  686. limit , zoiets als 'maximale recursie diepte' vervangen door globale
  687. variabele limit, initieel op 500 gezet
  688. last , actuele 'recursie diepte'
  689. workarrays: alist, blist, rlist, elist en iord ,
  690. vervangen door dynamische locale arrays
  691. neval , het aantal functie-evaluaties
  692. }
  693. Var abseps, area, area1, area12, area2,
  694. a1, a2, b1,b2, correc,
  695. defabs, defab1, defab2, dres,
  696. erlarg, erlast, errbnd, h,
  697. errmax, error1, error2, erro12, errsum, ertest, resabs,
  698. reseps, small: ArbFloat;
  699. res3la : hulpar;
  700. rlist, alist, blist, elist: ^arfloat1;
  701. iord: ^arint1;
  702. rlist2 : stock;
  703. id, ierro, iroff1, iroff2, iroff3, jupbnd,
  704. k, ksgn, ktmin, last, maxerr, nres, nrmax, numrl2: ArbInt;
  705. continue, break, extrap, noext : boolean;
  706. Begin
  707. ier := 6;
  708. h := 50*macheps;
  709. If h<0.5e-14 Then h := 0.5e-14;
  710. If (epsabs<=0) And (epsrel<h) Then exit;
  711. If (inf=2) Then bound := 0;
  712. qk15i(f, bound, inf, 0, 1, result, abserr, defabs, resabs);
  713. dres := abs(result);
  714. errbnd := epsrel*dres;
  715. If epsabs>errbnd Then errbnd := epsabs;
  716. ier := 2;
  717. If (abserr<=100*macheps*defabs) And (abserr>errbnd) Then exit;
  718. ier := 0;
  719. If ((abserr<=errbnd) And (abserr<>resabs)) Or (abserr=0) Then exit;
  720. GetMem(rlist, limit*SizeOf(ArbFloat));
  721. GetMem(alist, limit*SizeOf(ArbFloat));
  722. GetMem(blist, limit*SizeOf(ArbFloat));
  723. GetMem(elist, limit*SizeOf(ArbFloat));
  724. GetMem(iord, limit*SizeOf(ArbInt));
  725. alist^[1] := 0;
  726. blist^[1] := 1;
  727. rlist^[1] := result;
  728. elist^[1] := abserr;
  729. iord^[1] := 1;
  730. rlist2[1] := result;
  731. errmax := abserr;
  732. maxerr := 1;
  733. area := result;
  734. errsum := abserr;
  735. abserr := giant;
  736. nrmax := 1;
  737. nres := 0;
  738. ktmin := 0;
  739. numrl2 := 2;
  740. extrap := false;
  741. noext := false;
  742. ierro := 0;
  743. iroff1 := 0;
  744. iroff2 := 0;
  745. iroff3 := 0;
  746. If dres>=(1-50*macheps)*defabs Then ksgn := 1
  747. Else ksgn := -1;
  748. last := 1;
  749. continue := true;
  750. while (last<limit) and (ier=0) and continue Do
  751. Begin
  752. Inc(last);
  753. a1 := alist^[maxerr];
  754. b1 := 0.5*(alist^[maxerr]+blist^[maxerr]);
  755. a2 := b1;
  756. b2 := blist^[maxerr];
  757. erlast := errmax;
  758. qk15i(f, bound, inf, a1, b1, area1, error1, resabs, defab1);
  759. qk15i(f, bound, inf, a2, b2, area2, error2, resabs, defab2);
  760. area12 := area1+area2;
  761. erro12 := error1+error2;
  762. errsum := errsum+erro12-errmax;
  763. area := area+area12-rlist^[maxerr];
  764. If (defab1<>error1) And (defab2<>error2)
  765. Then
  766. Begin
  767. If (abs(rlist^[maxerr]-area12)<=1e-5*abs(area12)) And
  768. (erro12>=0.99*errmax)
  769. Then If extrap Then Inc(iroff2)
  770. Else Inc(iroff1);
  771. If (last>10) And (erro12>errmax) Then Inc(iroff3)
  772. End;
  773. rlist^[maxerr] := area1;
  774. rlist^[last] := area2;
  775. errbnd := epsrel*abs(area);
  776. If errbnd<epsabs Then errbnd := epsabs;
  777. If (iroff1+iroff2>=10) Or (iroff3>=20) Then ier := 2;
  778. If (iroff2>=5) Then ierro := 3;
  779. If (last=limit) Then ier := 1;
  780. h := abs(a1);
  781. If h<abs(b2) Then h := abs(b2);
  782. If h<=(1+100*macheps)*(abs(a2)+1000*midget) Then ier := 3;
  783. If (error2<=error1) Then
  784. Begin
  785. alist^[last] := a2;
  786. blist^[maxerr] := b1;
  787. blist^[last] := b2;
  788. elist^[maxerr] := error1;
  789. elist^[last] := error2
  790. End
  791. Else
  792. Begin
  793. alist^[maxerr] := a2;
  794. alist^[last] := a1;
  795. blist^[last] := b1;
  796. rlist^[maxerr] := area2;
  797. rlist^[last] := area1;
  798. elist^[maxerr] := error2;
  799. elist^[last] := error1
  800. End;
  801. qpsrt(limit, last, maxerr, errmax, elist^[1], iord^[1], nrmax);
  802. If (errsum<=errbnd) Then continue := false;
  803. If (ier=0) And continue Then
  804. If last=2 Then
  805. Begin
  806. small := 0.375;
  807. erlarg := errsum;
  808. ertest := errbnd;
  809. rlist2[2] := area
  810. End
  811. Else
  812. If Not noext Then
  813. Begin
  814. erlarg := erlarg-erlast;
  815. If (abs(b1-a1)>small) Then erlarg := erlarg+erro12;
  816. break := false;
  817. If Not extrap Then
  818. If (abs(blist^[maxerr]-alist^[maxerr])>small)
  819. Then break := true
  820. Else
  821. Begin
  822. extrap := true;
  823. nrmax := 2
  824. End;
  825. If Not break And (ierro<>3) And (erlarg>ertest) Then
  826. Begin
  827. id := nrmax;
  828. jupbnd := last;
  829. If (last>(2+limit Div 2)) Then jupbnd := limit+3-last;
  830. k := id-1;
  831. while (k<jupbnd) and not break
  832. Do
  833. Begin
  834. Inc(k);
  835. maxerr := iord^[nrmax];
  836. errmax := elist^[maxerr];
  837. If (abs(blist^[maxerr]-alist^[maxerr])>small)
  838. Then break := true
  839. Else Inc(nrmax)
  840. End
  841. End;
  842. If Not break Then
  843. Begin
  844. Inc(numrl2);
  845. rlist2[numrl2] := area;
  846. qelg(numrl2, rlist2, reseps, abseps, res3la, nres);
  847. Inc(ktmin);
  848. If (ktmin>5) And (abserr<1e-3*errsum) Then ier := 4;
  849. If (abseps<abserr)
  850. Then
  851. Begin
  852. ktmin := 0;
  853. abserr := abseps;
  854. result := reseps;
  855. correc := erlarg;
  856. ertest := epsrel*abs(reseps);
  857. If epsabs>ertest Then ertest := epsabs;
  858. If (abserr<=ertest) Then continue := false
  859. End;
  860. End;
  861. If continue And Not break Then
  862. Begin
  863. If (numrl2=1) Then noext := true;
  864. If ier<>4 Then
  865. Begin
  866. maxerr := iord^[1];
  867. errmax := elist^[maxerr];
  868. nrmax := 1;
  869. extrap := false;
  870. small := small*0.5;
  871. erlarg := errsum
  872. End
  873. End
  874. End
  875. End;
  876. h := 0;
  877. For k := 1 To last Do
  878. h := h+rlist^[k];
  879. FreeMem(rlist, limit*SizeOf(ArbFloat));
  880. FreeMem(alist, limit*SizeOf(ArbFloat));
  881. FreeMem(blist, limit*SizeOf(ArbFloat));
  882. FreeMem(elist, limit*SizeOf(ArbFloat));
  883. FreeMem(iord, limit*SizeOf(ArbInt));
  884. If (errsum<=errbnd) Or (abserr=giant) Then
  885. Begin
  886. result := h;
  887. abserr := errsum;
  888. exit
  889. End;
  890. If (ier+ierro)=0 Then
  891. Begin
  892. h := abs(result);
  893. If h<abs(area) Then h := abs(area);
  894. If (ksgn<>-1) Or (h>defabs*0.01) Then
  895. If (0.01>result/area) Or (result/area>100) Or (errsum>abs(area))
  896. Then ier := 5;
  897. exit
  898. End;
  899. If ierro=3 Then abserr := abserr+correc;
  900. If ier=0 Then ier := 2;
  901. If (result<>0) And (area<>0) Then
  902. If abserr/abs(result)>errsum/abs(area)
  903. Then
  904. Begin
  905. result := h;
  906. abserr := errsum;
  907. exit
  908. End
  909. Else
  910. Begin
  911. h := abs(result);
  912. If h<abs(area) Then h := abs(area);
  913. If (ksgn<>-1) Or (h>defabs*0.01) Then
  914. If (0.01>result/area) Or (result/area>100) Or (errsum>abs(area))
  915. Then ier := 5;
  916. exit
  917. End;
  918. If abserr>errsum Then
  919. Begin
  920. result := h;
  921. abserr := errsum;
  922. exit
  923. End;
  924. If area<>0
  925. Then
  926. Begin
  927. h := abs(result);
  928. If h<abs(area) Then h := abs(area);
  929. If (ksgn<>-1) Or (h>defabs*0.01) Then
  930. If (0.01>result/area) Or (result/area>100) Or (errsum>abs(area))
  931. Then ier := 5
  932. End
  933. End;
  934. Procedure int1fr(f: rfunc1r; a, b, ae: ArbFloat; Var integral, err: ArbFloat;
  935. Var term: ArbInt);
  936. Var neval, ier, last, inf: ArbInt;
  937. Begin
  938. term := 3;
  939. integral := NaN;
  940. If abs(a)=infinity
  941. Then If abs(b)=infinity
  942. Then If (a=b)
  943. Then exit
  944. Else
  945. Begin
  946. qagie(f, 0, 2, ae, epsrel, integral, err, ier);
  947. If a=infinity Then integral := -integral
  948. End
  949. Else If a=-infinity
  950. Then qagie(f, b, -1, ae, epsrel, integral, err, ier)
  951. Else
  952. Begin
  953. qagie(f, b, 1, ae, epsrel, integral, err, ier);
  954. integral := -integral
  955. End
  956. Else If abs(b)=infinity
  957. Then If b=-infinity
  958. Then
  959. Begin
  960. qagie(f, a, -1, ae, epsrel, integral, err, ier);
  961. integral := -integral
  962. End
  963. Else qagie(f, a, 1, ae, epsrel, integral, err, ier)
  964. Else qagse(f, a, b, ae, epsrel, limit, integral, err, neval, ier, last);
  965. term := 4;
  966. If ier=6 Then term := 3;
  967. If ier=0 Then term := 1;
  968. If (ier=2) Or (ier=4) Then term := 2
  969. End;
  970. Begin
  971. limit := 500;
  972. epsrel := 0;
  973. End.
  974. {
  975. $Log$
  976. Revision 1.2 2000-01-25 20:21:41 marco
  977. * small updates, crlf fix, and RTE 207 problem
  978. Revision 1.1 2000/01/24 22:08:58 marco
  979. * initial version
  980. }