1 #ifndef TOON_INCLUDE_DERIVATIVES_NUMERICAL_H
2 #define TOON_INCLUDE_DERIVATIVES_NUMERICAL_H
24 const Precision c = 1.1, t = 2;
26 static const int Npts = 400;
69 vector<Precision> P_i(1), P_i_1;
71 Precision best_err = HUGE_VAL;
72 Precision best_point=HUGE_VAL;
80 for(
int i=0; i < Npts; i++)
96 for(
int j=1; j <= i; j++)
103 P_i[j] = (cj * P_i[j-1] - P_i_1[j-1]) / (cj - 1);
110 Precision err1 =
abs(P_i[j] - P_i[j-1]);
114 Precision err2 =
abs(P_i[j] - P_i_1[j-1]);
117 Precision err = max(err1, err2);
130 if(ever_ok && !better && i > 0 && (
abs(P_i[i] - P_i_1[i-1]) > t * best_err||
isnan(P_i[i])))
134 return std::make_pair(best_point, best_err);
148 :v(v_),x(v),f(f_),i(0)
158 double h = hh * max(
abs(v[i]) * 1e-3, 1e-3);
166 double d = (f2 - f1) / (2*h);
183 :v(v_),x(v),f(f_),i(0),central(f(x))
193 double h = hh * max(
abs(v[i]) * 1e-3, 1e-3);
202 double d = (f2 - 2*central + f1) / (h*h);
219 :v(v_),x(v),f(f_),i(0),j(0)
229 double h = hh * max(
abs(v[i]) * 1e-3, 1e-3);
248 return (a-b-c+d) / (4*h*h);
328 using namespace Internal;
331 CentralDifferenceGradient<F, P, S, B> d(x, f);
333 for(
int i=0; i < x.size(); i++)
336 grad[i] = extrapolate_to_zero<CentralDifferenceGradient<F, P, S, B>, P>(d).first;
352 using namespace Internal;
355 CentralDifferenceGradient<F, P, S, B> d(x, f);
357 for(
int i=0; i < x.size(); i++)
360 pair<double, double> r= extrapolate_to_zero<CentralDifferenceGradient<F, P, S, B>, P>(d);
380 template<
class F,
int S,
class P,
class B> pair<Matrix<S, S, P>,
Matrix<S, S, P> >
numerical_hessian_with_errors(
const F& f,
const Vector<S, P, B>& x)
382 using namespace Internal;
386 CentralDifferenceSecond<F, P, S, B> curv(x, f);
387 CentralCrossDifferenceSecond<F, P, S, B> cross(x, f);
391 for(
int r=0; r < x.size(); r++)
392 for(
int c=r+1; c < x.size(); c++)
396 pair<double, double> e = extrapolate_to_zero<CentralCrossDifferenceSecond<F, P, S, B>, P >(cross);
397 hess[r][c] = hess[c][r] = e.first;
398 errors[r][c] = errors[c][r] = e.second;
401 for(
int i=0; i < x.size(); i++)
404 pair<double, double> e = extrapolate_to_zero<CentralDifferenceSecond<F, P, S, B>, P>(curv);
405 hess[i][i] = e.first;
406 errors[i][i] = e.second;
409 return make_pair(hess, errors);
420 using namespace Internal;
423 CentralDifferenceSecond<F, P, S, B> curv(x, f);
424 CentralCrossDifferenceSecond<F, P, S, B> cross(x, f);
427 for(
int r=0; r < x.size(); r++)
428 for(
int c=r+1; c < x.size(); c++)
432 pair<double, double> e = extrapolate_to_zero<CentralCrossDifferenceSecond<F, P, S, B>, P >(cross);
433 hess[r][c] = hess[c][r] = e.first;
436 for(
int i=0; i < x.size(); i++)
439 pair<double, double> e = extrapolate_to_zero<CentralDifferenceSecond<F, P, S, B>, P>(curv);
440 hess[i][i] = e.first;
Vector< Size, Precision > x
Local copy of v.
std::pair< Precision, Precision > extrapolate_to_zero(F &f)
int i
Index to difference along.
const Functor & f
Functor to evaluate.
Everything lives inside this namespace.
CentralDifferenceGradient(const Vector< Size, Precision, Base > &v_, const Functor &f_)
bool isfinite(const Vector< S, P, B > &v)
Precision operator()(Precision hh)
Compute central difference.
CentralCrossDifferenceSecond(const Vector< Size, Precision, Base > &v_, const Functor &f_)
const Vector< Size, Precision, Base > & v
Point about which to compute differences.
Vector< S, P > numerical_gradient(const F &f, const Vector< S, P, B > &x)
Precision operator()(Precision hh)
Compute central difference.
Precision operator()(Precision hh)
Compute central difference.
Matrix< S, S, P > numerical_hessian(const F &f, const Vector< S, P, B > &x)
Vector< Size, Precision > x
Local copy of v.
const Vector< Size, Precision, Base > & v
Point about which to compute differences.
int i
Index to difference along.
int j
Index to difference along.
pair< Matrix< S, S, P >, Matrix< S, S, P > > numerical_hessian_with_errors(const F &f, const Vector< S, P, B > &x)
CentralDifferenceSecond(const Vector< Size, Precision, Base > &v_, const Functor &f_)
const Functor & f
Functor to evaluate.
int i
Index to difference along.
const Precision central
Central point.
const Vector< Size, Precision, Base > & v
Point about which to compute differences.
Vector< Size, Precision > x
Local copy of v.
Matrix< S, 2, P > numerical_gradient_with_errors(const F &f, const Vector< S, P, B > &x)
const Functor & f
Functor to evaluate.
bool isnan(const Vector< S, P, B > &v)