1#ifndef CHEMMISOL_NEWTON_H
2#define CHEMMISOL_NEWTON_H
59 template<
typename X,
typename M, X (&G)(const X&)=
identity>
62 std::function<
X(
const X&)> f;
63 std::function<
M(
const X&)> df;
65 X solve_eps(
const X& x,
const X& f_x,
float epsilon,
66 X x_min,
X f_x_min,
double n_f_x_min)
const;
67 X solve_iter(
const X& x,
const X& f_x, std::size_t n,
68 X x_min,
X f_x_min,
double n_f_x_min)
const;
82 std::function<
X(
const X&)> f,
83 std::function<
M(
const X&)> df)
84 : x0(x0), f(f), df(df) {
97 X solve_eps(
float epsilon)
const;
107 X solve_iter(std::size_t n)
const;
110 template<
typename X,
typename M, X (&G)(const X&)>
113 return solve_eps(x0, f(x0), epsilon, x0, f_x0,
norm(f_x0));
116 template<
typename X,
typename M, X (&G)(const X&)>
119 return solve_iter(x0, f_x0, n, x0, f_x0,
norm(f_x0));
123 template<
typename X,
typename M, X (&G)(const X&)>
125 X x_min,
X f_x_min,
double n_f_x_min)
const {
126 CHEM_LOG(TRACE) <<
"[NEWTON] Current X: " << x;
127 CHEM_LOG(TRACE) <<
"[NEWTON] Current F(X): " << f_x;
128 CHEM_LOG(TRACE) <<
"[NEWTON] (e=" << epsilon <<
") Epsilon: " <<
norm(f_x);
129 if(
norm(f_x) < epsilon)
131 X _x = gauss::solve(df(x), -f_x);
133 auto n_f_x =
norm(f_x);
134 if (n_f_x < n_f_x_min)
135 return solve_eps(x1, f(x1), epsilon, x1, f_x, n_f_x);
136 if (n_f_x == n_f_x_min) {
140 CHEM_LOG(TRACE) <<
"[NEWTON] Cycle detected, returns current optimum (X: " << x_min
141 <<
", f(X): " << f_x_min <<
".";
145 return solve_eps(x1, f(x1), epsilon, x_min, f_x_min, n_f_x_min);
148 template<
typename X,
typename M, X (&G)(const X&)>
149 X Newton<X, M, G>::solve_iter(
150 const X& x,
const X& f_x, std::size_t n,
151 X x_min,
X f_x_min,
double n_f_x_min)
const {
152 CHEM_LOG(TRACE) <<
"[NEWTON] Current X: " << x;
153 CHEM_LOG(TRACE) <<
"[NEWTON] Current F(X): " << f_x;
154 CHEM_LOG(TRACE) <<
"[NEWTON] (n=" << n <<
") Epsilon: " <<
norm(f_x);
155 if(n == 0 ||
norm(f_x) ==
typename X::value_type(0))
157 X _x = gauss::solve(df(x), -f_x);
159 auto n_f_x =
norm(f_x);
160 if (n_f_x < n_f_x_min)
161 return solve_iter(x1, f(x1), n-1, x1, f_x, n_f_x);
162 if (n_f_x == n_f_x_min) {
166 CHEM_LOG(TRACE) <<
"[NEWTON] Cycle detected at n=" << n
167 <<
", returns current optimum (X: " << x_min
168 <<
", f(X): " << f_x_min <<
".";
172 return solve_iter(x1, f(x1), n-1, x_min, f_x_min, n_f_x_min);
194 template<
typename X,
typename M>
Newton(const X &x0, std::function< X(const X &)> f, std::function< M(const X &)> df)
Definition newton.h:80
#define CHEM_LOG(LEVEL)
Definition logging.h:21
Definition chemmisol.h:31
double norm(const X< T, N > &x)
Definition linear.h:117
std::array< T, N > X
Definition linear.h:26
T identity(const T &x)
Definition newton.h:22
std::array< std::array< T, P >, N > M
Definition linear.h:34