22 RichardsonDerivator::RichardsonDerivator(
double h) :
23 fFunctionCopied(false),
30 RichardsonDerivator::RichardsonDerivator(
const ROOT::Math::IGenFunction & f,
double h,
bool copyFunc) :
31 fFunctionCopied(copyFunc),
37 if (copyFunc) fFunction = f.Clone();
42 RichardsonDerivator::~RichardsonDerivator()
45 if ( fFunction != 0 && fFunctionCopied )
49 RichardsonDerivator::RichardsonDerivator(
const RichardsonDerivator & rhs)
53 fStepSize = rhs.fStepSize;
54 fLastError = rhs.fLastError;
55 fFunctionCopied = rhs.fFunctionCopied;
56 SetFunction(*rhs.fFunction);
59 RichardsonDerivator & RichardsonDerivator::operator= (
const RichardsonDerivator & rhs)
62 if (&rhs ==
this)
return *
this;
63 fFunctionCopied = rhs.fFunctionCopied;
64 fStepSize = rhs.fStepSize;
65 fLastError = rhs.fLastError;
66 SetFunction(*rhs.fFunction);
70 void RichardsonDerivator::SetFunction(
const ROOT::Math::IGenFunction & f)
73 if (fFunctionCopied) {
74 if (fFunction)
delete fFunction;
75 fFunction = f.Clone();
80 double RichardsonDerivator::Derivative1 (
const IGenFunction &
function,
double x,
double h)
82 const double keps = std::numeric_limits<double>::epsilon();
86 xx = x+h;
double f1 = (
function)(xx);
88 xx = x-h;
double f2 = (
function)(xx);
90 xx = x+h/2;
double g1 = (
function)(xx);
91 xx = x-h/2;
double g2 = (
function)(xx);
97 double deriv = h2*(8*d2 - d0)/3.;
103 double e0 = (std::abs( f1) + std::abs(f2)) * keps;
104 double e2 = 2* (std::abs( g1) + std::abs(g2)) * keps + e0;
105 double delta = std::max( std::abs( h2*d0), std::abs( deriv) ) * std::abs( x)/h * keps;
108 double err_trunc = std::abs( deriv - h2*d0 );
110 double err_round = std::abs( e2/h) + delta;
112 fLastError = err_trunc + err_round;
116 double RichardsonDerivator::DerivativeForward (
const IGenFunction &
function,
double x,
double h)
118 const double keps = std::numeric_limits<double>::epsilon();
122 xx = x+h/4.0;
double f1 = (
function)(xx);
123 xx = x+h/2.0;
double f2 = (
function)(xx);
125 xx = x+(3.0/4.0)*h;
double f3 = (
function)(xx);
126 xx = x+h;
double f4 = (
function)(xx);
130 double r2 = 2.0*(f4 - f2);
131 double r4 = (22.0 / 3.0) * (f4 - f3) - (62.0 / 3.0) * (f3 - f2) +
132 (52.0 / 3.0) * (f2 - f1);
136 double e4 = 2 * 20.67 * (fabs (f4) + fabs (f3) + fabs (f2) + fabs (f1)) * keps;
140 double dy = std::max (fabs (r2 / h), fabs (r4 / h)) * fabs (x / h) * keps;
147 double result = r4 / h;
148 double abserr_trunc = fabs ((r4 - r2) / h);
149 double abserr_round = fabs (e4 / h) + dy;
151 fLastError = abserr_trunc + abserr_round;
157 double RichardsonDerivator::Derivative2 (
const IGenFunction &
function,
double x,
double h)
159 const double kC1 = 4*std::numeric_limits<double>::epsilon();
162 xx = x+h;
double f1 = (
function)(xx);
163 xx = x;
double f2 = (
function)(xx);
164 xx = x-h;
double f3 = (
function)(xx);
166 xx = x+h/2;
double g1 = (
function)(xx);
167 xx = x-h/2;
double g3 = (
function)(xx);
171 double d0 = f3 - 2*f2 + f1;
172 double d2 = 4*g3 - 8*f2 +4*g1;
173 fLastError = kC1*hh*f2;
174 double deriv = hh*(4*d2 - d0)/3.;
178 double RichardsonDerivator::Derivative3 (
const IGenFunction &
function,
double x,
double h)
180 const double kC1 = 4*std::numeric_limits<double>::epsilon();
183 xx = x+2*h;
double f1 = (
function)(xx);
184 xx = x+h;
double f2 = (
function)(xx);
185 xx = x-h;
double f3 = (
function)(xx);
186 xx = x-2*h;
double f4 = (
function)(xx);
187 xx = x;
double fx = (
function)(xx);
188 xx = x+h/2;
double g2 = (
function)(xx);
189 xx = x-h/2;
double g3 = (
function)(xx);
192 double hhh = 1/(h*h*h);
193 double d0 = 0.5*f1 - f2 +f3 - 0.5*f4;
194 double d2 = 4*f2 - 8*g2 +8*g3 - 4*f3;
195 fLastError = kC1*hhh*fx;
196 double deriv = hhh*(4*d2 - d0)/3.;