/* ---------------------------------------------------------------------- */ LDBLE qromb_midpnt (LDBLE x1, LDBLE x2) /* ---------------------------------------------------------------------- */ { LDBLE ss, dss; LDBLE sv[MAX_QUAD + 2], h[MAX_QUAD + 2]; int j; h[0] = 1.0; sv[0] = midpnt (x1, x2, 1); for (j = 1; j < MAX_QUAD; j++) { sv[j] = midpnt (x1, x2, j + 1); h[j] = h[j - 1] / 9.0; if (fabs (sv[j] - sv[j - 1]) <= G_TOL * fabs (sv[j])) { sv[j] *= surface_charge_ptr->grams * surface_charge_ptr->specific_area * alpha / F_C_MOL; /* (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */ if ((x2 - 1) < 0.0) sv[j] *= -1.0; if (debug_diffuse_layer == TRUE) { output_msg (OUTPUT_MESSAGE, "Iterations in qromb_midpnt: %d\n", j); } return (sv[j]); } if (j >= K_POLY - 1) { polint (&h[j - K_POLY], &sv[j - K_POLY], K_POLY, 0.0, &ss, &dss); if (fabs (dss) <= G_TOL * fabs (ss) || fabs (dss) < G_TOL) { ss *= surface_charge_ptr->grams * surface_charge_ptr->specific_area * alpha / F_C_MOL; /* (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */ if ((x2 - 1) < 0.0) ss *= -1.0; if (debug_diffuse_layer == TRUE) { output_msg (OUTPUT_MESSAGE, "Iterations in qromb_midpnt: %d\n", j); } return (ss); } } } sprintf (error_string, "\nToo many iterations integrating diffuse layer.\n"); error_msg (error_string, STOP); return (-999.9); }
double midpnt(double (*func)(double), double a, double b, int n){ double x,tnm,sum,del,ddel; static double s; int it,j; if(n==1){ s=(b-a)*FUNC(0.5*(a+b)); return s; } else { for(it=1,j=1;j<n-1;j++) it*=3; tnm=it; del=(b-a)/(3.0*tnm); ddel=del+del; x=a+0.5*del; sum=0.0; for(j=1;j<=it;j++) { sum+=FUNC(x); x+=ddel; sum+=FUNC(x); x+=del; } s=( midpnt(func,a,b,n-1) + (b-a)*sum/tnm )/3.0; return s; } }
int main(void) { float a=0.0,b=1.0,s; int i; printf("\nIntegral of func computed with MIDPNT\n"); printf("Actual value of integral is %7.4f\n",(fint(b)-fint(a))); printf("%6s %29s \n","n","Approx. integral"); for (i=1;i<=NMAX;i++) { s=midpnt(func,a,b,i); printf("%6d %24.6f\n",i,s); } return 0; }