Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mdivide_right.hpp
Go to the documentation of this file.
1 #ifndef STAN__AGRAD__FWD__MATRIX__COLUMNS_MDIVIDE_RIGHT_HPP
2 #define STAN__AGRAD__FWD__MATRIX__COLUMNS_MDIVIDE_RIGHT_HPP
3 
4 #include <vector>
10 #include <stan/agrad/fwd/fvar.hpp>
19 
20 namespace stan {
21  namespace agrad {
22 
23  template <typename T, int R1,int C1,int R2,int C2>
24  inline
25  Eigen::Matrix<fvar<T>,R1,C2>
26  mdivide_right(const Eigen::Matrix<fvar<T>,R1,C1> &A,
27  const Eigen::Matrix<fvar<T>,R2,C2> &b) {
28 
29  using stan::math::multiply;
31  stan::math::check_square("mdivide_right(%1%)",b,"b",(double*)0);
32  stan::math::check_multiplicable("mdivide_right(%1%)",A,"A",
33  b,"b",(double*)0);
34 
35  Eigen::Matrix<T,R1,C2> A_mult_inv_b(A.rows(),b.cols());
36  Eigen::Matrix<T,R1,C2> deriv_A_mult_inv_b(A.rows(),b.cols());
37  Eigen::Matrix<T,R2,C2> deriv_b_mult_inv_b(b.rows(),b.cols());
38  Eigen::Matrix<T,R1,C1> val_A(A.rows(),A.cols());
39  Eigen::Matrix<T,R1,C1> deriv_A(A.rows(),A.cols());
40  Eigen::Matrix<T,R2,C2> val_b(b.rows(),b.cols());
41  Eigen::Matrix<T,R2,C2> deriv_b(b.rows(),b.cols());
42 
43  for (int j = 0; j < A.cols(); j++) {
44  for(int i = 0; i < A.rows(); i++) {
45  val_A(i,j) = A(i,j).val_;
46  deriv_A(i,j) = A(i,j).d_;
47  }
48  }
49 
50  for (int j = 0; j < b.cols(); j++) {
51  for(int i = 0; i < b.rows(); i++) {
52  val_b(i,j) = b(i,j).val_;
53  deriv_b(i,j) = b(i,j).d_;
54  }
55  }
56 
57  A_mult_inv_b = mdivide_right(val_A, val_b);
58  deriv_A_mult_inv_b = mdivide_right(deriv_A, val_b);
59  deriv_b_mult_inv_b = mdivide_right(deriv_b, val_b);
60 
61  Eigen::Matrix<T,R1,C2> deriv(A.rows(), b.cols());
62  deriv = deriv_A_mult_inv_b - multiply(A_mult_inv_b, deriv_b_mult_inv_b);
63 
64  return stan::agrad::to_fvar(A_mult_inv_b, deriv);
65  }
66 
67  template <typename T, int R1,int C1,int R2,int C2>
68  inline
69  Eigen::Matrix<fvar<T>,R1,C2>
70  mdivide_right(const Eigen::Matrix<fvar<T>,R1,C1> &A,
71  const Eigen::Matrix<double,R2,C2> &b) {
72 
73  using stan::math::multiply;
75  stan::math::check_square("mdivide_right(%1%)",b,"b",(double*)0);
76  stan::math::check_multiplicable("mdivide_right(%1%)",A,"A",
77  b,"b",(double*)0);
78 
79  Eigen::Matrix<T,R2,C2> deriv_b_mult_inv_b(b.rows(),b.cols());
80  Eigen::Matrix<T,R1,C1> val_A(A.rows(),A.cols());
81  Eigen::Matrix<T,R1,C1> deriv_A(A.rows(),A.cols());
82 
83  for (int j = 0; j < A.cols(); j++) {
84  for(int i = 0; i < A.rows(); i++) {
85  val_A(i,j) = A(i,j).val_;
86  deriv_A(i,j) = A(i,j).d_;
87  }
88  }
89 
90  return stan::agrad::to_fvar(mdivide_right(val_A, b),
91  mdivide_right(deriv_A, b));
92  }
93 
94  template <typename T, int R1,int C1,int R2,int C2>
95  inline
96  Eigen::Matrix<fvar<T>,R1,C2>
97  mdivide_right(const Eigen::Matrix<double,R1,C1> &A,
98  const Eigen::Matrix<fvar<T>,R2,C2> &b) {
99 
100  using stan::math::multiply;
102  stan::math::check_square("mdivide_right(%1%)",b,"b",(double*)0);
103  stan::math::check_multiplicable("mdivide_right(%1%)",A,"A",
104  b,"b",(double*)0);
105  Eigen::Matrix<T,R1,C2>
106  A_mult_inv_b(A.rows(),b.cols());
107  Eigen::Matrix<T,R2,C2> deriv_b_mult_inv_b(b.rows(),b.cols());
108  Eigen::Matrix<T,R2,C2> val_b(b.rows(),b.cols());
109  Eigen::Matrix<T,R2,C2> deriv_b(b.rows(),b.cols());
110 
111  for (int j = 0; j < b.cols(); j++) {
112  for(int i = 0; i < b.rows(); i++) {
113  val_b(i,j) = b(i,j).val_;
114  deriv_b(i,j) = b(i,j).d_;
115  }
116  }
117 
118  A_mult_inv_b = mdivide_right(A, val_b);
119  deriv_b_mult_inv_b = mdivide_right(deriv_b, val_b);
120 
121  Eigen::Matrix<T,R1,C2>
122  deriv(A.rows(), b.cols());
123  deriv = -multiply(A_mult_inv_b, deriv_b_mult_inv_b);
124 
125  return stan::agrad::to_fvar(A_mult_inv_b, deriv);
126  }
127  }
128 }
129 #endif
Eigen::Matrix< fvar< T >, R1, C2 > mdivide_right(const Eigen::Matrix< fvar< T >, R1, C1 > &A, const Eigen::Matrix< fvar< T >, R2, C2 > &b)
Eigen::Matrix< typename boost::math::tools::promote_args< T1, T2 >::type, R1, C2 > mdivide_right(const Eigen::Matrix< T1, R1, C1 > &b, const Eigen::Matrix< T2, R2, C2 > &A)
Returns the solution of the system Ax=b.
fvar< T > to_fvar(const T &x)
Definition: to_fvar.hpp:17
Eigen::Matrix< fvar< T >, R1, C1 > multiply(const Eigen::Matrix< fvar< T >, R1, C1 > &m, const fvar< T > &c)
Definition: multiply.hpp:21
bool check_multiplicable(const char *function, const T1 &y1, const char *name1, const T2 &y2, const char *name2, T_result *result)
boost::enable_if_c< boost::is_arithmetic< T >::value, Eigen::Matrix< double, R, C > >::type multiply(const Eigen::Matrix< double, R, C > &m, T c)
Return specified matrix multiplied by specified scalar.
Definition: multiply.hpp:25
bool check_square(const char *function, const Eigen::Matrix< T_y, Eigen::Dynamic, Eigen::Dynamic > &y, const char *name, T_result *result)
Return true if the specified matrix is square.

     [ Stan Home Page ] © 2011–2014, Stan Development Team.