-
-
Notifications
You must be signed in to change notification settings - Fork 367
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,10 @@ | |
#include <stan/agrad/fwd/matrix/typedefs.hpp> | ||
#include <stan/agrad/fwd/matrix/inverse.hpp> | ||
#include <stan/agrad/fwd/matrix/multiply.hpp> | ||
#include <stan/math/matrix/multiply.hpp> | ||
#include <stan/agrad/fwd/matrix/to_fvar.hpp> | ||
#include <stan/math/matrix/inverse.hpp> | ||
#include <stan/agrad/fwd/matrix/inverse.hpp> | ||
|
||
namespace stan { | ||
namespace agrad { | ||
|
@@ -20,10 +24,43 @@ namespace stan { | |
mdivide_left(const Eigen::Matrix<fvar<T1>,R1,C1> &A, | ||
const Eigen::Matrix<fvar<T2>,R2,C2> &b) { | ||
|
||
using stan::agrad::multiply; | ||
using stan::math::multiply; | ||
using stan::agrad::inverse; | ||
using stan::math::inverse; | ||
stan::math::validate_square(A,"mdivide_left"); | ||
stan::math::validate_multiplicable(A,b,"mdivide_left"); | ||
|
||
return stan::agrad::multiply(stan::agrad::inverse(A), b); | ||
|
||
Eigen::Matrix<fvar<T1>,R1,C1> fvar_inv_A; | ||
fvar_inv_A = stan::agrad::inverse(A); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
|
||
Eigen::Matrix<typename stan::return_type<T1,T2>,R1,C2> inv_A_mult_b; | ||
Eigen::Matrix<typename stan::return_type<T1,T2>,R1,C2> val; | ||
Eigen::Matrix<T1,R1,C1> val_A; | ||
Eigen::Matrix<T1,R1,C2> inv_A; | ||
Eigen::Matrix<T1,R1,C1> deriv_A; | ||
Eigen::Matrix<T2,R2,C2> val_b; | ||
Eigen::Matrix<T2,R2,C2> deriv_b; | ||
|
||
for (int i = 0; i < A.rows(); i++) { | ||
for(int j = 0; j < A.cols(); j++) { | ||
inv_A(i,j) = fvar_inv_A(i,j).val_; | ||
val_A(i,j) = A(i,j).d_; | ||
deriv_A(i,j) = A(i,j).d_; | ||
val_b(i,j) = b(i,j).val_; | ||
deriv_b(i,j) = b(i,j).d_; | ||
} | ||
} | ||
|
||
inv_A_mult_b = multiply(inverse(val_A), val_b); | ||
|
||
Eigen::Matrix<typename stan::return_type<T1,T2>,R1,C2> deriv; | ||
deriv = multiply(inv_A, val_b); | ||
deriv = multiply(deriv_A, deriv); | ||
deriv = multiply(inv_A, deriv_b - deriv); | ||
|
||
return stan::agrad::to_fvar(inv_A_mult_b, deriv); | ||
} | ||
|
||
template <typename T1, typename T2, int R1,int C1,int R2,int C2> | ||
|
@@ -32,10 +69,38 @@ namespace stan { | |
mdivide_left(const Eigen::Matrix<fvar<T1>,R1,C1> &A, | ||
const Eigen::Matrix<T2,R2,C2> &b) { | ||
|
||
using stan::agrad::multiply; | ||
using stan::math::multiply; | ||
using stan::agrad::inverse; | ||
using stan::math::inverse; | ||
stan::math::validate_square(A,"mdivide_left"); | ||
stan::math::validate_multiplicable(A,b,"mdivide_left"); | ||
|
||
return stan::agrad::multiply(stan::agrad::inverse(A), b); | ||
|
||
Eigen::Matrix<fvar<T1>,R1,C1> fvar_inv_A; | ||
fvar_inv_A = stan::agrad::inverse(A); | ||
|
||
Eigen::Matrix<typename stan::return_type<T1,T2>,R1,C2> inv_A_mult_b; | ||
Eigen::Matrix<typename stan::return_type<T1,T2>,R1,C2> val; | ||
Eigen::Matrix<T1,R1,C1> val_A; | ||
Eigen::Matrix<T1,R1,C1> deriv_A; | ||
Eigen::Matrix<T1,R1,C1> inv_A; | ||
|
||
for (int i = 0; i < A.rows(); i++) { | ||
for(int j = 0; j < A.cols(); j++) { | ||
This comment has been minimized.
Sorry, something went wrong.
randommm
Member
|
||
inv_A(i,j) = fvar_inv_A(i,j).val_; | ||
val_A(i,j) = A(i,j).d_; | ||
deriv_A(i,j) = A(i,j).d_; | ||
} | ||
} | ||
|
||
inv_A_mult_b = multiply(inverse(val_A), b); | ||
|
||
Eigen::Matrix<typename stan::return_type<T1,T2>,R1,C2> deriv; | ||
deriv = multiply(inv_A, b); | ||
deriv = multiply(deriv_A, deriv); | ||
deriv = -multiply(inv_A, deriv); | ||
|
||
return stan::agrad::to_fvar(inv_A_mult_b, deriv); | ||
} | ||
|
||
template <typename T1, typename T2, int R1,int C1,int R2,int C2> | ||
|
@@ -44,10 +109,32 @@ namespace stan { | |
mdivide_left(const Eigen::Matrix<T1,R1,C1> &A, | ||
const Eigen::Matrix<fvar<T2>,R2,C2> &b) { | ||
|
||
using stan::agrad::multiply; | ||
using stan::math::multiply; | ||
using stan::agrad::inverse; | ||
using stan::math::inverse; | ||
stan::math::validate_square(A,"mdivide_left"); | ||
stan::math::validate_multiplicable(A,b,"mdivide_left"); | ||
|
||
return stan::agrad::multiply(stan::agrad::inverse(to_fvar(A)), b); | ||
|
||
Eigen::Matrix<T1,R1,C1> inv_A; | ||
inv_A = inverse(A); | ||
|
||
Eigen::Matrix<typename stan::return_type<T1,T2>,R1,C2> inv_A_mult_b; | ||
Eigen::Matrix<T2,R2,C2> deriv_b; | ||
Eigen::Matrix<T2,R2,C2> val_b; | ||
|
||
for (int i = 0; i < A.rows(); i++) { | ||
for(int j = 0; j < A.cols(); j++) { | ||
deriv_b(i,j) = b(i,j).d_; | ||
val_b(i,j) = b(i,j).val_; | ||
} | ||
} | ||
|
||
inv_A_mult_b = multiply(inv_A, val_b); | ||
|
||
Eigen::Matrix<typename stan::return_type<T1,T2>,R1,C2> deriv; | ||
deriv = multiply(inv_A, deriv_b); | ||
return stan::agrad::to_fvar(inv_A_mult_b, deriv); | ||
} | ||
} | ||
} | ||
|
We should not be taking inverses! A major application of left division like this is to avoid taking matrix inverses.
This code needs to be rewritten to follow the way the reverse-mode code works in terms of the linear algebra solvers.