4 double x_min,
double x_max,
8 if (!(x_min < x_max))
throw std::invalid_argument(
"x_min < x_max required");
9 std::vector<double> xs;
10 xs.reserve(n_samples+1);
11 for (
int i = 0; i <= n_samples; ++i) {
12 double t = double(i) / double(n_samples);
13 xs.push_back(x_min + t * (x_max - x_min));
15 double fa =
f(xs.front());
16 if (!std::isfinite(fa))
return false;
17 if (std::fabs(fa) == 0.0) { a = b = xs.front();
return true; }
18 for (
size_t i = 1; i < xs.size(); ++i) {
20 if (!std::isfinite(fb))
return false;
21 if (fb == 0.0) { a = b = xs[i];
return true; }
22 if (fa * fb < 0.0) { a = xs[i-1]; b = xs[i];
return true; }
36 if (!std::isfinite(fa) || !std::isfinite(fb))
37 throw std::runtime_error(
"Function not finite at bracket endpoints.");
38 if (fa == 0.0)
return a;
39 if (fb == 0.0)
return b;
41 throw std::invalid_argument(
"Root is not bracketed (f(a) and f(b) must have opposite signs).");
48 for (
int iter = 0; iter < max_it; ++iter) {
49 if (std::fabs(fc) < std::fabs(fb)) {
55 double tol = 2.0 * std::numeric_limits<double>::epsilon() * std::fabs(b) + xtol;
56 double m = 0.5 * (c - b);
57 if (std::fabs(m) <= tol || std::fabs(fb) <= ftol) {
61 if (std::fabs(e) >= tol && std::fabs(fa) > std::fabs(fb)) {
70 p = s * (2.0 * m * s2 * (s2 - r) - (b - a) * (r - 1.0));
71 q = (s2 - 1.0) * (r - 1.0) * (s - 1.0);
73 if (p > 0) q = -q;
else p = -p;
74 if ( (2.0 * p) < (3.0 * m * q - std::fabs(tol * q)) && p < std::fabs(0.5 * e * q) ) {
87 if (std::fabs(d) > tol)
90 b += (m > 0 ? tol : -tol);
92 if (!std::isfinite(fb))
throw std::runtime_error(
"Function returned non-finite value during iteration.");
93 if ((fb > 0 && fc > 0) || (fb < 0 && fc < 0)) {
100 throw std::runtime_error(
"brent_root: maximum iterations exceeded");
108 std::unique_ptr<gsl_min_fminimizer, void(*)(gsl_min_fminimizer*)>
109 s(gsl_min_fminimizer_alloc(gsl_min_fminimizer_quad_golden),
110 gsl_min_fminimizer_free);
112 int st = gsl_min_fminimizer_set(s.get(), &gsl_f, context.start, context.bracket[0], context.bracket[1]);
115 throw std::runtime_error(std::string(
"gsl_min_fminimizer_set: ") + gsl_strerror(st));
119 std::size_t iter=0;
int status;
double size;
121 ++iter; status = gsl_min_fminimizer_iterate(s.get());
124 a = gsl_min_fminimizer_x_lower(s.get());
125 b = gsl_min_fminimizer_x_upper(s.get());
126 m = gsl_min_fminimizer_x_minimum(s.get());
128 status = gsl_min_test_interval(a, b, context.tol, 0.0);
129 }
while (status == GSL_CONTINUE && iter < context.max_iter);
160 std::size_t d = t0.size();
162 gsl_multimin_function gsl_f;
167 std::unique_ptr<gsl_multimin_fminimizer, void(*)(gsl_multimin_fminimizer*)>
168 s(gsl_multimin_fminimizer_alloc(gsl_multimin_fminimizer_nmsimplex2, d),
169 gsl_multimin_fminimizer_free);
171 gsl_vector* x = gsl_vector_alloc(d);
172 gsl_vector* step = gsl_vector_alloc(d);
173 for (
size_t i = 0; i < d; i++)
174 gsl_vector_set(x, i, t0[i]);
175 gsl_vector_set_all(step, context.simplex_initial_step_size);
177 int st = gsl_multimin_fminimizer_set(s.get(), &gsl_f, x, step);
180 throw std::runtime_error(std::string(
"gsl_multimin_fminimizer_set: ") + gsl_strerror(st));
182 std::size_t iter=0;
int status;
double size;
184 ++iter; status = gsl_multimin_fminimizer_iterate(s.get());
186 size = gsl_multimin_fminimizer_size(s.get());
187 status = gsl_multimin_test_size(size, context.switch_tol);
189 }
while (status == GSL_CONTINUE && iter < context.simplex_max_iter);
191 std::cout <<
"NM minimization converged in " << iter <<
" iterations." << std::endl;
192 gsl_vector* gsl_argmin = gsl_multimin_fminimizer_x(s.get());
193 std::vector<double> argmin(d);
194 for (std::size_t i = 0; i < d; ++i)
195 argmin[i] = gsl_vector_get(gsl_argmin, i);
200 mr.
min = gsl_multimin_fminimizer_minimum(s.get());
203 gsl_vector_free(step);
209 std::size_t d = t0.size();
210 gsl_multimin_function_fdf gsl_f;
218 std::unique_ptr<gsl_multimin_fdfminimizer, void(*)(gsl_multimin_fdfminimizer*)>
219 s(gsl_multimin_fdfminimizer_alloc(gsl_multimin_fdfminimizer_vector_bfgs2, d),
220 gsl_multimin_fdfminimizer_free);
222 gsl_vector* x = gsl_vector_alloc(d);
223 for (
size_t i = 0; i < d; i++)
224 gsl_vector_set(x, i, t0[i]);
225 int st = gsl_multimin_fdfminimizer_set(s.get(), &gsl_f, x, context.bfgs_initial_step_size, context.bfgs_line_search_tol);
228 throw std::runtime_error(std::string(
"gsl_multimin_fminimizer_set: ") + gsl_strerror(st));
230 std::size_t iter = 0;
int status; gsl_vector*
g;
231 double f_cur =
f(t0);
232 bool converged =
false;
235 ++iter; status = gsl_multimin_fdfminimizer_iterate(s.get());
237 g = gsl_multimin_fdfminimizer_gradient(s.get());
238 status = gsl_multimin_test_gradient(
g, context.final_tol);
239 double f_new = gsl_multimin_fdfminimizer_minimum(s.get());
240 double df = std::abs(f_new - f_cur);
241 converged = (status == GSL_SUCCESS) && (df < 1e-8 * (1.0 + std::abs(f_cur)));
242 iterate = !converged && (iter < context.bfgs_max_iter);
245 std::cout <<
"BFGS minimization converged in " << iter <<
" iterations." << std::endl;
246 gsl_vector* gsl_argmin = gsl_multimin_fdfminimizer_x(s.get());
247 std::vector<double> argmin(d);
248 for (std::size_t i = 0; i < d; ++i)
249 argmin[i] = gsl_vector_get(gsl_argmin, i);
254 mr.
min = gsl_multimin_fdfminimizer_minimum(s.get());
bool find_bracket(const RealValuedFunction &f, double x_min, double x_max, double &a, double &b, int n_samples)
double brent_root(const RealValuedFunction &f, double a, double b, double xtol, double ftol, int max_it)