chemmisol 0.1
Loading...
Searching...
No Matches
newton.h
Go to the documentation of this file.
1#ifndef CHEMMISOL_NEWTON_H
2#define CHEMMISOL_NEWTON_H
3
4#include <functional>
5#include <cmath>
6#include "linear.h"
7#include "gauss.h"
8
16namespace chemmisol {
17
21 template<typename T>
22 T identity(const T& x) {
23 return x;
24 }
25
59 template<typename X, typename M, X (&G)(const X&)=identity>
60 class Newton {
61 X x0;
62 std::function<X(const X&)> f;
63 std::function<M(const X&)> df;
64
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;
69
70 public:
81 const X& x0,
82 std::function<X(const X&)> f,
83 std::function<M(const X&)> df)
84 : x0(x0), f(f), df(df) {
85 }
86
97 X solve_eps(float epsilon) const;
98
107 X solve_iter(std::size_t n) const;
108 };
109
110 template<typename X, typename M, X (&G)(const X&)>
111 X Newton<X, M, G>::solve_eps(float epsilon) const {
112 auto f_x0 = f(x0);
113 return solve_eps(x0, f(x0), epsilon, x0, f_x0, norm(f_x0));
114 }
115
116 template<typename X, typename M, X (&G)(const X&)>
117 X Newton<X, M, G>::solve_iter(std::size_t n) const {
118 auto f_x0 = f(x0);
119 return solve_iter(x0, f_x0, n, x0, f_x0, norm(f_x0));
120 }
121
122
123 template<typename X, typename M, X (&G)(const X&)>
124 X Newton<X, M, G>::solve_eps(const X& x, const X& f_x, float epsilon,
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)
130 return x;
131 X _x = gauss::solve(df(x), -f_x);
132 X x1 = G(_x + 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) {
137 // Maybe we are in a cycle
138 if(x_min == x1) {
139 // We are in a cycle, break the algorithm
140 CHEM_LOG(TRACE) << "[NEWTON] Cycle detected, returns current optimum (X: " << x_min
141 << ", f(X): " << f_x_min << ".";
142 return x_min;
143 }
144 }
145 return solve_eps(x1, f(x1), epsilon, x_min, f_x_min, n_f_x_min);
146 }
147
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))
156 return x;
157 X _x = gauss::solve(df(x), -f_x);
158 X x1 = G(_x + 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) {
163 // Maybe we are in a cycle
164 if(x_min == x1) {
165 // We are in a cycle, break the algorithm
166 CHEM_LOG(TRACE) << "[NEWTON] Cycle detected at n=" << n
167 << ", returns current optimum (X: " << x_min
168 << ", f(X): " << f_x_min << ".";
169 return x_min;
170 }
171 }
172 return solve_iter(x1, f(x1), n-1, x_min, f_x_min, n_f_x_min);
173 }
174
194 template<typename X, typename M>
196}
197#endif
Definition newton.h:60
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