#pragma once #include Eigen::SparseMatrix projectionMatrix(const std::vector& fixedIdx, int size); Eigen::SparseMatrix buildHGN(const Eigen::VectorXd& masses, const Eigen::SparseMatrix& P, const Eigen::SparseMatrix& M_theta, const Eigen::SparseMatrix& H); void updateHGN(Eigen::SparseMatrix& HGN, const Eigen::SparseMatrix& P, const Eigen::SparseMatrix& H); const auto nullexpr = [](double) {}; template double lineSearch(const Eigen::VectorXd& x0, const Eigen::VectorXd& d, const double f, const Eigen::VectorXd& g, const Func& eval, // Callable of type T(const Eigen::Vector&) const Callback& callback = nullexpr, const double shrink = 0.8, const int max_iters = 64) { Eigen::VectorXd x_new = x0; double s = 1.0; for(int i = 0; i < max_iters; ++i) { x_new = x0 + s * d; callback(s); const double f_new = eval(x_new); if(f_new <= f + 1e-4 * s * d.dot(g)) // Armijo condition return s; s *= shrink; } // line search couldn't find improvement return -1; } std::vector findCenterFaceIndices(const Eigen::MatrixXd& P, const Eigen::MatrixXi& F);