20 #include <Eigen/Dense>
38 static constexpr
double EPS = 1e-13;
41 EIGEN_DEVICE_FUNC
bool is_converged(
const Eigen::Matrix<double, N, 1>& X,
42 const Eigen::Matrix<double, N, N>& J,
43 const Eigen::Matrix<double, N, 1>& F,
45 bool converged =
true;
46 double square_eps = eps * eps;
47 for (Eigen::Index i = 0; i < N; ++i) {
48 double square_error = 0.0;
49 for (Eigen::Index j = 0; j < N; ++j) {
50 double JX = J(i, j) * X(j);
51 square_error += JX * JX;
54 if (F(i) * F(i) > square_eps * square_error) {
79 template <
int N,
typename FUNC>
85 Eigen::Matrix<double, N, 1> dX;
87 Eigen::Matrix<double, N, 1> F;
89 Eigen::Matrix<double, N, N> J;
92 while (++iter < max_iter) {
103 J.transposeInPlace();
105 Eigen::Matrix<int, N, 1> pivot;
106 Eigen::Matrix<double, N, 1> rowmax;
108 if (nmodl::crout::Crout<double>(N, J.data(), pivot.data(), rowmax.data()) < 0) {
111 Eigen::Matrix<double, N, 1> X_solve;
112 nmodl::crout::solveCrout<double>(N, J.data(), F.data(), X_solve.data(), pivot.data());
125 template <
typename FUNC,
int N>
131 Eigen::Matrix<double, N, 1> F;
132 Eigen::Matrix<double, N, 1> dX;
133 Eigen::Matrix<double, N, N> J, J_inv;
135 while (++iter < max_iter) {
136 functor(X, dX, F, J);
142 J.computeInverseWithCheck(J_inv, invertible);
152 template <
typename FUNC>
157 return newton_solver_small_N<FUNC, 1>(X, functor, eps, max_iter);
160 template <
typename FUNC>
165 return newton_solver_small_N<FUNC, 2>(X, functor, eps, max_iter);
168 template <
typename FUNC>
173 return newton_solver_small_N<FUNC, 3>(X, functor, eps, max_iter);
176 template <
typename FUNC>
181 return newton_solver_small_N<FUNC, 4>(X, functor, eps, max_iter);