1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
double gauss_legendre(int n, double (*f)(double,void*), void* data, double a, double b)
{
double* x = NULL;
double* w = NULL;
double A,B,Ax,s;
int i, dtbl, m;
m = (n+1)>>1;
/* Load appropriate predefined table */
dtbl = 0;
for (i = 0; i<GLAWSIZE;i++)
{
if(n==glaw[i].n)
{
x = glaw[i].x;
w = glaw[i].w;
break;
}
}
/* Generate new if non-predefined table is required */
/* with precision of 1e-10 */
if(NULL==x)
{
dtbl = 1;
x = (double*)malloc(m*sizeof(double));
w = (double*)malloc(m*sizeof(double));
gauss_legendre_tbl(n,x,w,1e-10);
}
A = 0.5*(b-a);
B = 0.5*(b+a);
if(n&1) /* n - odd */
{
s = w[0]*((*f)(B,data)); // <====
for (i=1;i<m;i++)
{
Ax = A*x[i];
s += w[i]*((*f)(B+Ax,data)+(*f)(B-Ax,data)); // <====
}
}
else
{ /* n - even */
s = 0.0;
for (i=0;i<m;i++)
{
Ax = A*x[i];
s += w[i]*((*f)(B+Ax,data)+(*f)(B-Ax,data)); // <====
}
}
if (dtbl)
{
free(x);
free(w);
}
return A*s;
}
|