Automatic Differentiation
 
Loading...
Searching...
No Matches
mdivide_left_ldlt.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUN_MDIVIDE_LEFT_LDLT_HPP
2#define STAN_MATH_REV_FUN_MDIVIDE_LEFT_LDLT_HPP
3
12#include <memory>
13
14namespace stan {
15namespace math {
16
26template <typename T1, typename T2, require_all_matrix_t<T1, T2>* = nullptr,
27 require_any_st_var<T1, T2>* = nullptr>
28inline auto mdivide_left_ldlt(LDLT_factor<T1>& A, const T2& B) {
29 using ret_val_type
30 = Eigen::Matrix<double, Eigen::Dynamic, T2::ColsAtCompileTime>;
32
33 check_multiplicable("mdivide_left_ldlt", "A", A.matrix().val(), "B", B);
34
35 if (A.matrix().size() == 0) {
36 return ret_type(ret_val_type(0, B.cols()));
37 }
38
41 arena_t<promote_scalar_t<var, T1>> arena_A = A.matrix();
42 arena_t<ret_type> res = A.ldlt().solve(arena_B.val());
43 const auto* ldlt_ptr = make_chainable_ptr(A.ldlt());
44
45 reverse_pass_callback([arena_A, arena_B, ldlt_ptr, res]() mutable {
46 promote_scalar_t<double, T2> adjB = ldlt_ptr->solve(res.adj());
47
48 arena_A.adj() -= adjB * res.val_op().transpose();
49 arena_B.adj() += adjB;
50 });
51
52 return ret_type(res);
53 } else if (!is_constant<T1>::value) {
54 arena_t<promote_scalar_t<var, T1>> arena_A = A.matrix();
55 arena_t<ret_type> res = A.ldlt().solve(value_of(B));
56 const auto* ldlt_ptr = make_chainable_ptr(A.ldlt());
57
58 reverse_pass_callback([arena_A, ldlt_ptr, res]() mutable {
59 arena_A.adj() -= ldlt_ptr->solve(res.adj()) * res.val_op().transpose();
60 });
61
62 return ret_type(res);
63 } else {
65 arena_t<ret_type> res = A.ldlt().solve(arena_B.val());
66 const auto* ldlt_ptr = make_chainable_ptr(A.ldlt());
67
68 reverse_pass_callback([arena_B, ldlt_ptr, res]() mutable {
69 arena_B.adj() += ldlt_ptr->solve(res.adj());
70 });
71
72 return ret_type(res);
73 }
74}
75
76} // namespace math
77} // namespace stan
78#endif
LDLT_factor is a structure that holds a matrix of type T and the LDLT of its values.
void check_multiplicable(const char *function, const char *name1, const T1 &y1, const char *name2, const T2 &y2)
Check if the matrices can be multiplied.
typename promote_scalar_type< std::decay_t< T >, std::decay_t< S > >::type promote_scalar_t
void reverse_pass_callback(F &&functor)
Puts a callback on the autodiff stack to be called in reverse pass.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition value_of.hpp:18
auto make_chainable_ptr(T &&obj)
Store the given object in a chainable_object so it is destructed only when the chainable stack memory...
Eigen::Matrix< value_type_t< EigMat >, Eigen::Dynamic, EigMat::ColsAtCompileTime > mdivide_left_ldlt(LDLT_factor< T > &A, const EigMat &b)
Returns the solution of the system Ax=b given an LDLT_factor of A.
std::conditional_t< is_any_var_matrix< ReturnType, Types... >::value, stan::math::var_value< stan::math::promote_scalar_t< double, ReturnType > >, stan::math::promote_scalar_t< stan::math::var_value< double >, ReturnType > > promote_var_matrix_t
Given an Eigen type and several inputs, determine if a matrix should be var<Matrix> or Matrix<var>.
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 ...
Metaprogramming struct to detect whether a given type is constant in the mathematical sense (not the ...