1#ifndef STAN_MATH_REV_FUNCTOR_SOLVE_POWELL_HPP
2#define STAN_MATH_REV_FUNCTOR_SOLVE_POWELL_HPP
12#include <unsupported/Eigen/NonLinearOptimization>
46template <
typename F,
typename T,
typename... Args,
47 require_eigen_vector_t<T>* =
nullptr>
49 const double relative_tolerance,
50 const double function_tolerance,
51 const int64_t max_num_steps,
const Args&... args) {
54 Eigen::HybridNonLinearSolver<hybrj_functor_solver<F>> solver(hfs);
57 solver.parameters.xtol = relative_tolerance;
58 solver.parameters.maxfev = max_num_steps;
62 if (solver.nfev >= max_num_steps) {
65 max_num_steps,
"(",
") was exceeded in the solve.");
70 double system_norm = f(x).stableNorm();
71 if (system_norm > function_tolerance) {
73 std::ostringstream message;
74 message <<
"the norm of the algebraic function is " << system_norm
75 <<
" but should be lower than the function "
78 function_tolerance,
"",
79 ". Consider decreasing the relative tolerance and "
80 "increasing max_num_steps.");
125template <
typename F,
typename T,
typename... Args,
129 const double relative_tolerance,
130 const double function_tolerance,
131 const int64_t max_num_steps,
132 std::ostream*
const msgs,
133 const Args&... args) {
135 auto args_vals_tuple = std::make_tuple(
to_ref(args)...);
137 auto f_wrt_x = [&args_vals_tuple, &f, msgs](
const auto& x) {
139 [&x, &f, msgs](
const auto&... args) {
return f(x, msgs, args...); },
150 f_wrt_x(x_ref),
"the vector of unknowns, x,", x_ref);
154 function_tolerance, max_num_steps);
186template <
typename F,
typename T,
typename... T_Args,
189 const F& f,
const T& x, std::ostream*
const msgs,
const T_Args&... args) {
190 double relative_tolerance = 1
e-10;
191 double function_tolerance = 1
e-6;
192 int64_t max_num_steps = 200;
193 const auto& args_ref_tuple = std::make_tuple(
to_ref(args)...);
195 [&](
const auto&... args_refs) {
197 max_num_steps, msgs, args_refs...);
249template <
typename F,
typename T1,
typename T2,
252 const F& f,
const T1& x,
const T2& y,
const std::vector<double>& dat,
253 const std::vector<int>& dat_int, std::ostream* msgs =
nullptr,
254 const double relative_tolerance = 1
e-10,
255 const double function_tolerance = 1
e-6,
256 const int64_t max_num_steps = 1
e+3) {
258 function_tolerance, max_num_steps, msgs, y, dat,
322template <
typename F,
typename T,
typename... T_Args,
326 const F& f,
const T& x,
const double relative_tolerance,
327 const double function_tolerance,
const int64_t max_num_steps,
328 std::ostream*
const msgs,
const T_Args&... args) {
332 [&](
const auto&... args) {
337 auto f_wrt_x = [&args_vals_tuple, &f, msgs](
const auto& x) {
339 [&x, &f, msgs](
const auto&... args) {
return f(x, msgs, args...); },
350 f_wrt_x(x_ref),
"the vector of unknowns, x,", x_ref);
354 function_tolerance, max_num_steps);
356 Eigen::MatrixXd Jf_x;
359 jacobian(f_wrt_x, x_ref, f_x, Jf_x);
361 using ret_type = Eigen::Matrix<
var, Eigen::Dynamic, -1>;
369 Eigen::VectorXd eta = -Jf_x_T_lu_ptr->solve(ret.adj().eval());
375 Eigen::VectorXd ret_val = ret.val();
377 [&](
const auto&... args) {
return eval(f(ret_val, msgs, args...)); },
384 return ret_type(ret);
A class following the RAII idiom to start and recover nested autodiff scopes.
require_all_t< std::is_arithmetic< scalar_type_t< std::decay_t< Types > > >... > require_all_st_arithmetic
Require all of the scalar types satisfy std::is_arithmetic.
require_t< is_eigen_vector< std::decay_t< T > > > require_eigen_vector_t
Require type satisfies is_eigen_vector.
require_all_t< is_eigen_vector< std::decay_t< Types > >... > require_all_eigen_vector_t
Require all of the types satisfy is_eigen_vector.
typename return_type< Ts... >::type return_type_t
Convenience type for the return type of the specified template parameters.
require_any_t< is_var< scalar_type_t< std::decay_t< Types > > >... > require_any_st_var
Require any of the scalar types satisfy is_var.
void jacobian(const F &f, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &x, Eigen::Matrix< T, Eigen::Dynamic, 1 > &fx, Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &J)
Eigen::Matrix< value_type_t< T2 >, Eigen::Dynamic, 1 > algebra_solver(const F &f, const T1 &x, const T2 &y, const std::vector< double > &dat, const std::vector< int > &dat_int, std::ostream *msgs=nullptr, const double relative_tolerance=1e-10, const double function_tolerance=1e-6, const int64_t max_num_steps=1e+3)
Return the solution to the specified system of algebraic equations given an initial guess,...
void check_nonnegative(const char *function, const char *name, const T_y &y)
Check if y is non-negative.
static constexpr double e()
Return the base of the natural logarithm.
auto make_unsafe_chainable_ptr(T &&obj)
Store the given object in a chainable_object so it is destructed only when the chainable stack memory...
void reverse_pass_callback(F &&functor)
Puts a callback on the autodiff stack to be called in reverse pass.
T eval(T &&arg)
Inputs which have a plain_type equal to the own time are forwarded unmodified (for Eigen expressions ...
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Eigen::Matrix< stan::return_type_t< T_Args... >, Eigen::Dynamic, 1 > solve_powell(const F &f, const T &x, std::ostream *const msgs, const T_Args &... args)
Return the solution to the specified system of algebraic equations given an initial guess,...
void throw_domain_error(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
Throw a domain error with a consistently formatted message.
auto make_chainable_ptr(T &&obj)
Store the given object in a chainable_object so it is destructed only when the chainable stack memory...
void check_matching_sizes(const char *function, const char *name1, const T_y1 &y1, const char *name2, const T_y2 &y2)
Check if two structures at the same size.
T & solve_powell_call_solver(const F &f, T &x, std::ostream *const msgs, const double relative_tolerance, const double function_tolerance, const int64_t max_num_steps, const Args &... args)
Solve algebraic equations using Powell solver.
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
void check_finite(const char *function, const char *name, const T_y &y)
Return true if all values in y are finite.
void check_nonzero_size(const char *function, const char *name, const T_y &y)
Check if the specified matrix/vector is of non-zero size.
void check_positive(const char *function, const char *name, const T_y &y)
Check if y is positive.
static void grad()
Compute the gradient for all variables starting from the end of the AD tape.
constexpr decltype(auto) apply(F &&f, Tuple &&t, PreArgs &&... pre_args)
Eigen::VectorXd solve_powell_tol(const F &f, const T &x, const double relative_tolerance, const double function_tolerance, const int64_t max_num_steps, std::ostream *const msgs, const Args &... args)
Return the solution to the specified system of algebraic equations given an initial guess,...
typename internal::arena_type_impl< std::decay_t< T > >::type arena_t
Determines a type that can be used in place of T that does any dynamic allocations on the AD stack.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
Adapt the non-variadic algebra_solver_newton and algebra_solver_powell arguemts to the variadic algeb...
A functor with the required operators to call Eigen's algebraic solver.