inline Eigen::Matrix<typename boost::math::tools::promote_args<T1,T2>::type,R1,C2> mdivide_right_ldlt(const Eigen::Matrix<T1,R1,C1> &b, const stan::math::LDLT_factor<T2,R2,C2> &A) { stan::math::validate_multiplicable(b,A,"mdivide_right_ldlt"); return transpose(mdivide_left_ldlt(A,transpose(b))); }
inline Eigen::Matrix<fvar<T2>,R1,C2> mdivide_left_ldlt(const stan::math::LDLT_factor<double,R1,C1> &A, const Eigen::Matrix<fvar<T2>,R2,C2> &b) { stan::math::check_multiplicable("mdivide_left_ldlt", "A", A, "b", b); Eigen::Matrix<T2,R2,C2> b_val(b.rows(), b.cols()); Eigen::Matrix<T2,R2,C2> b_der(b.rows(), b.cols()); for (int i = 0; i < b.rows(); i++) for (int j = 0; j < b.cols(); j++) { b_val(i,j) = b(i,j).val_; b_der(i,j) = b(i,j).d_; } return to_fvar(mdivide_left_ldlt(A, b_val), mdivide_left_ldlt(A, b_der)); }
TEST(MathMatrix,mdivide_left_ldlt_val) { stan::math::LDLT_factor<double,-1,-1> ldlt_Ad; stan::math::matrix_d Ad(2,2); stan::math::matrix_d I; Ad << 2.0, 3.0, 3.0, 7.0; ldlt_Ad.compute(Ad); ASSERT_TRUE(ldlt_Ad.success()); I = mdivide_left_ldlt(ldlt_Ad,Ad); EXPECT_NEAR(1.0,I(0,0),1.0E-12); EXPECT_NEAR(0.0,I(0,1),1.0E-12); EXPECT_NEAR(0.0,I(1,0),1.0E-12); EXPECT_NEAR(1.0,I(1,1),1.0e-12); }
inline typename boost::enable_if_c<!stan::is_var<T1>::value && !stan::is_var<T2>::value && !stan::is_var<T3>::value, typename boost::math::tools::promote_args<T1,T2,T3>::type>::type trace_gen_inv_quad_form_ldlt(const Eigen::Matrix<T1,R1,C1> &D, const stan::math::LDLT_factor<T2,R2,C2> &A, const Eigen::Matrix<T3,R3,C3> &B) { stan::math::check_square("trace_gen_inv_quad_form_ldlt", "D", D); stan::math::check_multiplicable("trace_gen_inv_quad_form_ldlt", "A", A, "B", B); stan::math::check_multiplicable("trace_gen_inv_quad_form_ldlt", "B", B, "D", D); return trace(multiply(multiply(D,transpose(B)),mdivide_left_ldlt(A,B))); }