24 R
sqr(R x) {
return x*x; }
27 #define MAXIT (sizeof(xptr)/sizeof(xptr[0])-1) 29 static double c_gl, (*func_gl)(
double x);
31 static double hifn(
double x)
36 static double lofn(
double x)
43 double (*func)(double,
void *);
48 static double hifn_r(
double x,
void *vdata)
52 return((*data->func)(x, data->fdata)/
53 sqrt(x<ac ? ac-x : 1e-16*(ac ? fabs(ac) : 1)));
56 static double lofn_r(
double x,
void *vdata)
60 return((*data->func)(x, data->fdata)/
61 sqrt(x>ac ? x-ac : 1e-16*(ac ? fabs(ac) : 1)));
65 double kgauss_sub(
double (*f)(
double x),
double (*f_r)(
double x,
void *),
66 void *fdata,
double a,
double b,
double c,
double *acc,
67 int root,
int lev,
double I0,
int maxrecur,
int paranoid)
71 {0.9491079123427585245, 0.7415311855993944399, 0.40584515137739716691, 0},
73 {0.12948496616886969327, 0.27970539148927666790, 0.38183005050511894495,
74 0.20897959183673469388},
76 {0.9914553711208126392, 0.8648644233597690728, 0.5860872354676911303,
77 0.20778495500789846760},
79 {0.06309209262997855329, 0.14065325971552591875, 0.19035057806478540991,
80 0.10474107054236391401, 0.022935322010529224964, 0.10479001032225018384,
81 0.16900472663926790283, 0.20443294007529889241},
83 {0.9986871096784667298, 0.9753835882088933697, 0.9122048827832628784,
84 0.8076889391724375091, 0.6673480981043001754, 0.49863678655283200429,
85 0.30857924791058777890, 0.10452827381078071340},
87 {0.031577706217045857274, 0.07033204641040065094, 0.09517802993183068012,
88 0.052371606782402922364, 0.011319468444683435107, 0.052384370820982692472,
89 0.08449876530124302120, 0.10221418000570274392, 0.0036349311950498838561,
90 0.021039446258726795607, 0.042193500584546594485, 0.061821985645449856431,
91 0.07787534711524599642, 0.09026180214655860231, 0.09919685766743291249,
92 0.10409995547269735501},
94 {0.9998092141980435177, 0.9960402386259685431, 0.9846371438756441798,
95 0.9635649536133961699, 0.9319846573806651406, 0.8898093648749426400,
96 0.8374568325601445865, 0.7756739083583348141, 0.7053824093748503091,
97 0.6275454213822932614, 0.5430823509867011311, 0.45285563284960723138,
98 0.35771483158603327041, 0.25855961875447247355, 0.15639264033608140153,
99 0.052344665459830506663},
101 {0.015788872779215423953, 0.035166023524553984272, 0.047589015038602680558,
102 0.026185803412726870878, 0.005660867725095312756, 0.026192186880710567449,
103 0.042249382781031758514, 0.051107090052427067322, 0.0018039393894459073286,
104 0.010519600488254708543, 0.021096745715199243564, 0.030910992205938984344,
105 0.038937673364353656898, 0.045130900978520531208, 0.049598428775219425281,
106 0.052049977691713990513, 0.0005394072866580217702,
107 0.0035577405571320363985, 0.008008877528118372922, 0.013129713474427210903,
108 0.018455916099884639804, 0.023683152580752000206, 0.028605857490498295944,
109 0.033099092907400232260, 0.037111404910397191759, 0.040648875788571024107,
110 0.043742748418925043826, 0.046413730813032435148, 0.048652555041851185681,
111 0.050419337829027882637, 0.051653256012700288788, 0.052290832457614024465},
113 {0.9999732140537096663, 0.9994072045541133135, 0.9975832115407271425,
114 0.9940109708349837137, 0.9883399710474278217, 0.9803243695495499628,
115 0.9698006651097387898, 0.9566689345185500717, 0.9408797537558513210,
116 0.9224249470755334487, 0.9013304843743343536, 0.8776505702242030085,
117 0.8514623710548997088, 0.8228610497537872099, 0.7919549469554387927,
118 0.7588609140247034710, 0.7236999634679475019, 0.6865935263842583902,
119 0.6476606483346630945, 0.6070163823125118480, 0.5647714587971209075,
120 0.5210330881098700049, 0.47590656926256125696, 0.42949731364743432232,
121 0.38191294949982269268, 0.33326529310537285172, 0.28367206848397232384,
122 0.23325827809314719522, 0.18215708913074090694, 0.13051006423363166234,
123 0.07846658760948939210, 0.026182433405385318012},
125 {0.007894436389622294500, 0.017583011762276993951, 0.023794507519301340354,
126 0.013092901706363435451, 0.0028304340009942515258, 0.013096093440355333640,
127 0.021124691390515879519, 0.025553545026213533694, 0.0009020326132240592195,
128 0.005259800244982030301, 0.010548372857600215651, 0.015455496102969499733,
129 0.019468836682176829061, 0.022565450489260265736, 0.024799214387609712688,
130 0.026024988845856995283, 0.00026824492648199271332,
131 0.0017788676370217658788, 0.004004438754554190525, 0.006564856737114416480,
132 0.009227958049939655524, 0.011841576290375841473, 0.014302928745249129776,
133 0.016549546453700112606, 0.018555702455198594863, 0.020324437894285511663,
134 0.021871374209462521731, 0.023206865406516217476, 0.024326277520925592782,
135 0.025209668914513941280, 0.025826628006350144365, 0.026145416228807012208,
136 0.00007666028154662839408, 0.0005490365712772494279,
137 0.0013149375828678979980, 0.0022863309701736851777,
138 0.0034049581223715159493, 0.004624110998701176147, 0.005907814428674106763,
139 0.007227959698738149350, 0.008561844248934732274, 0.009890749642424429307,
140 0.011199152457074135131, 0.012474289971042915773, 0.013705938795913981808,
141 0.014886315023128753955, 0.016010013553407559797, 0.017073903395086741336,
142 0.018076904204550982752, 0.019019598918148049863, 0.019903688814155477260,
143 0.020731356767667036739, 0.021504646454995216775, 0.022224966589876512971,
144 0.022892785760346567564, 0.023507517384958226284, 0.024067543172072124703,
145 0.024570314471893502741, 0.025012500880974706687, 0.025390194359438009696,
146 0.025699193007816822839, 0.025935371167822469283, 0.026095105661905096599,
147 0.026175694952196227010},
149 {0.9999963067486951954, 0.9999152752559348126, 0.9996433483555746783,
150 0.9990913137344203859, 0.9981867960827265115, 0.9968697356940136751,
151 0.9950890556563352695, 0.9928012000738545143, 0.9899695008102539966,
152 0.9865635049160346460, 0.9825582265834872996, 0.9779334496251760458,
153 0.9726731369993381727, 0.9667649473643406394, 0.9601998389233076039,
154 0.9529717393703213579, 0.9450772648209298621, 0.9365154750708113300,
155 0.9272876559818071015, 0.9173971221917106181, 0.9068490349651485285,
156 0.8956502311299054918, 0.8838090598842230091, 0.8713352249541538215,
157 0.8582396302130598049, 0.8445342274991779505, 0.8302318660071731089,
158 0.8153461432903685913, 0.7998912585787304708, 0.7838818697648637995,
159 0.7673329559944715517, 0.7502596882683412608, 0.7326773107667189801,
160 0.7146010356960037625, 0.6960459542984969734, 0.6770269662478566161,
161 0.6575587289946255923, 0.6376556277780920590, 0.6173317660619912557,
162 0.5966009751817463673, 0.5754768411167735517, 0.5539727456204857446,
163 0.5321019185252632801, 0.5098774979234026434, 0.48731259509574956027,
164 0.46442036146072008750, 0.44121405535670282430, 0.41770710704249008257,
165 0.39391318079976768177, 0.36984623336963443023, 0.34552056811136913486,
166 0.32095088424031443935, 0.29615232032684852625, 0.27114049099145203618,
167 0.24593151549383166774, 0.22054203676240731795, 0.19498922939984828060,
168 0.16929079535915298899, 0.14346494631303911128, 0.11753037221284078240,
169 0.09150619611020609502, 0.06541191594510644914, 0.039267334634802255021,
170 0.013092480382206823402},
172 {0.003947218194811147250, 0.008791505881138496975, 0.011897253759650670177,
173 0.006546450853181717726, 0.0014152170004971327031, 0.006548046720177666820,
174 0.010562345695257939759, 0.012776772513106766847,
175 0.00045101631047035672287, 0.0026299001224910151504,
176 0.005274186428800107826, 0.007727748051484749866, 0.009734418341088414530,
177 0.011282725244630132868, 0.012399607193804856344, 0.013012494422928497641,
178 0.00013412814082582891278, 0.0008894338185147723354,
179 0.0020022193772770952853, 0.0032824283685572082402,
180 0.004613979024969827762, 0.005920788145187920736, 0.007151464372624564888,
181 0.008274773226850056303, 0.009277851227599297431, 0.010162218947142755831,
182 0.010935687104731260865, 0.011603432703258108738, 0.012163138760462796391,
183 0.012604834457256970640, 0.012913314003175072183, 0.013072708114403506104,
184 0.000038150115729678883900, 0.00027451814107948522455,
185 0.0006574687913192254503, 0.0011431654850866902753,
186 0.0017024790611857576058, 0.0023120554993505880716,
187 0.0029539072143370533817, 0.0036139798493690746749,
188 0.004280922124467366137, 0.004945374821212214654, 0.005599576228537067565,
189 0.006237144985521457886, 0.006852969397956990904, 0.007443157511564376978,
190 0.008005006776703779898, 0.008536951697543370668, 0.009038452102275491376,
191 0.009509799459074024932, 0.009951844407077738630, 0.010365678383833518369,
192 0.010752323227497608387, 0.011112483294938256485, 0.011446392880173283782,
193 0.011753758692479113142, 0.012033771586036062351, 0.012285157235946751371,
194 0.012506250440487353344, 0.012695097179719004848, 0.012849596503908411419,
195 0.012967685583911234641, 0.013047552830952548299, 0.013087847476098113505,
196 0.000010631773187689331551, 0.00007993324160416183366,
197 0.00019934629225661752482, 0.00035868882139811536585,
198 0.0005508028934055661185, 0.0007705041764177031044,
199 0.0010138011699455911823, 0.0012771043628389088432,
200 0.0015571262359162832193, 0.0018509459382531284054,
201 0.0021560121638169668193, 0.0024700972126411342886,
202 0.0027912405830786672989, 0.0031176998048792041352,
203 0.0034479123342294940334, 0.0037804671803520797730,
204 0.004114083913896834036, 0.004447597043058076436, 0.004779944312994714648,
205 0.005110157949984851451, 0.005437358183979665448, 0.005760748571634470826,
206 0.006079612745214887369, 0.006393312261301573719, 0.006701285238160699107,
207 0.007003045467007902253, 0.007298181671581202210, 0.007586356581948386573,
208 0.007867305490660966780, 0.008140833979476674666, 0.008406814548503037823,
209 0.008665181949799686451, 0.008915927123675733374, 0.009159089753242067779,
210 0.009394749581797212635, 0.009623016765016277986, 0.009844021640034099622,
211 0.010057904370771690380, 0.010264804960494993925, 0.010464854101398603935,
212 0.010658165257317194199, 0.010844828258217972251, 0.011024904540326784412,
213 0.011198424015314858577, 0.011365383419231345237, 0.011525745897233022556,
214 0.011679441536946909568, 0.011826368574785933586, 0.011966395058237419718,
215 0.012099360836564130280, 0.012225079850850787912, 0.012343342780032364446,
216 0.012453920155062457233, 0.012556566069048776249, 0.012651022586171432515,
217 0.012737024893523940703, 0.012814307159984132831, 0.012882608979232163138,
218 0.012941682193613858686, 0.012991297832248668971, 0.013031252857161437795,
219 0.013061376397838128294, 0.013081535166722437529, 0.013091637782748817614},
220 *xptr[]={x7, x15, x31, x63, x127, x255},
221 *wptr[]={w7, w15, w31, w63, w127, w255};
225 double acc1, sum_1=0, sum0, sum, *w, *x, epst, dx, xm, xr, xs1, xs2,
226 fn[128], r, rc, eps, eps0;
227 int i, num, iter, lm, looks_ok=1;
232 xs1=0.5*sqrt(c-a); xs2=0.5*sqrt(c-b); xr=2*(xs1-xs2);
234 xr=0.5*(b-a); xs1=xs2=0;
237 sum=0; iter=0; num=7; lm=(num+1)/2-1; x=xptr[0], w=wptr[0];
240 for (i=0; i<lm; i++) {
241 double z1=1+x[i], z2=1-x[i];
243 fn[i]=(*f_r)(c+root*
sqr(z1*xs1+z2*xs2), fdata)+
244 (*f_r)(c+root*
sqr(z1*xs2+z2*xs1), fdata);
247 fn[lm]=2*(*f_r)(c+root*
sqr(xs1+xs2), fdata); sum+=w[lm]*fn[lm];
249 for (i=0; i<lm; i++) {
250 double z1=1+x[i], z2=1-x[i];
252 fn[i]=(*f)(c+root*
sqr(z1*xs1+z2*xs2))+
253 (*f)(c+root*
sqr(z1*xs2+z2*xs1));
256 fn[lm]=2*(*f)(c+root*
sqr(xs1+xs2)); sum+=w[lm]*fn[lm];
260 for (i=0; i<lm; i++) {
261 dx=xr*x[i]; fn[i]=(*f_r)(xm-dx, fdata)+(*f_r)(xm+dx, fdata);
264 fn[lm]=2*(*f_r)(xm, fdata); sum+=w[lm]*fn[lm];
266 for (i=0; i<lm; i++) {
267 dx=xr*x[i]; fn[i]=(*f)(xm-dx)+(*f)(xm+dx);
270 fn[lm]=2*(*f)(xm); sum+=w[lm]*fn[lm];
274 lm++; rc=4*0.15; eps=0.05/(0.5*rc);
277 iter++; x=xptr[iter]-lm; w=wptr[iter]; rc*=0.5;
278 for (i=0, sum=0; i<lm; i++) sum+=w[i]*fn[i];
281 for (i=lm; i<=num; i++) {
282 double z1=1+x[i], z2=1-x[i];
284 fn[i]=(*f_r)(c+root*
sqr(z1*xs1+z2*xs2), fdata)+
285 (*f_r)(c+root*
sqr(z1*xs2+z2*xs1), fdata);
289 for (i=lm; i<=num; i++) {
290 double z1=1+x[i], z2=1-x[i];
292 fn[i]=(*f)(c+root*
sqr(z1*xs1+z2*xs2))+
293 (*f)(c+root*
sqr(z1*xs2+z2*xs1));
299 for (i=lm; i<=num; i++) {
300 dx=xr*x[i]; fn[i]=(*f_r)(xm-dx, fdata)+(*f_r)(xm+dx, fdata);
304 for (i=lm; i<=num; i++) {
305 dx=xr*x[i]; fn[i]=(*f)(xm-dx)+(*f)(xm+dx);
311 eps0=eps; lm=num+1; num=2*num+1;
312 if (sum) eps=1e-16+fabs((sum0-sum)/sum);
else eps=1;
313 r=eps/eps0;
if (I0) epst=fabs(xr*(sum-sum0)/I0);
else epst=eps;
316 if (iter>1) epst*=3*(r<1e-4 ? 1e-4 : r>1 ? 1 : r);
321 looks_ok=(fabs(xr*(sum_1-sum0))<=acc1*fabs(I0) &&
322 fabs(xr*(sum0-sum))<=acc1*fabs(I0) &&
323 fabs(xr*(sum_1-sum))<=acc1*fabs(I0));
325 looks_ok=(fabs(sum_1-sum0)<=acc1*fabs(sum0) &&
326 fabs(sum0-sum)<=acc1*fabs(sum) &&
327 fabs(sum_1-sum)<=acc1*fabs(sum));
333 if (r>rc || (iter==
MAXIT-1 && epst*0.5*r>acc1)) {
334 if (iter==1) epst*=3;
337 }
while (((!looks_ok && epst<acc1) || (sum0!=sum && epst>acc1))
340 if (sum0==sum) epst=1e-16;
341 if (!looks_ok || epst>acc1)
342 if (lev<maxrecur && a!=xm) {
343 if (I0==0 && epst<0.1) I0=xr*sum;
356 acc, 0, lev+1, I0, maxrecur, paranoid)+
358 acc, -1, lev+1, I0, maxrecur, paranoid));
361 acc, 0, lev+1, I0,maxrecur, paranoid)+
363 acc, 1, lev+1, I0, maxrecur, paranoid));
367 acc, 0, lev+1, I0, maxrecur, paranoid)+
369 acc, 0, lev+1, I0, maxrecur, paranoid));
371 if (*acc>0 && first) {
372 fprintf(stderr,
"Precision not met in kgauss (%.1e/%.1e) in " 373 "[%.12g,%.12g]\n", epst, acc1, xm-0.5*(b-a), xm+0.5*(b-a));
376 if (lev==0) *acc=(-epst);
378 else if (lev==0) *acc=epst;
382 double kgauss(
double (*f)(
double x),
double a,
double b,
double err)
384 return(
kgauss_sub(f, NULL, NULL, a, b, 0.0, &err, 0, 0, 0., 100, 0));
387 double kgauss2(
double (*f)(
double x),
double a,
double b,
double err)
389 return(
kgauss_sub(f, NULL, NULL, a, b, 0.0, &err, 0, 0, 0., 100, 1));
392 double ksqrtgauss(
double (*f)(
double x),
double a,
double b,
double c,
399 if (a>b) {
double tmp=a; a=b; b=tmp; sgn=-1; }
else sgn=1;
401 return(sgn*
kgauss_sub(f, NULL, NULL, 2*c-b, 2*c-a, c,
402 &err, 1, 0, 0., 100, 0));
405 &err, -1, 0, 0., 100, 0));
410 double kgauss_r(
double (*f_r)(
double x,
void *),
void *fdata,
411 double a,
double b,
double err)
413 return(
kgauss_sub(NULL, f_r, fdata, a, b, 0.0, &err, 0, 0, 0., 100, 0));
416 double kgauss2_r(
double (*f_r)(
double x,
void *),
void *fdata,
417 double a,
double b,
double err)
419 return(
kgauss_sub(NULL, f_r, fdata, a, b, 0.0, &err, 0, 0, 0., 100, 1));
423 double a,
double b,
double c,
double err)
428 if (a>b) {
double tmp=a; a=b; b=tmp; sgn=-1; }
else sgn=1;
430 return(sgn*
kgauss_sub(NULL, f_r, fdata, 2*c-b, 2*c-a, c,
431 &err, 1, 0, 0., 100, 0));
433 return(sgn*
kgauss_sub(NULL, f_r, fdata, a, b, c,
434 &err, -1, 0, 0., 100, 0));
double ksqrtgauss_r(double(*f_r)(double x, void *), void *fdata, double a, double b, double c, double err)
static double hifn_r(double x, void *vdata)
double kgauss_sub(double(*f)(double x), double(*f_r)(double x, void *), void *fdata, double a, double b, double c, double *acc, int root, int lev, double I0, int maxrecur, int paranoid)
static double hifn(double x)
static double lofn_r(double x, void *vdata)
double kgauss2_r(double(*f_r)(double x, void *), void *fdata, double a, double b, double err)
double kgauss(double(*f)(double x), double a, double b, double err)
static double(* func_gl)(double x)
static double lofn(double x)
double kgauss2(double(*f)(double x), double a, double b, double err)
double ksqrtgauss(double(*f)(double x), double a, double b, double c, double err)
double kgauss_r(double(*f_r)(double x, void *), void *fdata, double a, double b, double err)