|
2 | 2 |
|
3 | 3 | #include <polysolve/Types.hpp> |
4 | 4 |
|
| 5 | +#include "Criteria.hpp" |
5 | 6 | #include "PostStepData.hpp" |
6 | 7 |
|
7 | | -#include <cppoptlib/problem.h> |
8 | | - |
9 | 8 | #include <memory> |
10 | 9 | #include <vector> |
11 | 10 |
|
12 | 11 | namespace polysolve::nonlinear |
13 | 12 | { |
14 | | - class Problem : public cppoptlib::Problem<double> |
| 13 | + class Problem |
15 | 14 | { |
16 | 15 | public: |
17 | | - using typename cppoptlib::Problem<double>::Scalar; |
18 | | - using typename cppoptlib::Problem<double>::TVector; |
19 | | - typedef polysolve::StiffnessMatrix THessian; |
20 | | - |
21 | | - // disable warning for dense hessian |
22 | | - using cppoptlib::Problem<double>::hessian; |
| 16 | + static constexpr int Dim = Eigen::Dynamic; |
| 17 | + using Scalar = double; |
| 18 | + using TVector = Eigen::Matrix<Scalar, Dim, 1>; |
| 19 | + using TMatrix = Eigen::Matrix<Scalar, Dim, Dim>; |
| 20 | + using THessian = StiffnessMatrix; |
23 | 21 |
|
| 22 | + public: |
24 | 23 | Problem() {} |
25 | | - ~Problem() = default; |
| 24 | + virtual ~Problem() = default; |
26 | 25 |
|
| 26 | + /// @brief Initialize the problem. |
| 27 | + /// @param x0 Initial guess. |
27 | 28 | virtual void init(const TVector &x0) {} |
28 | 29 |
|
29 | | - virtual double value(const TVector &x) override = 0; |
30 | | - virtual void gradient(const TVector &x, TVector &gradv) override = 0; |
| 30 | + /// @brief Compute the value of the function at x. |
| 31 | + /// @param x Degrees of freedom. |
| 32 | + /// @return The value of the function at x. |
| 33 | + Scalar operator()(const TVector &x) { return value(x); } |
| 34 | + |
| 35 | + /// @brief Compute the value of the function at x. |
| 36 | + /// @param x Degrees of freedom. |
| 37 | + /// @return The value of the function at x. |
| 38 | + virtual Scalar value(const TVector &x) = 0; |
| 39 | + |
| 40 | + /// @brief Compute the gradient of the function at x. |
| 41 | + /// @param[in] x Degrees of freedom. |
| 42 | + /// @param[out] grad Gradient of the function at x. |
| 43 | + virtual void gradient(const TVector &x, TVector &grad) = 0; |
| 44 | + |
| 45 | + /// @brief Compute the Hessian of the function at x. |
| 46 | + /// @param[in] x Degrees of freedom. |
| 47 | + /// @param[out] hessian Hessian of the function at x. |
| 48 | + virtual void hessian(const TVector &x, TMatrix &hessian) |
| 49 | + { |
| 50 | + throw std::runtime_error("Dense Hessian not implemented."); |
| 51 | + } |
| 52 | + |
| 53 | + /// @brief Compute the Hessian of the function at x. |
| 54 | + /// @param[in] x Degrees of freedom. |
| 55 | + /// @param[out] hessian Hessian of the function at x. |
31 | 56 | virtual void hessian(const TVector &x, THessian &hessian) = 0; |
32 | 57 |
|
| 58 | + /// @brief Determine if the step from x0 to x1 is valid. |
| 59 | + /// @param x0 Starting point. |
| 60 | + /// @param x1 Ending point. |
| 61 | + /// @return True if the step is valid, false otherwise. |
33 | 62 | virtual bool is_step_valid(const TVector &x0, const TVector &x1) { return true; } |
| 63 | + |
| 64 | + /// @brief Determine a maximum step size from x0 to x1. |
| 65 | + /// @param x0 Starting point. |
| 66 | + /// @param x1 Ending point. |
| 67 | + /// @return Maximum step size. |
34 | 68 | virtual double max_step_size(const TVector &x0, const TVector &x1) { return 1; } |
35 | 69 |
|
| 70 | + // --- Callbacks ------------------------------------------------------ |
| 71 | + |
| 72 | + /// @brief Callback function for the start of a line search. |
| 73 | + /// @param x0 Starting point. |
| 74 | + /// @param x1 Ending point. |
36 | 75 | virtual void line_search_begin(const TVector &x0, const TVector &x1) {} |
| 76 | + |
| 77 | + /// @brief Callback function for the end of a line search. |
37 | 78 | virtual void line_search_end() {} |
| 79 | + |
| 80 | + /// @brief Callback function for the end of a step. |
| 81 | + /// @param data Post step data. |
38 | 82 | virtual void post_step(const PostStepData &data) {} |
39 | 83 |
|
| 84 | + /// @brief Set the project to PSD flag. |
| 85 | + /// @param val True if the problem should be projected to PSD, false otherwise. |
40 | 86 | virtual void set_project_to_psd(bool val) {} |
41 | 87 |
|
| 88 | + /// @brief Callback function for when the solution changes. |
| 89 | + /// @param new_x New solution. |
42 | 90 | virtual void solution_changed(const TVector &new_x) {} |
43 | 91 |
|
| 92 | + /// @brief Callback function used to determine if the solver should stop. |
| 93 | + /// @param state Current state of the solver. |
| 94 | + /// @param x Current solution. |
| 95 | + /// @return True if the solver should stop, false otherwise. |
| 96 | + virtual bool callback(const Criteria &state, const TVector &x) { return true; } |
| 97 | + |
| 98 | + /// @brief Callback function used Determine if the solver should stop. |
| 99 | + /// @param x Current solution. |
| 100 | + /// @return True if the solver should stop, false otherwise. |
44 | 101 | virtual bool stop(const TVector &x) { return false; } |
45 | 102 |
|
| 103 | + /// --- Misc ---------------------------------------------------------- |
| 104 | + |
| 105 | + /// @brief Sample the function along a direction. |
| 106 | + /// @param[in] x Starting point. |
| 107 | + /// @param[in] direction Direction to sample along. |
| 108 | + /// @param[in] start Starting step size. |
| 109 | + /// @param[in] end Ending step size. |
| 110 | + /// @param[in] num_samples Number of samples to take. |
| 111 | + /// @param[out] alphas Sampled step sizes. |
| 112 | + /// @param[out] fs Sampled function values. |
| 113 | + /// @param[out] valid If each sample is valid. |
46 | 114 | void sample_along_direction( |
47 | 115 | const Problem::TVector &x, |
48 | 116 | const Problem::TVector &direction, |
|
0 commit comments