31 : model_(
model), n_poly_basis_(
model.poly_basis_size()), n_points_(points.rows()) {
32 op_ = std::make_unique<rbf_operator<>>(
model, points);
33 res_eval_ = std::make_unique<rbf_residual_evaluator>(
model, points);
39 model_(
model), n_poly_basis_(
model.poly_basis_size()) {
40 op_ = std::make_unique<rbf_operator<>>(
model, tree_height, bbox);
41 res_eval_ = std::make_unique<rbf_residual_evaluator>(
model, tree_height, bbox);
45 n_points_ = points.rows();
47 op_->set_points(points);
48 res_eval_->set_points(points);
50 pc_ = std::make_unique<Preconditioner>(model_, points);
51 if (n_poly_basis_ > 0) {
53 p_ = poly.evaluate(points).transpose();
54 common::orthonormalize_cols(p_);
57 template <
class Derived>
58 valuesd solve(
const Eigen::MatrixBase<Derived>& values,
double absolute_tolerance,
60 RSMESH_ASSERT(values.rows() == n_points_);
62 return solve_impl(values, absolute_tolerance, max_iter);
65 template <
class Derived,
class Derived2>
66 valuesd solve(
const Eigen::MatrixBase<Derived>& values,
double absolute_tolerance,
67 int max_iter,
const Eigen::MatrixBase<Derived2>& initial_solution)
const {
68 RSMESH_ASSERT(values.rows() == n_points_);
69 RSMESH_ASSERT(initial_solution.rows() == n_points_ + n_poly_basis_);
71 valuesd ini_sol = initial_solution;
73 if (n_poly_basis_ > 0) {
75 auto n_cols = p_.cols();
76 for (index_t i = 0; i < n_cols; i++) {
77 ini_sol.head(n_points_) -= p_.col(i).dot(ini_sol.head(n_points_)) * p_.col(i);
81 return solve_impl(values, absolute_tolerance, max_iter, &ini_sol);
85 template <
class Derived,
class Derived2 = valuesd>
86 valuesd solve_impl(
const Eigen::MatrixBase<Derived>& values,
double absolute_tolerance,
88 const Eigen::MatrixBase<Derived2> *initial_solution =
nullptr)
const {
91 return valuesd::Zero(n_points_ + n_poly_basis_);
94 valuesd rhs(n_points_ + n_poly_basis_);
95 rhs.head(n_points_) = values;
96 rhs.tail(n_poly_basis_) = valuesd::Zero(n_poly_basis_);
99 if(initial_solution !=
nullptr) {
100 solver.set_initial_solution(*initial_solution);
102 solver.set_right_preconditioner(*pc_);
105 std::cout << std::setw(4) <<
"iter" << std::setw(16) <<
"rel_res" << std::endl
106 << std::setw(4) << solver.iteration_count() << std::setw(16) << std::scientific
107 << solver.relative_residual() << std::defaultfloat << std::endl;
110 solver.iterate_process();
111 solution = solver.solution_vector();
112 std::cout << std::setw(4) << solver.iteration_count() << std::setw(16) << std::scientific
113 << solver.relative_residual() << std::defaultfloat << std::endl;
115 auto convergence = res_eval_->converged(values, solution, absolute_tolerance);
116 if (convergence.first) {
117 std::cout <<
"Achieved absolute residual: " << convergence.second << std::endl;
120 if(solver.iteration_count() == solver.max_iterations()) {
121 throw std::runtime_error(
"Reached the maximum number of iterations.");
127 const index_t n_poly_basis_;
130 std::unique_ptr<rbf_operator<>> op_;
131 std::unique_ptr<Preconditioner> pc_;
132 std::unique_ptr<rbf_residual_evaluator> res_eval_;