6#include <pybind11/attr.h>
7#include <pybind11/cast.h>
8#include <pybind11/chrono.h>
9#include <pybind11/detail/common.h>
10#include <pybind11/eigen.h>
11#include <pybind11/functional.h>
12#include <pybind11/iostream.h>
13#include <pybind11/pybind11.h>
14#include <pybind11/pytypes.h>
15#include <pybind11/stl.h>
28namespace py = pybind11;
31 using py::operator
""_a;
43 options.enable_function_signatures();
44 options.enable_user_defined_docstrings();
46 m.doc() =
"Quala Quasi-Newton algorithms";
48#ifdef QUALA_VERSION_INFO
49 m.attr(
"__version__") = QUALA_VERSION_INFO;
51 m.attr(
"__version__") =
"dev";
54 py::class_<LimitedMemoryQR>(m,
"LimitedMemoryQR")
56 .def(py::init<length_t, length_t>(),
"n"_a,
"m"_a)
57 .def_property_readonly(
"n", &LimitedMemoryQR::n)
58 .def_property_readonly(
"m", &LimitedMemoryQR::m)
59 .def_property_readonly(
"size", &LimitedMemoryQR::size)
60 .def_property_readonly(
"history", &LimitedMemoryQR::history)
61 .def(
"add_column", &LimitedMemoryQR::add_column<crvec>,
"v"_a)
62 .def(
"remove_column", &LimitedMemoryQR::remove_column)
65 [](
const LimitedMemoryQR &qr, crmat b, rmat x, real_t tol) { qr.solve(b, x, tol); },
66 "b"_a,
"x"_a,
"tol"_a = 0)
69 [](
const LimitedMemoryQR &qr, crmat b, real_t tol) -> mat {
70 mat x(qr.num_columns(), b.cols());
75 .def_property_readonly(
"R", &LimitedMemoryQR::get_R)
76 .def_property_readonly(
"Q", &LimitedMemoryQR::get_Q)
77 .def(
"reset", &LimitedMemoryQR::reset)
78 .def(
"resize", &LimitedMemoryQR::resize)
79 .def_property_readonly(
"num_columns", &LimitedMemoryQR::num_columns)
80 .def_property_readonly(
"min_eig", &LimitedMemoryQR::get_min_eig)
81 .def_property_readonly(
"max_eig", &LimitedMemoryQR::get_max_eig)
82 .def_property_readonly(
"current_history", &LimitedMemoryQR::current_history)
83 .def_property_readonly(
"reorth_count", &LimitedMemoryQR::get_reorth_count)
84 .def(
"clear_reorth_count", &LimitedMemoryQR::clear_reorth_count);
86 py::class_<quala::LBFGSParams::CBFGSParams>(
87 m,
"LBFGSParamsCBFGS",
"C++ documentation: :cpp:member:`quala::LBFGSParams::CBFGSParams `")
89 .def(py::init(&kwargs_to_struct<quala::LBFGSParams::CBFGSParams>))
90 .def(
"to_dict", &struct_to_dict<quala::LBFGSParams::CBFGSParams>)
93 .def(
"__bool__", &quala::LBFGSParams::CBFGSParams::operator
bool);
95 py::class_<quala::LBFGSParams>(m,
"LBFGSParams",
96 "C++ documentation: :cpp:class:`quala::LBFGSParams`")
98 .def(py::init(&kwargs_to_struct<quala::LBFGSParams>))
99 .def(
"to_dict", &struct_to_dict<quala::LBFGSParams>)
107 py::class_<quala::LBFGS>(m,
"LBFGS",
"C++ documentation: :cpp:class:`quala::LBFGS`");
108 auto lbfgssign = py::enum_<quala::LBFGS::Sign>(
109 lbfgs,
"Sign",
"C++ documentation :cpp:enum:`quala::LBFGS::Sign`");
115 .def(py::init<quala::LBFGS::Params>(),
"params"_a)
117 return {kwargs_to_struct<quala::LBFGS::Params>(params)};
120 .def(py::init<quala::LBFGS::Params, length_t>(),
"params"_a,
"n"_a)
121 .def(py::init([](py::dict params, length_t n) ->
quala::LBFGS {
122 return {kwargs_to_struct<quala::LBFGS::Params>(params), n};
129 [](
quala::LBFGS &self, crvec xk, crvec xkp1, crvec pk, crvec pkp1,
131 if (xk.size() != self.
n())
132 throw std::invalid_argument(
"xk dimension mismatch");
133 if (xkp1.size() != self.
n())
134 throw std::invalid_argument(
"xkp1 dimension mismatch");
135 if (pk.size() != self.
n())
136 throw std::invalid_argument(
"pk dimension mismatch");
137 if (pkp1.size() != self.
n())
138 throw std::invalid_argument(
"pkp1 dimension mismatch");
139 return self.
update(xk, xkp1, pk, pkp1, sign, forced);
145 [](
quala::LBFGS &self, crvec sk, crvec yk, real_t pkp1Tpkp1,
bool forced) {
146 if (sk.size() != self.
n())
147 throw std::invalid_argument(
"sk dimension mismatch");
148 if (yk.size() != self.
n())
149 throw std::invalid_argument(
"yk dimension mismatch");
150 return self.
update_sy(sk, yk, pkp1Tpkp1, forced);
152 "sk"_a,
"yk"_a,
"pkp1Tpkp1"_a,
"forced"_a =
false)
156 if (q.size() != self.
n())
157 throw std::invalid_argument(
"q dimension mismatch");
158 return self.
apply(q, γ);
163 [](
quala::LBFGS &self, rvec q, real_t γ,
const std::vector<vec::Index> &J) {
164 return self.
apply(q, γ, J);
172 .def(
"s", [](
quala::LBFGS &self, index_t i) -> rvec {
return self.
s(i); })
173 .def(
"y", [](
quala::LBFGS &self, index_t i) -> rvec {
return self.
y(i); })
174 .def(
"ρ", [](
quala::LBFGS &self, index_t i) -> real_t & {
return self.
ρ(i); })
175 .def(
"α", [](
quala::LBFGS &self, index_t i) -> real_t & {
return self.
α(i); })
178 py::class_<quala::AndersonAccelParams>(
179 m,
"AndersonAccelParams",
"C++ documentation: :cpp:class:`quala::AndersonAccelParams`")
181 .def(py::init(&kwargs_to_struct<quala::AndersonAccelParams>))
182 .def(
"to_dict", &struct_to_dict<quala::AndersonAccelParams>)
186 py::class_<quala::AndersonAccel>(m,
"AndersonAccel",
187 "C++ documentation: :cpp:class:`quala::AndersonAccel`")
188 .def(py::init<quala::AndersonAccel::Params>(),
"params"_a)
190 return {kwargs_to_struct<quala::AndersonAccel::Params>(params)};
193 .def(py::init<quala::AndersonAccel::Params, length_t>(),
"params"_a,
"n"_a)
195 return {kwargs_to_struct<quala::AndersonAccel::Params>(params), n};
202 if (g_0.size() != self.
n())
203 throw std::invalid_argument(
"g_0 dimension mismatch");
204 if (r_0.size() != self.
n())
205 throw std::invalid_argument(
"r_0 dimension mismatch");
206 self.initialize(g_0, std::move(r_0));
212 if (g_k.size() != self.
n())
213 throw std::invalid_argument(
"g_k dimension mismatch");
214 if (r_k.size() != self.
n())
215 throw std::invalid_argument(
"r_k dimension mismatch");
216 if (x_k_aa.size() != self.
n())
217 throw std::invalid_argument(
"x_k_aa dimension mismatch");
218 self.compute(g_k, std::move(r_k), x_k_aa);
220 "g_k"_a,
"r_k"_a,
"x_k_aa"_a)
224 if (g_k.size() != self.
n())
225 throw std::invalid_argument(
"g_k dimension mismatch");
226 if (r_k.size() != self.
n())
227 throw std::invalid_argument(
"r_k dimension mismatch");
229 self.compute(g_k, std::move(r_k), x_k_aa);
237 py::class_<quala::BroydenGoodParams>(m,
"BroydenGoodParams",
238 "C++ documentation: :cpp:class:`quala::BroydenGoodParams`")
240 .def(py::init(&kwargs_to_struct<quala::BroydenGoodParams>))
241 .def(
"to_dict", &struct_to_dict<quala::BroydenGoodParams>)
249 py::class_<quala::BroydenGood>(m,
"BroydenGood",
250 "C++ documentation: :cpp:class:`quala::BroydenGood`")
251 .def(py::init<quala::BroydenGood::Params>(),
"params"_a)
253 return {kwargs_to_struct<quala::BroydenGood::Params>(params)};
256 .def(py::init<quala::BroydenGood::Params, length_t>(),
"params"_a,
"n"_a)
258 return {kwargs_to_struct<quala::BroydenGood::Params>(params), n};
264 [](
quala::BroydenGood &self, crvec xk, crvec xkp1, crvec pk, crvec pkp1,
bool forced) {
265 if (xk.size() != self.
n())
266 throw std::invalid_argument(
"xk dimension mismatch");
267 if (xkp1.size() != self.
n())
268 throw std::invalid_argument(
"xkp1 dimension mismatch");
269 if (pk.size() != self.
n())
270 throw std::invalid_argument(
"pk dimension mismatch");
271 if (pkp1.size() != self.
n())
272 throw std::invalid_argument(
"pkp1 dimension mismatch");
273 return self.
update(xk, xkp1, pk, pkp1, forced);
275 "xk"_a,
"xkp1"_a,
"pk"_a,
"pkp1"_a,
"forced"_a =
false)
279 if (sk.size() != self.
n())
280 throw std::invalid_argument(
"sk dimension mismatch");
281 if (yk.size() != self.
n())
282 throw std::invalid_argument(
"yk dimension mismatch");
285 "sk"_a,
"yk"_a,
"forced"_a =
false)
289 if (q.size() != self.
n())
290 throw std::invalid_argument(
"q dimension mismatch");
291 return self.
apply(q, γ);
length_t current_history() const
Get the number of columns currently stored in the buffer.
const Params & get_params() const
Get the parameters.
void resize(length_t n)
Change the problem dimension.
void reset()
Reset the accelerator (but keep the last function value and residual, so calling initialize is not ne...
Broyden's “Good” method for solving systems of nonlinear equations .
length_t current_history() const
Get the number of previous s and y vectors currently stored in the buffer.
const Params & get_params() const
Get the parameters.
void resize(length_t n)
Re-allocate storage for a problem with a different size.
void reset()
Throw away the approximation and all previous vectors s and y.
Limited memory Broyden–Fletcher–Goldfarb–Shanno (L-BFGS) algorithm.
static bool update_valid(const LBFGSParams ¶ms, real_t yᵀs, real_t sᵀs, real_t pᵀp)
Check if the new vectors s and y allow for a valid BFGS update that preserves the positive definitene...
length_t current_history() const
Get the number of previous s and y vectors currently stored in the buffer.
length_t n() const
Get the size of the s and y vectors in the buffer.
const Params & get_params() const
Get the parameters.
bool apply(rvec q, real_t γ=-1)
Apply the inverse Hessian approximation to the given vector q.
void resize(length_t n)
Re-allocate storage for a problem with a different size.
void reset()
Throw away the approximation and all previous vectors s and y.
Sign
The sign of the vectors passed to the LBFGS::update method.
void scale_y(real_t factor)
Scale the stored y vectors by the given factor.
bool update(crvec xₖ, crvec xₙₑₓₜ, crvec pₖ, crvec pₙₑₓₜ, Sign sign=Sign::Positive, bool forced=false)
Update the inverse Hessian approximation using the new vectors xₖ₊₁ and pₖ₊₁.
bool update_sy(const anymat< VecS > &s, const anymat< VecY > &y, real_t pₙₑₓₜᵀpₙₑₓₜ, bool forced=false)
Update the inverse Hessian approximation using the new vectors sₖ = xₖ₊₁ - xₖ and yₖ = pₖ₊₁ - pₖ.
Incremental QR factorization using modified Gram-Schmidt with reorthogonalization.
This file defines mappings from Python dicts (kwargs) to simple parameter structs.
real_t powell_damping_factor
Powell's trick, damping, prevents nonsingularity.
Eigen::Ref< const vec > crvec
Default type for immutable references to vectors.
real_t min_abs_s
Reject update if .
real_t min_div_abs
Reject update if .
CBFGSParams cbfgs
Parameters in the cautious BFGS update condition.
bool restarted
If set to true, the buffer is cleared after memory iterations.
Eigen::Ref< const mat > crmat
Default type for immutable references to matrices.
length_t memory
Length of the history to keep.
realmat mat
Default type for matrices.
index_t length_t
Default type for vector sizes.
real_t min_stepsize
Minimum automatic step size.
real_t min_div
Minimum divisor when solving close to singular systems, scaled by the maximum eigenvalue of R.
bool force_pos_def
If set to true, the inverse Hessian estimate should remain definite, i.e.
realvec vec
Default type for vectors.
Eigen::Index index_t
Default type for vector indices.
Eigen::Ref< mat > rmat
Default type for mutable references to matrices.
double real_t
Default floating point type.
real_t min_div_fac
Reject update if .
Eigen::Ref< vec > rvec
Default type for mutable references to vectors.
PYBIND11_MODULE(QUALA_MODULE_NAME, m)
real_t ϵ
Set to zero to disable CBFGS check.