Loading [MathJax]/extensions/tex2jax.js
Optimist  0.0.0
A C++ library for optimization
All Classes Namespaces Files Functions Variables Typedefs Macros Pages
Solver.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * Copyright (c) 2025, Davide Stocco, Mattia Piazza and Enrico Bertolazzi. *
3 * *
4 * The Optimist project is distributed under the BSD 2-Clause License. *
5 * *
6 * Davide Stocco Mattia Piazza Enrico Bertolazzi *
7 * University of Trento University of Trento University of Trento *
8 * davide.stocco@unitn.it mattia.piazza@unitn.it enrico.bertolazzi@unitn.it *
9\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10
11#pragma once
12
13#ifndef OPTIMIST_SOLVER_HH
14#define OPTIMIST_SOLVER_HH
15
16#include "Optimist.hh"
17#include "Function.hh"
18
19namespace Optimist
20{
21
22 /*\
23 | ____ _
24 | / ___| ___ | |_ _____ _ __
25 | \___ \ / _ \| \ \ / / _ \ '__|
26 | ___) | (_) | |\ V / __/ |
27 | |____/ \___/|_| \_/ \___|_|
28 |
29 \*/
30
41 template <typename Real, Integer SolInDim, Integer SolOutDim, typename DerivedSolver>
42 class Solver
43 {
44 public:
45 // Fancy static assertions (just for fun, don't take it too seriously)
46 static_assert(SolInDim > static_cast<Integer>(0) && SolOutDim > static_cast<Integer>(0),
47 "Negative-dimensional optimization problem? Are you serious?");
48
50
51 protected:
52 // I/O types
53 using InputType = typename std::conditional_t<SolInDim == 1, Real, Eigen::Vector<Real, SolInDim>>;
54 using OutputType = typename std::conditional_t<SolOutDim == 1, Real, Eigen::Vector<Real, SolOutDim>>;
55
56 // Trace types
57 using TraceType = typename std::vector<InputType>;
58
59 // Derivative types
60 using FirstDerivativeType = std::conditional_t<SolInDim == 1 && SolOutDim == 1, Real, Eigen::Matrix<Real, SolOutDim, SolInDim>>;
61 using SecondDerivativeType = std::conditional_t<SolInDim == 1 && SolOutDim == 1, Real,
62 std::conditional_t<SolInDim == 1 || SolOutDim == 1, Eigen::Matrix<Real, SolInDim, SolInDim>,
63 std::vector<Eigen::Matrix<Real, SolInDim, SolInDim>>>>;
64
65 // Function types
66 using FunctionWrapper = typename std::function<void(const InputType &, OutputType &)>;
67 using FirstDerivativeWrapper = typename std::function<void(const InputType &, FirstDerivativeType &)>;
68 using SecondDerivativeWrapper = typename std::function<void(const InputType &, SecondDerivativeType &)>;
69
70 // Bounds (may not be used)
73
74 // Evaluations
78
79 // Maximum allowed evaluations
83
84 // Iterations and relaxations
87 Real m_alpha{0.8};
90
91 // Settings
92 Real m_tolerance{EPSILON_LOW};
93 bool m_verbose{false};
94 bool m_damped{true};
95 std::ostream * m_ostream{&std::cout};
96
97 // Convergence output flag and trace
98 std::string m_task{"Undefined"};
99 bool m_converged{false};
101
102 public:
107 if constexpr (SolInDim == 1) {
108 this->m_lower_bound = -INFTY;
109 this->m_upper_bound = INFTY;
110 } else if constexpr (SolInDim > 1) {
111 this->m_lower_bound.setConstant(-INFTY);
112 this->m_upper_bound.setConstant(INFTY);
113 }
114 this->m_trace.reserve(this->m_max_iterations * this->m_max_relaxations);
115 }
116
123 Solver(FunctionWrapper function, const InputType & x_ini, InputType & x_sol) : Solver() {
124 this->solve_impl(function, x_ini, x_sol);
125 }
126
134 Solver(FunctionWrapper function, FirstDerivativeWrapper first_derivative, const InputType & x_ini,
135 InputType & x_sol) : Solver()
136 {
137 this->solve_impl(function, first_derivative, x_ini, x_sol);
138 }
139
149 second_derivative, const InputType & x_ini, InputType & x_sol) : Solver()
150 {
151 this->solve_impl(function, first_derivative, second_derivative, x_ini, x_sol);
152 }
153
158 const InputType & lower_bound() const {return this->m_lower_bound;}
159
164 void lower_bound(const InputType & t_lower_bound) {
165 #define CMD "Optimist::Solver::bounds(...): "
166
167 if constexpr (SolInDim == 1) {
168 OPTIMIST_ASSERT(this->m_upper_bound > t_lower_bound,
169 CMD "invalid or degenarate bounds detected.");
170 } else if constexpr (SolInDim > 1) {
171 OPTIMIST_ASSERT((this->m_upper_bound - t_lower_bound).minCoeff() <= 0.0,
172 CMD "invalid or degenarate bounds detected.");
173 }
174 this->m_lower_bound = t_lower_bound;
175
176 #undef CMD
177 }
178
183 const InputType & upper_bound() const {return this->m_upper_bound;}
184
189 void upper_bound(const InputType & t_upper_bound) {
190 #define CMD "Optimist::Solver::bounds(...): "
191
192 if constexpr (SolInDim == 1) {
193 OPTIMIST_ASSERT(t_upper_bound > this->m_lower_bound,
194 CMD "invalid or degenarate bounds detected.");
195 } else if constexpr (SolInDim > 1) {
196 OPTIMIST_ASSERT((t_upper_bound - this->m_lower_bound).minCoeff() <= 0.0,
197 CMD "invalid or degenarate bounds detected.");
198 }
199 this->m_upper_bound = t_upper_bound;
200
201 #undef CMD
202 }
203
209 void bounds(const InputType & t_lower_bound, const InputType & t_upper_bound)
210 {
211 #define CMD "Optimist::Solver::bounds(...): "
212
213 if constexpr (SolInDim == 1) {
214 OPTIMIST_ASSERT(t_upper_bound > t_lower_bound,
215 CMD "invalid or degenarate bounds detected.");
216 } else if constexpr (SolInDim > 1) {
217 OPTIMIST_ASSERT((t_upper_bound - t_lower_bound).minCoeff() <= 0.0,
218 CMD "invalid or degenarate bounds detected.");
219 }
220 this->m_lower_bound = t_lower_bound;
221 this->m_upper_bound = t_upper_bound;
222
223 #undef CMD
224 }
225
230 constexpr Integer input_dimension() const {return SolInDim;}
231
236 constexpr Integer output_dimension() const {return SolOutDim;}
237
243
248 void max_function_evaluations(Integer t_max_function_evaluations)
249 {
250 OPTIMIST_ASSERT(!std::isnan(t_max_function_evaluations) && std::isfinite(t_max_function_evaluations),
251 "Optimist::Solver::max_function_evaluations(...): invalid input detected.");
252 this->m_max_function_evaluations = t_max_function_evaluations;
253 }
254
260
261 protected:
267
273
279 {
281 !std::isnan(first_derivative_evaluations) && std::isfinite(first_derivative_evaluations),
282 "Optimist::Solver::max_first_derivative_evaluations(...): invalid input detected.");
284 }
285
291
297
303 {
306 "Optimist::Solver::max_second_derivative_evaluations(...): invalid input detected.");
308 }
309
310 public:
314 Integer iterations() const {return this->m_iterations;}
315
320 Integer max_iterations() const {return this->max_iterations;}
321
326 void max_iterations(Integer t_max_iterations) {
327 OPTIMIST_ASSERT(!std::isnan(t_max_iterations) && std::isfinite(t_max_iterations),
328 "Optimist::Solver::max_iterations(...): invalid input detected.");
329 this->m_max_iterations = t_max_iterations;
330 }
331
336 Real alpha() const {return this->m_alpha;}
337
342 void alpha(Real t_alpha)
343 {
345 !std::isnan(t_alpha) && std::isfinite(t_alpha) && 0.0 <= t_alpha && t_alpha <= 1.0,
346 "Optimist::Solver::alpha(...): invalid input detected.");
347 this->m_alpha = t_alpha;
348 }
349
354 Integer relaxations() const {return this->m_relaxations;}
355
361
366 void max_relaxations(Integer t_max_relaxations)
367 {
368 OPTIMIST_ASSERT(!std::isnan(t_max_relaxations) && std::isfinite(t_max_relaxations),
369 "Optimist::Solver::max_relaxations(...): invalid input detected.");
370 this->m_max_relaxations = t_max_relaxations;
371 }
372
377 Real tolerance() const {return this->m_tolerance;}
378
384 void tolerance(Real t_tolerance) {
386 !std::isnan(t_tolerance) && std::isfinite(t_tolerance) && t_tolerance > 0.0,
387 "Optimist::Solver::tolerance(...): invalid input detected.");
388 this->m_tolerance = t_tolerance;
389 }
390
395 void verbose_mode(bool t_verbose) {this->m_verbose = t_verbose;}
396
401 bool verbose_mode() const {return this->m_verbose;}
402
406 void enable_verbose_mode() {this->m_verbose = true;}
407
411 void disable_verbose_mode() {this->m_verbose = false;}
412
417 void damped_mode(bool t_damped) {this->m_damped = t_damped;}
418
423 bool damped_mode() const {return this->m_damped;}
424
428 void enable_damped_mode() {this->m_damped = true;}
429
433 void disable_damped_mode() {this->m_damped = false;}
434
439 std::string task() const {return this->m_task;}
440
445 void task(std::string t_task) {this->m_task = t_task;}
446
451 bool converged() const {return this->m_converged;}
452
457 const TraceType & trace() const {return this->m_trace;}
458
463 std::ostream & ostream() const {return *this->m_ostream;}
464
469 void ostream(std::ostream & t_ostream) {this->m_ostream = &t_ostream;}
470
477 bool solve(FunctionWrapper function, const InputType & x_ini, InputType & x_sol)
478 {
479 #define CMD "Optimist::Solver::solve(...): "
480
481 static_assert(DerivedSolver::requires_function,
482 CMD "the solver requires a function.");
483 return static_cast<DerivedSolver *>(this)->solve(function, nullptr, nullptr, x_ini, x_sol);
484
485 #undef CMD
486 }
487
495 bool solve(FunctionWrapper function, FirstDerivativeWrapper first_derivative, const InputType & x_ini,
496 InputType & x_sol)
497 {
498 #define CMD "Optimist::Solver::solve(...): "
499
500 static_assert(DerivedSolver::requires_function,
501 CMD "the solver requires a function.");
502 static_assert(DerivedSolver::requires_first_derivative,
503 CMD "the solver requires the first derivative.");
504 return static_cast<DerivedSolver *>(this)->solve(function, first_derivative, nullptr, x_ini, x_sol);
505
506 #undef CMD
507 }
508
518 second_derivative, const InputType & x_ini, InputType & x_sol)
519 {
520 #define CMD "Optimist::Solver::solve(...): "
521
522 static_assert(DerivedSolver::requires_function,
523 CMD "the solver requires the function.");
524 static_assert(DerivedSolver::requires_first_derivative,
525 CMD "the solver requires the first derivative.");
526 static_assert(DerivedSolver::requires_second_derivative,
527 CMD "the solver requires the second derivative.");
528 return static_cast<DerivedSolver *>(this)->solve(function, first_derivative, second_derivative,
529 x_ini, x_sol);
530
531 #undef CMD
532 }
533
543 template <Integer FunInDim, Integer FunOutDim, typename DerivedFunction>
545 & x_ini, InputType & x_sol)
546 {
547 #define CMD "Optimist::Solver::rootfind(...): "
548
549 static_assert(SolInDim == FunInDim,
550 CMD "solver input dimension must be equal to the function input dimension.");
551 static_assert(SolOutDim == FunOutDim || SolOutDim == 1,
552 CMD "solver output dimension must be equal to the function output dimension or 1.");
553 static_assert(!(SolInDim == 1 && DerivedSolver::is_optimizer),
554 CMD "one-dimensional optimizers do not support root-finding problems.");
555 return this->solve(function, x_ini, x_sol, SolOutDim != FunOutDim || (SolInDim > 1 && SolOutDim == 1));
556
557 #undef CMD
558 }
559
569 template <Integer FunInDim, Integer FunOutDim, typename DerivedFunction>
571 & x_ini, InputType & x_sol)
572 {
573 #define CMD "Optimist::Solver::optimize(...): "
574
575 static_assert(SolInDim == FunInDim,
576 CMD "solver input dimension must be equal to the function input dimension.");
577 static_assert(SolOutDim == 1,
578 CMD "solver output dimension must be equal to the function output dimension or 1.");
579 static_assert(!(SolInDim == 1 && DerivedSolver::is_rootfinder),
580 CMD "one-dimensional root-finders do not support optimization problems.");
581 return this->solve(function, x_ini, x_sol, true);
582
583 #undef CMD
584 }
585
590 std::string name() const {return static_cast<const DerivedSolver *>(this)->name_impl();};
591
592 protected:
603 template <Integer FunInDim, Integer FunOutDim, typename DerivedFunction>
605 InputType & x_sol, bool is_optimization)
606 {
607 #define CMD "Optimist::Solver::solve(...): "
608
610
611 static_assert(SolInDim == FunInDim,
612 CMD "solver input dimension must be equal to the function input dimension.");
613 static_assert(SolOutDim == FunOutDim || SolOutDim == 1,
614 CMD "solver output dimension must be equal to the function output dimension or 1.");
615
616 // Lambda generators for function and derivatives
617 auto function_wrapper = [&function, is_optimization](const InputType & x, OutputType & out)
618 {
619 typename FunctionType::OutputType f;
620 function.evaluate(x, f);
621 if (is_optimization) {
622 if constexpr (FunOutDim == 1) {out = 0.5*f*f;}
623 else if constexpr (SolOutDim != FunOutDim) {out = 0.5*f.squaredNorm();}
624 else {OPTIMIST_ERROR(CMD "optimization problem with inconsistent output in function.");}
625 } else {
626 if constexpr (SolOutDim == FunOutDim) {
627 out = f;
628 }
629 else {OPTIMIST_ERROR(CMD "root-finding problem with inconsistent output in function.");}
630 }
631 };
632
633 auto first_derivative_wrapper = [&function, is_optimization, this](const InputType & x, FirstDerivativeType & out)
634 {
635 typename FunctionType::FirstDerivativeType J; function.first_derivative(x, J);
636
637 if (is_optimization) {
638 typename FunctionType::OutputType f; function.evaluate(x, f);
640 if constexpr (FunInDim == 1 && FunOutDim == 1) {out = J*f;}
641 else if constexpr (SolOutDim != FunOutDim) {out = J.transpose()*f;}
642 else {OPTIMIST_ERROR(CMD "optimization problem inconsistent output in first derivative.");}
643 } else {
644 if constexpr (SolOutDim == FunOutDim) {
645 out = J;
646 }
647 else {OPTIMIST_ERROR(CMD "root-finding problem with inconsistent output in first derivative.");}
648 }
649 };
650
651 auto second_derivative_wrapper = [&function, is_optimization, this](const InputType & x, SecondDerivativeType & out)
652 {
653 typename FunctionType::SecondDerivativeType H; function.second_derivative(x, H);
654
655 if (is_optimization) {
656 typename FunctionType::OutputType f; function.evaluate(x, f);
657 typename FunctionType::FirstDerivativeType J; function.first_derivative(x, J);
659 if constexpr (FunInDim == 1 && FunOutDim == 1) {out = J*J + f*H;}
660 else if constexpr (SolOutDim != FunOutDim) {
661 out = J.transpose()*J;
662 for (Integer i = 0; i < static_cast<Integer>(H.size()); ++i) {out += f(i)*H[i];}
663 }
664 else {OPTIMIST_ERROR(CMD "optimization problem with inconsistent output in second derivative.");}
665 } else {
666 if constexpr (SolOutDim == FunOutDim) {out = H;}
667 else {OPTIMIST_ERROR(CMD "root-finding problem with inconsistent output in second derivative.");}
668 }
669 };
670
671 // Select solver method based on derivative requirements
672 if constexpr (DerivedSolver::requires_function && !DerivedSolver::requires_first_derivative &&
673 !DerivedSolver::requires_second_derivative) {
674 return static_cast<DerivedSolver *>(this)->solve(function_wrapper, x_ini, x_sol);
675 } else if constexpr (DerivedSolver::requires_function && DerivedSolver::requires_first_derivative &&
676 !DerivedSolver::requires_second_derivative) {
677 return static_cast<DerivedSolver *>(this)->solve(function_wrapper, first_derivative_wrapper,
678 x_ini, x_sol);
679 } else if constexpr (DerivedSolver::requires_function && DerivedSolver::requires_first_derivative &&
680 DerivedSolver::requires_second_derivative) {
681 return static_cast<DerivedSolver *>(this)->solve(function_wrapper, first_derivative_wrapper,
682 second_derivative_wrapper, x_ini, x_sol);
683 } else {
684 OPTIMIST_ERROR(CMD "no matching function signature found for the solver.");
685 }
686
687 #undef CMD
688 }
689
693 void reset()
694 {
695 this->m_function_evaluations = static_cast<Integer>(0);
696 this->m_first_derivative_evaluations = static_cast<Integer>(0);
697 this->m_second_derivative_evaluations = static_cast<Integer>(0);
698 this->m_iterations = static_cast<Integer>(0);
699 this->m_relaxations = static_cast<Integer>(0);
700 this->m_converged = false;
701 this->m_trace.clear();
702 }
703
710 void evaluate_function(FunctionWrapper function, const InputType & x, OutputType & out)
711 {
713 "Optimist::" << this-> name() << "::evaluate_function(...): maximum allowed function evaluations reached.");
715 function(x, out);
716 }
717
725 {
727 "Optimist::" << this-> name() << "::evaluate_first_derivative(...): maximum allowed first derivative evaluations reached.");
729 function(x, out);
730 }
731
739 {
741 "Optimist::" << this-> name() << "::evaluate_second_derivative(...): maximum allowed second derivative evaluations reached.");
743 function(x, out);
744 }
745
750 void store_trace(const InputType & x) {this->m_trace.push_back(x);}
751
763 bool damp(FunctionWrapper function, InputType const & x_old, InputType const & function_old,
764 InputType const & step_old, InputType & x_new, InputType & function_new, InputType & step_new)
765 {
766 Real step_norm_old, step_norm_new, residuals_old, residuals_new, tau{1.0};
767 for (this->m_relaxations = static_cast<Integer>(0); this->m_relaxations < this->m_max_relaxations; ++this->m_relaxations)
768 {
769 // Update point
770 step_new = tau * step_old;
771 x_new = x_old + step_new;
772 this->evaluate_function(function, x_new, function_new);
773
774 // Check relaxation
775 if constexpr (SolInDim == 1 && SolOutDim == 1) {
776 residuals_old = std::abs(function_old);
777 residuals_new = std::abs(function_new);
778 step_norm_old = std::abs(step_old);
779 step_norm_new = std::abs(step_new);
780 } else {
781 residuals_old = function_old.norm();
782 residuals_new = function_new.norm();
783 step_norm_old = step_old.norm();
784 step_norm_new = step_new.norm();
785 }
786 if (residuals_new < residuals_old || step_norm_new < (Real(1.0)-tau/Real(2.0))*step_norm_old) {
787 return true;
788 } else {
789 tau *= this->m_alpha;
790 }
791 }
792 return false;
793 }
794
799 void header()
800 {
801 std::string c_tl{table_top_left_corner()};
802 std::string c_tr{table_top_right_corner()};
803 std::string h_7{table_horizontal_line<7>()};
804 std::string h_14{table_horizontal_line<14>()};
805 std::string h_23{table_horizontal_line<23>()};
806 std::string h_78{table_horizontal_line<78>()};
807 std::string v_ll{table_vertical_line() + " "};
808 std::string v_rr{" " + table_vertical_line()};
809 std::string v_lc{" " + table_vertical_line() + " "};
810 std::string j_tt{table_top_junction()};
811 std::string j_cc{table_center_cross()};
812 std::string j_ll{table_left_junction()};
813 std::string j_rr{table_right_junction()};
814
815 *this->m_ostream
816 << c_tl << h_78 << c_tr << std::endl
817 << v_ll << "Solver:" << std::setw(69) << this->name() << v_rr << std::endl
818 << v_ll << "Task: " << std::setw(69) << this->task() << v_rr << std::endl
819 << j_ll << h_7 << j_tt << h_7 << j_tt << h_7 << j_tt << h_7 << j_tt << h_7 << j_tt << h_14 << j_tt << h_23 << j_rr << std::endl
820 << v_ll << "#Iter" << v_lc << " #f" << v_lc << " #Df" << v_lc << " #DDf" << v_lc << " #Rlx" << v_lc
821 << " ║f(x)║₂ " << v_lc << "Additional notes" << std::setw(9) << v_rr << std::endl
822 << j_ll << h_7 << j_cc << h_7 << j_cc << h_7 << j_cc << h_7 << j_cc << h_7 << j_cc << h_14 << j_cc << h_23 << j_rr << std::endl;
823 }
824
829 void bottom()
830 {
831 std::string c_bl{table_bottom_left_corner()};
832 std::string c_br{table_bottom_right_corner()};
833 std::string h_7{table_horizontal_line<7>()};
834 std::string h_14{table_horizontal_line<14>()};
835 std::string h_23{table_horizontal_line<23>()};
836 std::string h_78{table_horizontal_line<78>()};
837 std::string v_ll{table_vertical_line() + " "};
838 std::string v_rr{" " + table_vertical_line()};
839 std::string j_ll{table_left_junction()};
840 std::string j_rr{table_right_junction()};
841 std::string j_bb{table_bottom_junction()};
842
843 *this->m_ostream
844 << j_ll << h_7 << j_bb << h_7 << j_bb << h_7 << j_bb << h_7 << j_bb << h_7 << j_bb << h_14 << j_bb << h_23 << j_rr << std::endl
845 << v_ll << std::setw(40) << (this->m_converged ? "CONVERGED" : "NOT CONVERGED") << std::setw(40) << v_rr << std::endl
846 << c_bl << h_78 << c_br << std::endl;
847 }
848
853 void info(Real residuals, std::string const & notes = "-")
854 {
855 std::string v_rr{" " + table_vertical_line()};
856 std::string v_ll{table_vertical_line() + " "};
857 std::string v_lc{" " + table_vertical_line() + " "};
858
859 *this->m_ostream << v_ll
860 << std::setw(5) << this->m_iterations << v_lc
861 << std::setw(5) << this->m_function_evaluations << v_lc
862 << std::setw(5) << this->m_first_derivative_evaluations << v_lc
863 << std::setw(5) << this->m_second_derivative_evaluations << v_lc
864 << std::setw(5) << this->m_relaxations << v_lc
865 << std::setw(12) << std::scientific << std::setprecision(6) << residuals << v_lc
866 << notes << std::setw(25-notes.length()) << v_rr << std::endl;
867 }
868
869 }; // class Solver
870
871} // namespace Optimist
872
873#endif // OPTIMIST_SOLVER_HH
#define OPTIMIST_ERROR(MSG)
Definition Optimist.hh:33
#define OPTIMIST_BASIC_CONSTANTS(Real)
Definition Optimist.hh:70
#define OPTIMIST_ASSERT(COND, MSG)
Definition Optimist.hh:43
#define CMD
Class container for the generic function.
Definition Function.hh:33
void second_derivative(const InputType &x, SecondDerivativeType &out) const
Definition Function.hh:92
void first_derivative(const InputType &x, FirstDerivativeType &out) const
Definition Function.hh:82
void evaluate(const InputType &x, OutputType &out) const
Definition Function.hh:72
Integer m_max_function_evaluations
Definition Solver.hh:80
Real m_tolerance
Definition Solver.hh:92
Integer first_derivative_evaluations() const
Definition Solver.hh:266
const TraceType & trace() const
Definition Solver.hh:457
constexpr Integer output_dimension() const
Definition Solver.hh:236
Solver(FunctionWrapper function, const InputType &x_ini, InputType &x_sol)
Definition Solver.hh:123
std::ostream * m_ostream
Definition Solver.hh:95
bool m_verbose
Definition Solver.hh:93
Solver()
Definition Solver.hh:106
Integer max_relaxations() const
Definition Solver.hh:360
bool m_converged
Definition Solver.hh:99
void ostream(std::ostream &t_ostream)
Definition Solver.hh:469
void lower_bound(const InputType &t_lower_bound)
Definition Solver.hh:164
void max_function_evaluations(Integer t_max_function_evaluations)
Definition Solver.hh:248
Integer m_function_evaluations
Definition Solver.hh:75
bool verbose_mode() const
Definition Solver.hh:401
bool m_damped
Definition Solver.hh:94
void store_trace(const InputType &x)
Definition Solver.hh:750
void task(std::string t_task)
Definition Solver.hh:445
bool rootfind(Function< Real, FunInDim, FunOutDim, DerivedFunction > const &function, const InputType &x_ini, InputType &x_sol)
Definition Solver.hh:544
InputType m_upper_bound
Definition Solver.hh:72
TraceType m_trace
Definition Solver.hh:100
bool solve(FunctionWrapper function, FirstDerivativeWrapper first_derivative, const InputType &x_ini, InputType &x_sol)
Definition Solver.hh:495
void max_iterations(Integer t_max_iterations)
Definition Solver.hh:326
void max_second_derivative_evaluations(Integer second_derivative_evaluations)
Definition Solver.hh:302
bool optimize(Function< Real, FunInDim, FunOutDim, DerivedFunction > const &function, const InputType &x_ini, InputType &x_sol)
Definition Solver.hh:570
Solver(FunctionWrapper function, FirstDerivativeWrapper first_derivative, const InputType &x_ini, InputType &x_sol)
Definition Solver.hh:134
typename std::conditional_t< SolInDim==1, Real, Eigen::Vector< Real, SolInDim > > InputType
Definition Solver.hh:53
Integer function_evaluations() const
Definition Solver.hh:242
std::string task() const
Definition Solver.hh:439
void damped_mode(bool t_damped)
Definition Solver.hh:417
std::ostream & ostream() const
Definition Solver.hh:463
Integer m_second_derivative_evaluations
Definition Solver.hh:77
void header()
Definition Solver.hh:799
Integer relaxations() const
Definition Solver.hh:354
void reset()
Definition Solver.hh:693
InputType m_lower_bound
Definition Solver.hh:71
Integer max_iterations() const
Definition Solver.hh:320
void max_relaxations(Integer t_max_relaxations)
Definition Solver.hh:366
bool converged() const
Definition Solver.hh:451
const InputType & upper_bound() const
Definition Solver.hh:183
std::string name() const
Definition Solver.hh:590
Integer max_function_evaluations() const
Definition Solver.hh:259
typename std::function< void(const InputType &, FirstDerivativeType &)> FirstDerivativeWrapper
Definition Solver.hh:67
void bounds(const InputType &t_lower_bound, const InputType &t_upper_bound)
Definition Solver.hh:209
typename std::vector< InputType > TraceType
Definition Solver.hh:57
bool damp(FunctionWrapper function, InputType const &x_old, InputType const &function_old, InputType const &step_old, InputType &x_new, InputType &function_new, InputType &step_new)
Definition Solver.hh:763
std::conditional_t< SolInDim==1 &&SolOutDim==1, Real, std::conditional_t< SolInDim==1||SolOutDim==1, Eigen::Matrix< Real, SolInDim, SolInDim >, std::vector< Eigen::Matrix< Real, SolInDim, SolInDim > > > > SecondDerivativeType
Definition Solver.hh:61
void enable_damped_mode()
Definition Solver.hh:428
Integer max_second_derivative_evaluations() const
Definition Solver.hh:296
Integer max_first_derivative_evaluations() const
Definition Solver.hh:272
typename std::function< void(const InputType &, SecondDerivativeType &)> SecondDerivativeWrapper
Definition Solver.hh:68
typename std::function< void(const InputType &, OutputType &)> FunctionWrapper
Definition Solver.hh:66
Integer m_first_derivative_evaluations
Definition Solver.hh:76
Integer m_max_second_derivative_evaluations
Definition Solver.hh:82
bool damped_mode() const
Definition Solver.hh:423
void tolerance(Real t_tolerance)
Definition Solver.hh:384
void enable_verbose_mode()
Definition Solver.hh:406
Integer m_max_relaxations
Definition Solver.hh:89
const InputType & lower_bound() const
Definition Solver.hh:158
Real tolerance() const
Definition Solver.hh:377
constexpr Integer input_dimension() const
Definition Solver.hh:230
Integer iterations() const
Definition Solver.hh:314
void evaluate_first_derivative(FirstDerivativeWrapper function, const InputType &x, FirstDerivativeType &out)
Definition Solver.hh:724
void alpha(Real t_alpha)
Definition Solver.hh:342
void bottom()
Definition Solver.hh:829
void evaluate_function(FunctionWrapper function, const InputType &x, OutputType &out)
Definition Solver.hh:710
std::string m_task
Definition Solver.hh:98
Solver(FunctionWrapper function, FirstDerivativeWrapper first_derivative, SecondDerivativeWrapper second_derivative, const InputType &x_ini, InputType &x_sol)
Definition Solver.hh:148
Real m_alpha
Definition Solver.hh:87
Integer second_derivative_evaluations() const
Definition Solver.hh:290
void verbose_mode(bool t_verbose)
Definition Solver.hh:395
void upper_bound(const InputType &t_upper_bound)
Definition Solver.hh:189
void max_first_derivative_evaluations(Integer first_derivative_evaluations)
Definition Solver.hh:278
std::conditional_t< SolInDim==1 &&SolOutDim==1, Real, Eigen::Matrix< Real, SolOutDim, SolInDim > > FirstDerivativeType
Definition Solver.hh:60
Integer m_max_first_derivative_evaluations
Definition Solver.hh:81
Real alpha() const
Definition Solver.hh:336
void info(Real residuals, std::string const &notes="-")
Definition Solver.hh:853
Integer m_iterations
Definition Solver.hh:85
Integer m_max_iterations
Definition Solver.hh:86
Integer m_relaxations
Definition Solver.hh:88
bool solve(FunctionWrapper function, const InputType &x_ini, InputType &x_sol)
Definition Solver.hh:477
bool solve(Function< Real, FunInDim, FunOutDim, DerivedFunction > const &function, const InputType &x_ini, InputType &x_sol, bool is_optimization)
Definition Solver.hh:604
void disable_damped_mode()
Definition Solver.hh:433
bool solve(FunctionWrapper function, FirstDerivativeWrapper first_derivative, SecondDerivativeWrapper second_derivative, const InputType &x_ini, InputType &x_sol)
Definition Solver.hh:517
typename std::conditional_t< SolOutDim==1, Real, Eigen::Vector< Real, SolOutDim > > OutputType
Definition Solver.hh:54
void disable_verbose_mode()
Definition Solver.hh:411
void evaluate_second_derivative(SecondDerivativeWrapper function, const InputType &x, SecondDerivativeType &out)
Definition Solver.hh:738
Namespace for the Optimist library.
Definition Optimist.hh:87
static std::string table_vertical_line()
Retrieve the Unicode character for the vertical line of a table.
Definition Optimist.hh:173
static std::string table_bottom_right_corner()
Retrieve the Unicode character for the bottom-right corner of a table.
Definition Optimist.hh:119
static std::string table_top_left_corner()
Retrieve the Unicode character for the top-left corner of a table.
Definition Optimist.hh:101
static std::string table_bottom_left_corner()
Retrieve the Unicode character for the bottom-left corner of a table.
Definition Optimist.hh:113
OPTIMIST_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Optimist.hh:95
static std::string table_center_cross()
Retrieve the Unicode character for the center cross of a table.
Definition Optimist.hh:149
static std::string table_bottom_junction()
Retrieve the Unicode character for the bottom junction of a table.
Definition Optimist.hh:143
static std::string table_top_junction()
Retrieve the Unicode character for the top junction of a table.
Definition Optimist.hh:137
static std::string table_top_right_corner()
Retrieve the Unicode character for the top-right corner of a table.
Definition Optimist.hh:107
static std::string table_horizontal_line()
Retrieve the Unicode character for the horizontal line of a table.
Definition Optimist.hh:155
static std::string table_right_junction()
Retrieve the Unicode character for the right junction of a table.
Definition Optimist.hh:131
static std::string table_left_junction()
Retrieve the Unicode character for the left junction of a table.
Definition Optimist.hh:125