110 constexpr Scalar EPSILON{std::numeric_limits<Scalar>::epsilon()};
111 const Scalar diff_r{(f_r - f_c) / h}, diff_l{(f_c - f_l) / h};
112 Scalar weight_r{std::abs(diff_r) + EPSILON},
113 weight_l{std::abs(diff_l) + EPSILON};
114 const Scalar weight_max{std::max(weight_r, weight_l)};
115 weight_r = std::sqrt(weight_r / weight_max);
116 weight_l = std::sqrt(weight_l / weight_max);
120 (diff_r * weight_l + diff_l * weight_r) / (weight_r + weight_l);
123 (diff_r * weight_l + diff_l * weight_r) / (weight_r + weight_l);
182 constexpr Scalar EPSILON{std::numeric_limits<Scalar>::epsilon()};
183 const Vector diff_r((f_r - f_c) / h), diff_l((f_c - f_l) / h);
186 Vector weight_r(diff_r.array().abs() + EPSILON),
187 weight_l(diff_l.array().abs() + EPSILON);
188 const Vector weight_max(weight_r.array().max(weight_l.array()));
189 weight_r = (weight_r.array() / weight_max.array()).sqrt();
190 weight_l = (weight_l.array() / weight_max.array()).sqrt();
191 out.col(i) = (diff_r.array() * weight_l.array() +
192 diff_l.array() * weight_r.array()) /
193 (weight_r.array() + weight_l.array());
195 Scalar weight_r, weight_l, weight_max;
196 for (Eigen::Index j{0}; j < diff_r.size(); ++j) {
197 weight_r = std::abs(diff_r.coeff(j)) + EPSILON;
198 weight_l = std::abs(diff_l.coeff(j)) + EPSILON;
199 weight_max = std::max(weight_r, weight_l);
200 weight_r = std::sqrt(weight_r / weight_max);
201 weight_l = std::sqrt(weight_l / weight_max);
203 (diff_r.coeff(j) * weight_l + diff_l.coeff(j) * weight_r) /
204 (weight_r + weight_l);
224 is_invocable_r_v<bool, Function, const Vector &, Scalar &> &&
229 if (!function(x, v_c) || !std::isfinite(v_c)) {
232 Eigen::Index dim_x{x.size()};
241 for (Eigen::Index i{0}; i < dim_x; ++i) {
255 v_x.coeffRef(i) = tmp + h_1;
258 bool is_finite_r{function(v_x, v_r) && std::isfinite(v_r)};
263 v_x.coeffRef(i) = tmp - h_1;
266 bool is_finite_l{function(v_x, v_l) && std::isfinite(v_l)};
267 Eigen::Index ic{(is_finite_r && is_finite_l)
269 : (is_finite_r ? 1 : (is_finite_l ? -1 : -2))};
280 v_x.coeffRef(i) = tmp + h_2;
283 bool is_finite_rr{function(v_x, v_rr) && std::isfinite(v_rr)};
289 out(i) = (v_r - v_c) / h_1;
291 out.coeffRef(i) = (v_r - v_c) / h_1;
301 v_x.coeffRef(i) = tmp - h_2;
304 bool is_finite_ll{function(v_x, v_ll) && std::isfinite(v_ll)};
310 out(i) = (v_c - v_l) / h_1;
312 out.coeffRef(i) = (v_c - v_l) / h_1;
328 return out.allFinite();
330 for (Eigen::Index j{0}; j < out.size(); ++j) {
331 if (!std::isfinite(out.coeff(j))) {
356 is_invocable_r_v<bool, Function, const Vector &, Vector &> &&
362 if (!function(x, v_c)) {
367 if (!v_c.allFinite()) {
371 for (Eigen::Index r{0}; r < v_c.rows(); ++r) {
372 if (!std::isfinite(v_c.coeff(r))) {
377 Eigen::Index dim_x{x.size()};
380 out.resize(dim_x, dim_x);
383 out.reserve(dim_x * dim_x);
386 for (Eigen::Index j{0}; j < dim_x; ++j) {
400 v_x.coeffRef(j) = tmp + h_1;
403 bool is_finite_r{function(v_x, v_r)};
406 is_finite_r = is_finite_r && v_r.allFinite();
408 for (Eigen::Index r{0}; r < v_r.rows(); ++r) {
409 is_finite_r = is_finite_r && std::isfinite(v_r.coeff(r));
416 v_x.coeffRef(j) = tmp - h_1;
419 bool is_finite_l{function(v_x, v_l)};
422 is_finite_l = is_finite_l && v_l.allFinite();
424 for (Eigen::Index r{0}; r < v_l.rows(); ++r) {
425 is_finite_l = is_finite_l && std::isfinite(v_l.coeff(r));
428 Eigen::Index ic{(is_finite_r && is_finite_l)
430 : (is_finite_r ? 1 : (is_finite_l ? -1 : -2))};
440 v_x.coeffRef(j) = tmp + h_2;
443 bool is_finite_rr{function(v_x, v_rr)};
446 is_finite_rr = is_finite_rr && v_rr.allFinite();
448 for (Eigen::Index r{0}; r < v_rr.rows(); ++r) {
449 is_finite_rr = is_finite_rr && std::isfinite(v_rr.coeff(r));
457 out.col(j) = (v_r - v_c) / h_1;
459 for (Eigen::Index r{0}; r < v_r.rows(); ++r) {
460 out.coeffRef(r, j) = (v_r.coeff(r) - v_c.coeff(r)) / h_1;
471 v_x.coeffRef(j) = tmp - h_2;
474 bool is_finite_ll{function(v_x, v_ll)};
477 is_finite_ll = is_finite_ll && v_ll.allFinite();
479 for (Eigen::Index r{0}; r < v_ll.rows(); ++r) {
480 is_finite_ll = is_finite_ll && std::isfinite(v_ll.coeff(r));
488 out.col(j) = (v_c - v_l) / h_1;
490 for (Eigen::Index r{0}; r < v_l.rows(); ++r) {
491 out.coeffRef(r, j) = (v_c.coeff(r) - v_l.coeff(r)) / h_1;
500 out.col(j).setZero();
502 for (
typename Matrix::InnerIterator it(out, j); it; ++it) {
512 return out.allFinite();
514 for (Eigen::Index r{0}; r < out.rows(); ++r) {
515 for (Eigen::Index c{0}; c < out.cols(); ++c) {
516 if (!std::isfinite(out.coeff(r, c))) {
542 is_invocable_r_v<bool, Function, const Vector &, Scalar &> &&
547 Eigen::Index dim_x{x.size()};
550 out.resize(dim_x, dim_x);
553 out.reserve(dim_x * dim_x);
557 if (!function(x, fc) || !std::isfinite(fc)) {
560 for (Eigen::Index j{0}; j < dim_x; ++j) {
572 v_x(j) = tmp_j + h_j;
574 v_x.coeffRef(j) = tmp_j + h_j;
577 if (!function(v_x, fp) || !std::isfinite(fp)) {
582 v_x(j) = tmp_j - h_j;
584 v_x.coeffRef(j) = tmp_j - h_j;
587 if (!function(v_x, fm) || !std::isfinite(fm)) {
592 out(j, j) = ((fp + fm) - 2.0 * fc) / (h_j * h_j);
594 out.coeffRef(j, j) = ((fp + fm) - 2.0 * fc) / (h_j * h_j);
596 for (Eigen::Index i{j + 1}; i < dim_x; ++i) {
607 v_x(i) = tmp_i + h_i;
608 v_x(j) = tmp_j + h_j;
610 v_x.coeffRef(i) = tmp_i + h_i;
611 v_x.coeffRef(j) = tmp_j + h_j;
614 if (!function(v_x, fpp) || !std::isfinite(fpp)) {
619 v_x(i) = tmp_i - h_i;
621 v_x.coeffRef(i) = tmp_i - h_i;
624 if (!function(v_x, fmp) || !std::isfinite(fmp)) {
629 v_x(j) = tmp_j - h_j;
631 v_x.coeffRef(j) = tmp_j - h_j;
634 if (!function(v_x, fmm) || !std::isfinite(fmm)) {
639 v_x(i) = tmp_i + h_i;
641 v_x.coeffRef(i) = tmp_i + h_i;
644 if (!function(v_x, fpm) || !std::isfinite(fpm)) {
647 Scalar h_ij{4.0 * h_i * h_j},
648 value{((fpp + fmm) - (fpm + fmp)) / h_ij};
651 out(j, i) = out(i, j) = value;
654 out.coeffRef(j, i) = out.coeffRef(i, j) = value;
655 v_x.coeffRef(i) = tmp_i;
662 v_x.coeffRef(j) = tmp_j;
667 return out.allFinite();
669 for (Eigen::Index r{0}; r < out.rows(); ++r) {
670 for (Eigen::Index c{0}; c < out.cols(); ++c) {
671 if (!std::isfinite(out.coeff(r, c))) {