/*
Programmazione II - Algoritmo di Ridders
Ridders algorithm implementation (from Numerical Recipes)
By the way: don't emulate this coding style!
*/
#include
#include
#define CON 1.4 /* Stepsize id decreased by CON at each iteration */
#define CON2 (CON*CON)
#define BIG 1.0e50
#define NTAB 10 /* Sets maximum size of tableau */
#define SAFE 2.0 /* Return when error is SAFE worse than the best so far */
double
dfridr(double (*func)(double), double x, double h, double *err)
/* returns the derivative of a function func at a point x by Ridders'
method of polynomial extrapolation. The value h is input as an estimated
initial stepsize; it need not be small, but rather should be an
increment in x over which func changes substantially.
An estimate of the error in the derivative is returned as err */
{
int i,j;
double errt, fac, hh, a[NTAB+1][NTAB+1], ans;
double test1,test2;
if (h == 0)
{
fprintf(stderr,"Third argument to function dfridr must be nonzero.");
return(0);
}
hh = h;
/* Note: this routine assumes a to be a one-based matrix */
a[1][1]=((*func)(x+hh)-(*func)(x-hh))/(2.0*hh);
*err = BIG;
for (i=2;i<=NTAB;i++)
{
/* Successive columns in the Neville tableau will go to smaller
stepsizes and higher orders of extrapolation. */
hh /= CON;
/* Try new, smaller stepsize */
a[1][i]=((*func)(x+hh)-(*func)(x-hh))/(2.0*hh);
fac=CON2;
for(j=2;j<=i;j++)
{
/* Compute extrapolations of various orders, requiring no
new function evaluations */
a[j][i] = (a[j-1][i]*fac-a[j-1][i-1])/(fac-1.0);
fac = CON2*fac;
test1 = fabs(a[j][i]-a[j-1][i]);
test2 = fabs(a[j][i]-a[j-1][i-1]);
if (test1>test2) errt = test1;
else errt = test2;
/* The error strategy is to compare each new extrapolation to one
order lower, both at the present stepsize ans the previous one. */
if (errt <= *err)
{
/* If error is decreased, save the improved answer */
*err=errt;
ans=a[j][i];
}
}
/* If higher order is worse by a significant factor SAFE, then quit early */
if (fabs(a[i][i]-a[i-1][i-1]) >= SAFE*(*err)) break;
}
return (ans);
}