13#ifndef OPTIMIST_FINITE_DIFFERENCES_HH
14#define OPTIMIST_FINITE_DIFFERENCES_HH
26 template<
typename Real>
38 Real
epsilon_2(Real
const v)
const {
return (std::abs(v) + 1.0)*this->m_epsilon_2;}
41 Real
epsilon_3(Real
const v)
const {
return (std::abs(v) + 1.0)*this->m_epsilon_3;}
55 template<
typename Real>
59 Real d_fun_1{fun_1 - fun_0};
60 Real d_fun_2{fun_2 - fun_0};
62 return ((h_1/h_2)*d_fun_2 - (h_2/h_1)*d_fun_1) / d_h;
74 template<
typename Real>
77 constexpr Real EPSILON{std::numeric_limits<Real>::epsilon()};
78 Real diff_r{(fun_r-fun_c)/h};
79 Real diff_l{(fun_c-fun_l)/h};
80 Real weight_r{std::abs(diff_r) + EPSILON};
81 Real weight_l{std::abs(diff_l) + EPSILON};
82 Real weight_max{std::max(weight_r, weight_l)};
83 weight_r = std::sqrt(weight_r/weight_max);
84 weight_l = std::sqrt(weight_l/weight_max);
85 return (diff_r*weight_l + diff_l*weight_r) / (weight_r+weight_l);
98 template<
typename Real>
99 using VectorXd = Eigen::Vector<Real, Eigen::Dynamic>;
102 template<
typename Real>
103 using MatrixXd = Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic>;
115 template<
typename Real>
120 Real t_1{-(h_2/h_1) / d_h};
121 Real t_2{(h_1/h_2) / d_h};
122 return t_1*(fun_1 - fun_0) + t_2*(fun_2 - fun_0);
134 template<
typename Real>
138 constexpr Real EPSILON{std::numeric_limits<Real>::epsilon()};
143 VectorXd<Real> weight_max(weight_r.array().max(weight_l.array()));
144 weight_r = (weight_r.array()/weight_max.array()).sqrt();
145 weight_l = (weight_l.array()/weight_max.array()).sqrt();
146 return (diff_r.array()*weight_l.array() + diff_l.array()*weight_r.array()) / (weight_r.array()+weight_l.array());
158 template <
typename Function,
typename Real>
163 if (!fun(x, v_c) || !std::isfinite(v_c)) {
return false;}
164 grad.resize(x.size());
165 for (
Integer i{0}; i < x.size(); ++i) {
170 v_x[i] = tmp + h_1; Real v_r{0.0};
bool is_finite_r{fun(v_x, v_r) && std::isfinite(v_r)};
171 v_x[i] = tmp - h_1; Real v_l{0.0};
bool is_finite_l{fun(v_x, v_l) && std::isfinite(v_l)};
172 Integer ic{(is_finite_r && is_finite_l) ? 0 : (is_finite_r ? 1 : (is_finite_l ? -1 : -2))};
178 v_x[i] = tmp + h_2; Real v_rr{0.0};
bool is_finite_rr{fun(v_x, v_rr) && std::isfinite(v_rr)};
183 v_x[i] = tmp - h_2; Real v_ll{0.0};
bool is_finite_ll{fun(v_x, v_ll) && std::isfinite(v_ll)};
193 return grad.allFinite();
205 template <
typename Function,
typename Real>
210 if (!fun(x, v_c) || !v_c.allFinite()) {
return false;}
213 jac.resize(dim_f, dim_x);
214 for (
Integer j{0}; j < dim_x; ++j) {
219 v_x[j] = tmp + h_1;
VectorXd<Real> v_r;
bool is_finite_r{fun(v_x, v_r) && v_r.allFinite()};
220 v_x[j] = tmp - h_1;
VectorXd<Real> v_l;
bool is_finite_l{fun(v_x, v_l) && v_l.allFinite()};
221 Integer ic{(is_finite_r && is_finite_l) ? 0 : (is_finite_r ? 1 : (is_finite_l ? -1 : -2))};
227 v_x[j] = tmp + h_2;
VectorXd<Real> v_rr;
bool is_finite_rr{fun(v_x, v_rr) && v_rr.allFinite()};
232 v_x[j] = tmp - h_2;
VectorXd<Real> v_ll;
bool is_finite_ll{fun(v_x, v_ll) && v_ll.allFinite()};
237 jac.col(j).setZero();
242 return jac.allFinite();
254 template <
typename Function,
typename Real>
259 hes.resize(dim_x, dim_x);
261 if (!fun(x, fc) || !std::isfinite(fc)) {
return false;}
262 for (
Integer j{0}; j < dim_x; ++j) {
266 v_x[j] = tmp_j + h_j; Real fp{0.0};
if (!fun(v_x, fp) || !std::isfinite(fp)) {
return false;}
267 v_x[j] = tmp_j - h_j; Real fm{0.0};
if (!fun(v_x, fm) || !std::isfinite(fm)) {
return false;}
268 hes(j, j) = ((fp + fm) - 2.0 * fc) / (h_j * h_j);
269 for (
Integer i{j + 1}; i < dim_x; ++i) {
272 v_x[i] = tmp_i + h_i; v_x[j] = tmp_j + h_j; Real fpp{0.0};
if (!fun(v_x, fpp) || !std::isfinite(fpp)) {
return false;}
273 v_x[i] = tmp_i - h_i; Real fmp{0.0};
if (!fun(v_x, fmp) || !std::isfinite(fmp)) {
return false;}
274 v_x[j] = tmp_j - h_j; Real fmm{0.0};
if (!fun(v_x, fmm) || !std::isfinite(fmm)) {
return false;}
275 v_x[i] = tmp_i + h_i; Real fpm{0.0};
if (!fun(v_x, fpm) || !std::isfinite(fpm)) {
return false;}
276 Real h_ij{4.0 * h_i * h_j};
277 Real value{((fpp + fmm) - (fpm + fmp)) / h_ij};
278 hes(j, i) = hes(i, j) = value;
283 return hes.allFinite();
305 template<
typename Vector>
307 Vector
const & fun_2,
typename Vector::Scalar h_1,
typename Vector::Scalar h_2)
309 using Real =
typename Vector::Scalar;
311 Real t_1{-(h_2/h_1) / d_h};
312 Real t_2{(h_1/h_2) / d_h};
313 return t_1*(fun_1 - fun_0) + t_2*(fun_2 - fun_0);
325 template<
typename Vector>
327 typename Vector::Scalar h)
329 using Real =
typename Vector::Scalar;
330 constexpr Real EPSILON{std::numeric_limits<Real>::epsilon()};
331 Vector diff_r((fun_r - fun_c) / h);
332 Vector diff_l((fun_c - fun_l) / h);
333 Vector weight_r(diff_r.array().abs() + EPSILON);
334 Vector weight_l(diff_l.array().abs() + EPSILON);
335 Vector weight_max(weight_r.array().max(weight_l.array()));
336 weight_r = (weight_r.array()/weight_max.array()).sqrt();
337 weight_l = (weight_l.array()/weight_max.array()).sqrt();
338 return (diff_r.array()*weight_l.array() + diff_l.array()*weight_r.array()) / (weight_r.array()+weight_l.array());
350 template <
typename Function,
typename Vector>
353 using Real =
typename Vector::Scalar;
356 if (!fun(x, v_c) || !std::isfinite(v_c)) {
return false;}
357 constexpr Integer dim_x{Vector::RowsAtCompileTime};
359 for (
Integer i = 0; i < dim_x; ++i) {
364 v_x(i) = tmp + h_1; Real v_r{0.0};
bool is_finite_r = fun(v_x, v_r) && std::isfinite(v_r);
365 v_x(i) = tmp - h_1; Real v_l{0.0};
bool is_finite_l = fun(v_x, v_l) && std::isfinite(v_l);
366 Integer ic{(is_finite_r && is_finite_l) ? 0 : (is_finite_r ? 1 : (is_finite_l ? -1 : -2))};
372 v_x(i) = tmp + h_2; Real v_rr{0.0};
bool is_finite_rr = fun(v_x, v_rr) && std::isfinite(v_rr);
377 v_x(i) = tmp - h_2; Real v_ll{0.0};
bool is_finite_ll = fun(v_x, v_ll) && std::isfinite(v_ll);
387 return grad.allFinite();
400 template <
typename Function,
typename Vector,
typename Matrix>
403 using Real =
typename Vector::Scalar;
406 if (!fun(x, v_c) || !v_c.allFinite()) {
return false;}
407 constexpr Integer dim_x{Vector::RowsAtCompileTime};
409 for (
Integer j{0}; j < dim_x; ++j) {
414 v_x(j) = tmp + h_1; Vector v_r;
bool is_finite_r = fun(v_x, v_r) && v_r.allFinite();
415 v_x(j) = tmp - h_1; Vector v_l;
bool is_finite_l = fun(v_x, v_l) && v_l.allFinite();
416 Integer ic{(is_finite_r && is_finite_l) ? 0 : (is_finite_r ? 1 : (is_finite_l ? -1 : -2))};
422 v_x(j) = tmp + h_2; Vector v_rr;
bool is_finite_rr = fun(v_x, v_rr) && v_rr.allFinite();
427 v_x(j) = tmp - h_2; Vector v_ll;
bool is_finite_ll = fun(v_x, v_ll) && v_ll.allFinite();
432 jac.col(j).setZero();
437 return jac.allFinite();
450 template <
typename Function,
typename Vector,
typename Matrix>
453 using Real =
typename Vector::Scalar;
455 constexpr Integer dim_x = Vector::RowsAtCompileTime;
458 if (!fun(x, fc) || !std::isfinite(fc)) {
return false;}
459 for (
Integer j{0}; j < dim_x; ++j) {
463 v_x(j) = tmp_j + h_j; Real fp{0.0};
if (!fun(v_x, fp) || !std::isfinite(fp)) {
return false;}
464 v_x(j) = tmp_j - h_j; Real fm{0.0};
if (!fun(v_x, fm) || !std::isfinite(fm)) {
return false;}
465 hes(j, j) = ((fp + fm) - 2.0 * fc) / (h_j * h_j);
466 for (
Integer i{j + 1}; i < dim_x; ++i) {
469 v_x(i) = tmp_i + h_i; v_x(j) = tmp_j + h_j; Real fpp{0.0};
if (!fun(v_x, fpp) || !std::isfinite(fpp)) {
return false;}
470 v_x(i) = tmp_i - h_i; Real fmp{0.0};
if (!fun(v_x, fmp) || !std::isfinite(fmp)) {
return false;}
471 v_x(j) = tmp_j - h_j; Real fmm{0.0};
if (!fun(v_x, fmm) || !std::isfinite(fmm)) {
return false;}
472 v_x(i) = tmp_i + h_i; Real fpm{0.0};
if (!fun(v_x, fpm) || !std::isfinite(fpm)) {
return false;}
473 Real h_ij{4.0 * h_i * h_j};
474 Real value{((fpp + fmm) - (fpm + fmp)) / h_ij};
475 hes(j, i) = hes(i, j) = value;
480 return hes.allFinite();
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:71
Definition FiniteDifferences.hh:27
Real m_epsilon_3
Definition FiniteDifferences.hh:31
Real m_epsilon_1
Definition FiniteDifferences.hh:29
Real epsilon_3(Real const v) const
Definition FiniteDifferences.hh:41
Real epsilon_2(Real const v) const
Definition FiniteDifferences.hh:38
Real m_epsilon_2
Definition FiniteDifferences.hh:30
Real epsilon_1(Real const v) const
Definition FiniteDifferences.hh:35
Class container for the vector-valued function.
Definition Function.hh:184
Definition FiniteDifferences.hh:20
bool Gradient(VectorXd< Real > const &x, Function fun, VectorXd< Real > &grad)
Definition FiniteDifferences.hh:159
Eigen::Vector< Real, Eigen::Dynamic > VectorXd
Definition FiniteDifferences.hh:99
bool Hessian(VectorXd< Real > const &x, Function fun, MatrixXd< Real > &hes)
Definition FiniteDifferences.hh:255
Real SideFiniteDifferences(Real const fun_0, Real const fun_1, Real const fun_2, Real h_1, Real h_2)
Definition FiniteDifferences.hh:56
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > MatrixXd
Definition FiniteDifferences.hh:103
bool Jacobian(VectorXd< Real > const &x, Function fun, MatrixXd< Real > &jac)
Definition FiniteDifferences.hh:206
Real CenteredFiniteDifferences(Real const fun_l, Real const fun_c, Real const fun_r, Real h)
Definition FiniteDifferences.hh:75
Namespace for the Optimist library.
Definition Optimist.hh:88
OPTIMIST_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Optimist.hh:96