int.pas 31 KB

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