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_f_1{f_1 - f_0};
60 Real d_f_2{f_2 - f_0};
62 return ((h_1/h_2)*d_f_2 - (h_2/h_1)*d_f_1) / d_h;
74 template<
typename Real>
77 constexpr Real EPSILON{std::numeric_limits<Real>::epsilon()};
78 Real diff_r{(f_r-f_c)/h};
79 Real diff_l{(f_c-f_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);
99 template<
typename Vector,
typename Real =
typename Vector::Scalar>
101 Vector
const & f_2, Real h_1, Real h_2)
103 Real d_h{h_1-h_2}, t_1{-(h_2/h_1)/d_h}, t_2{(h_1/h_2)/d_h};
104 return t_1*(f_1-f_0) + t_2*(f_2-f_0);
117 template<
typename Vector,
typename Real =
typename Vector::Scalar>
121 constexpr Real EPSILON{std::numeric_limits<Real>::epsilon()};
122 Vector diff_r((f_r - f_c) / h);
123 Vector diff_l((f_c - f_l) / h);
124 Vector weight_r(diff_r.array().abs() + EPSILON);
125 Vector weight_l(diff_l.array().abs() + EPSILON);
126 Vector weight_max(weight_r.array().max(weight_l.array()));
127 weight_r = (weight_r.array()/weight_max.array()).sqrt();
128 weight_l = (weight_l.array()/weight_max.array()).sqrt();
129 return (diff_r.array()*weight_l.array() + diff_l.array()*weight_r.array()) / (weight_r.array()+weight_l.array());
142 template <
typename Function,
typename Vector,
typename Real =
typename Vector::Scalar>
147 if (!function(x, v_c) || !std::isfinite(v_c)) {
return false;}
148 Eigen::Index dim_x{x.size()};
151 for (Eigen::Index i{0}; i < dim_x; ++i) {
154 v_x[i] = tmp + h_1; Real v_r{0.0};
bool is_finite_r{function(v_x, v_r) && std::isfinite(v_r)};
155 v_x[i] = tmp - h_1; Real v_l{0.0};
bool is_finite_l{function(v_x, v_l) && std::isfinite(v_l)};
156 Integer ic{(is_finite_r && is_finite_l) ? 0 : (is_finite_r ? 1 : (is_finite_l ? -1 : -2))};
162 v_x[i] = tmp + h_2; Real v_rr{0.0};
bool is_finite_rr{function(v_x, v_rr) && std::isfinite(v_rr)};
167 v_x[i] = tmp - h_2; Real v_ll{0.0};
bool is_finite_ll{function(v_x, v_ll) && std::isfinite(v_ll)};
177 return out.allFinite();
191 template <
typename Function,
typename Vector,
typename Matrix,
typename Real =
typename Vector::Scalar>
196 if (!function(x, v_c) || !v_c.allFinite()) {
return false;}
197 Eigen::Index dim_x{x.size()};
198 out.resize(dim_x, dim_x);
200 for (Eigen::Index j{0}; j < dim_x; ++j) {
203 v_x[j] = tmp + h_1; Vector v_r;
bool is_finite_r{function(v_x, v_r) && v_r.allFinite()};
204 v_x[j] = tmp - h_1; Vector v_l;
bool is_finite_l{function(v_x, v_l) && v_l.allFinite()};
205 Integer ic{(is_finite_r && is_finite_l) ? 0 : (is_finite_r ? 1 : (is_finite_l ? -1 : -2))};
211 v_x[j] = tmp + h_2; Vector v_rr;
bool is_finite_rr{function(v_x, v_rr) && v_rr.allFinite()};
216 v_x[j] = tmp - h_2; Vector v_ll;
bool is_finite_ll{function(v_x, v_ll) && v_ll.allFinite()};
221 out.col(j).setZero();
226 return out.allFinite();
240 template <
typename Function,
typename Vector,
typename Matrix,
typename Real =
typename Vector::Scalar>
244 Eigen::Index dim_x{x.size()};
245 out.resize(dim_x, dim_x);
248 if (!function(x, fc) || !std::isfinite(fc)) {
return false;}
249 for (Eigen::Index j{0}; j < dim_x; ++j) {
250 Real tmp_j{x[j]}, h_j{eps.
epsilon_3(tmp_j)};
252 v_x[j] = tmp_j + h_j; Real fp;
if (!function(v_x, fp) || !std::isfinite(fp)) {
return false;}
253 v_x[j] = tmp_j - h_j; Real fm;
if (!function(v_x, fm) || !std::isfinite(fm)) {
return false;}
254 out(j, j) = ((fp + fm) - 2.0 * fc) / (h_j * h_j);
255 for (Eigen::Index i{j + 1}; i < dim_x; ++i) {
256 Real tmp_i{x[i]}, h_i{eps.
epsilon_3(tmp_i)};
257 v_x[i] = tmp_i + h_i;
258 v_x[j] = tmp_j + h_j; Real fpp;
if (!function(v_x, fpp) || !std::isfinite(fpp)) {
return false;}
259 v_x[i] = tmp_i - h_i; Real fmp;
if (!function(v_x, fmp) || !std::isfinite(fmp)) {
return false;}
260 v_x[j] = tmp_j - h_j; Real fmm;
if (!function(v_x, fmm) || !std::isfinite(fmm)) {
return false;}
261 v_x[i] = tmp_i + h_i; Real fpm;
if (!function(v_x, fpm) || !std::isfinite(fpm)) {
return false;}
262 Real h_ij{4.0 * h_i * h_j}, value{((fpp + fmm) - (fpm + fmp)) / h_ij};
263 out(j, i) = out(i, j) = value;
268 return out.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:190
Definition FiniteDifferences.hh:20
bool Gradient(Vector const &x, Function &&function, Vector &out)
Definition FiniteDifferences.hh:143
Real SideFiniteDifferences(Real const f_0, Real const f_1, Real const f_2, Real h_1, Real h_2)
Definition FiniteDifferences.hh:56
bool Jacobian(Vector const &x, Function &&function, Matrix &out)
Definition FiniteDifferences.hh:192
bool Hessian(Vector const &x, Function &&function, Matrix &out)
Definition FiniteDifferences.hh:241
Real CenteredFiniteDifferences(Real const f_l, Real const f_c, Real const f_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