int.pas 31 KB

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