43 #ifndef O2SCL_DERIV_GSL_H 44 #define O2SCL_DERIV_GSL_H 54 #include <gsl/gsl_deriv.h> 55 #include <gsl/gsl_errno.h> 57 #include <o2scl/deriv.h> 58 #include <o2scl/funct.h> 59 #include <o2scl/err_hnd.h> 61 #ifndef DOXYGEN_NO_O2NS 160 virtual int deriv_err(
double x, func_t &func,
double &dfdx,
double &err) {
161 return deriv_tlate<func_t>(x,func,dfdx,err);
165 virtual const char *
type() {
return "deriv_gsl"; }
167 #ifndef DOXYGEN_INTERNAL 174 double &dfdx,
double &err) {
177 if (x==0.0) hh=1.0e-4;
178 else hh=1.0e-4*fabs(x);
183 double r_0, round, trunc, error;
187 while (fail && it_count<20) {
192 if (cret!=0) fail=
true;
196 if (fail==
false && round < trunc && (round > 0 && trunc > 0)) {
197 double r_opt, round_opt, trunc_opt, error_opt;
203 h_opt=hh*pow(round/(2.0*trunc),1.0/3.0);
205 if (cret!=0) fail=
true;
206 error_opt=round_opt+trunc_opt;
211 if (fail==
false && error_opt < error &&
212 fabs (r_opt-r_0) < 4.0*error) {
222 std::cout <<
"Function deriv_gsl::deriv_tlate out of range. " 223 <<
"Decreasing step." << std::endl;
228 if (fail==
true || it_count>=20) {
230 O2SCL_ERR2(
"Failed to find finite derivative in ",
246 (
double x,
funct11 &func,
double &dfdx,
double &err) {
247 return deriv_tlate<>(x,func,dfdx,err);
260 template<
class func2_t>
262 double &abserr_round,
double &abserr_trunc,
265 double fm1, fp1, fmh, fph;
267 double eps=std::numeric_limits<double>::epsilon();
276 std::cout <<
"deriv_gsl: " << std::endl;
277 std::cout <<
"step: " << hh << std::endl;
278 std::cout <<
"abscissas: " << x-hh/2 <<
" " << x-hh <<
" " 279 << x+hh/2 <<
" " << x+hh << std::endl;
280 std::cout <<
"ordinates: " << fm1 <<
" " << fmh <<
" " << fph <<
" " 284 if (!std::isfinite(fm1) ||
285 !std::isfinite(fp1) ||
286 !std::isfinite(fmh) ||
287 !std::isfinite(fph) ||
288 (func_max>0.0 && (fabs(fm1)>func_max ||
289 fabs(fp1)>func_max ||
290 fabs(fmh)>func_max ||
291 fabs(fph)>func_max))) {
295 double r3=0.5*(fp1-fm1);
296 double r5=(4.0/3.0)*(fph-fmh)-(1.0/3.0)*r3;
298 double e3=(fabs(fp1)+fabs(fm1))*eps;
299 double e5=2.0*(fabs(fph)+fabs(fmh))*eps+e3;
303 double dy=GSL_MAX(fabs(r3/hh),fabs(r5/hh))*fabs(x/hh)*eps;
313 abserr_trunc=fabs((r5-r3)/hh);
315 abserr_round=fabs(e5/hh)+dy;
318 std::cout <<
"res: " << result <<
" trc: " << abserr_trunc
319 <<
" rnd: " << abserr_round << std::endl;
333 #ifndef DOXYGEN_NO_O2NS double h_opt
The last value of the optimized stepsize.
int central_deriv(double x, double hh, double &result, double &abserr_round, double &abserr_trunc, func2_t &func)
Compute derivative using 5-point rule.
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
std::function< double(double)> funct11
One-dimensional function typedef.
virtual int deriv_err(double x, func_t &func, double &dfdx, double &err)
Calculate the first derivative of func w.r.t. x and uncertainty.
double h
Initial stepsize.
Numerical differentiation base [abstract base].
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
bool err_nonconv
If true, call the error handler if the routine does not "converge".
double func_max
Maximum absolute value of function, or a negative value for no maximum (default -1) ...
Numerical differentiation (GSL)
virtual const char * type()
Return string denoting type ("deriv_gsl")
int verbose
Output control.
int deriv_tlate(double x, func2_t &func, double &dfdx, double &err)
Internal template version of the derivative function.
virtual int deriv_err_int(double x, funct11 &func, double &dfdx, double &err)
Internal version of calc_err() for second and third derivatives.