Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Francesco Brarda
stan-math-petsc
Commits
ac75bde4
Unverified
Commit
ac75bde4
authored
7 years ago
by
Bob Carpenter
Committed by
GitHub
7 years ago
Browse files
Options
Download
Plain Diff
Merge pull request #904 from yizhang-cae/feature/892_rename_matrix_exp_action
Feature/892 rename matrix exp action
parents
92de17e7
a9b4cd32
No related merge requests found
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
stan/math/prim/mat.hpp
+2
-0
stan/math/prim/mat.hpp
stan/math/prim/mat/fun/matrix_exp_action_handler.hpp
+14
-18
stan/math/prim/mat/fun/matrix_exp_action_handler.hpp
stan/math/prim/mat/fun/matrix_exp_multiply.hpp
+30
-0
stan/math/prim/mat/fun/matrix_exp_multiply.hpp
stan/math/prim/mat/fun/scale_matrix_exp_multiply.hpp
+32
-0
stan/math/prim/mat/fun/scale_matrix_exp_multiply.hpp
stan/math/rev/mat.hpp
+2
-0
stan/math/rev/mat.hpp
stan/math/rev/mat/fun/matrix_exp_multiply.hpp
+36
-34
stan/math/rev/mat/fun/matrix_exp_multiply.hpp
stan/math/rev/mat/fun/scale_matrix_exp_multiply.hpp
+39
-0
stan/math/rev/mat/fun/scale_matrix_exp_multiply.hpp
test/unit/math/prim/mat/fun/matrix_exp_multiply_test.cpp
+59
-0
test/unit/math/prim/mat/fun/matrix_exp_multiply_test.cpp
test/unit/math/prim/mat/fun/scale_matrix_exp_multiply_test.cpp
+61
-0
...unit/math/prim/mat/fun/scale_matrix_exp_multiply_test.cpp
test/unit/math/rev/mat/fun/matrix_exp_action_handler_test.cpp
+126
-0
.../unit/math/rev/mat/fun/matrix_exp_action_handler_test.cpp
test/unit/math/rev/mat/fun/matrix_exp_multiply_test.cpp
+248
-0
test/unit/math/rev/mat/fun/matrix_exp_multiply_test.cpp
test/unit/math/rev/mat/fun/scale_matrix_exp_multiply_test.cpp
+206
-0
.../unit/math/rev/mat/fun/scale_matrix_exp_multiply_test.cpp
with
855 additions
and
52 deletions
+855
-52
stan/math/prim/mat.hpp
View file @
ac75bde4
...
...
@@ -158,6 +158,7 @@
#include <stan/math/prim/mat/fun/logit.hpp>
#include <stan/math/prim/mat/fun/make_nu.hpp>
#include <stan/math/prim/mat/fun/matrix_exp.hpp>
#include <stan/math/prim/mat/fun/matrix_exp_multiply.hpp>
#include <stan/math/prim/mat/fun/max.hpp>
#include <stan/math/prim/mat/fun/mdivide_left.hpp>
#include <stan/math/prim/mat/fun/mdivide_left_ldlt.hpp>
...
...
@@ -203,6 +204,7 @@
#include <stan/math/prim/mat/fun/rows.hpp>
#include <stan/math/prim/mat/fun/rows_dot_product.hpp>
#include <stan/math/prim/mat/fun/rows_dot_self.hpp>
#include <stan/math/prim/mat/fun/scale_matrix_exp_multiply.hpp>
#include <stan/math/prim/mat/fun/sd.hpp>
#include <stan/math/prim/mat/fun/segment.hpp>
#include <stan/math/prim/mat/fun/simplex_constrain.hpp>
...
...
This diff is collapsed.
Click to expand it.
stan/math/
rev
/mat/fun/matrix_exp_action_handler.hpp
→
stan/math/
prim
/mat/fun/matrix_exp_action_handler.hpp
View file @
ac75bde4
#ifndef STAN_MATH_
REV
_MAT_FUN_MATRIX_EXP_ACTION_HANDLER_HPP
#define STAN_MATH_
REV
_MAT_FUN_MATRIX_EXP_ACTION_HANDLER_HPP
#ifndef STAN_MATH_
PRIM
_MAT_FUN_MATRIX_EXP_ACTION_HANDLER_HPP
#define STAN_MATH_
PRIM
_MAT_FUN_MATRIX_EXP_ACTION_HANDLER_HPP
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/rev/core.hpp>
#include <vector>
double
l1norm
(
const
Eigen
::
MatrixXd
&
m
)
{
return
m
.
colwise
().
lpNorm
<
1
>
().
maxCoeff
();
}
namespace
stan
{
namespace
math
{
...
...
@@ -25,8 +20,18 @@ class matrix_exp_action_handler {
static
constexpr
int
p_max
=
8
;
static
constexpr
int
m_max
=
55
;
static
constexpr
double
tol
=
1.1e-16
;
static
const
std
::
vector
<
double
>
theta_m_single_precision
;
static
const
std
::
vector
<
double
>
theta_m_double_precision
;
// table 3.1 in the reference
const
std
::
vector
<
double
>
theta_m_single_precision
{
1.3e-1
,
1.0e0
,
2.2e0
,
3.6e0
,
4.9e0
,
6.3e0
,
7.7e0
,
9.1e0
,
1.1e1
,
1.2e1
,
1.3e1
};
const
std
::
vector
<
double
>
theta_m_double_precision
{
2.4e-3
,
1.4e-1
,
6.4e-1
,
1.4e0
,
2.4e0
,
3.5e0
,
4.7e0
,
6.0e0
,
7.2e0
,
8.5e0
,
9.9e0
};
double
l1norm
(
const
Eigen
::
MatrixXd
&
m
)
{
return
m
.
colwise
().
lpNorm
<
1
>
().
maxCoeff
();
}
public:
/* Constructor
...
...
@@ -116,15 +121,6 @@ class matrix_exp_action_handler {
}
};
// table 3.1 in the reference
const
std
::
vector
<
double
>
matrix_exp_action_handler
::
theta_m_single_precision
{
1.3e-1
,
1.0e0
,
2.2e0
,
3.6e0
,
4.9e0
,
6.3e0
,
7.7e0
,
9.1e0
,
1.1e1
,
1.2e1
,
1.3e1
};
const
std
::
vector
<
double
>
matrix_exp_action_handler
::
theta_m_double_precision
{
2.4e-3
,
1.4e-1
,
6.4e-1
,
1.4e0
,
2.4e0
,
3.5e0
,
4.7e0
,
6.0e0
,
7.2e0
,
8.5e0
,
9.9e0
};
}
// namespace math
}
// namespace stan
...
...
This diff is collapsed.
Click to expand it.
stan/math/prim/mat/fun/matrix_exp_multiply.hpp
0 → 100644
View file @
ac75bde4
#ifndef STAN_MATH_PRIM_MAT_FUN_MATRIX_EXP_MULTIPLY_HPP
#define STAN_MATH_PRIM_MAT_FUN_MATRIX_EXP_MULTIPLY_HPP
#include <stan/math/prim/mat.hpp>
#include <stan/math/prim/mat/fun/matrix_exp_action_handler.hpp>
namespace
stan
{
namespace
math
{
/**
* Return product of exp(A) and B, where A is a NxN double matrix,
* B is a NxCb double matrix, and t is a double
* @tparam Cb Columns matrix B
* @param[in] A Matrix
* @param[in] B Matrix
* @return exponential of A multiplies B
*/
template
<
int
Cb
>
inline
Eigen
::
Matrix
<
double
,
-
1
,
Cb
>
matrix_exp_multiply
(
const
Eigen
::
MatrixXd
&
A
,
const
Eigen
::
Matrix
<
double
,
-
1
,
Cb
>&
B
)
{
check_nonzero_size
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
A
);
check_nonzero_size
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
B
);
check_multiplicable
(
"scale_matrix_exp_multiply"
,
"A"
,
A
,
"B"
,
B
);
check_square
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
A
);
return
matrix_exp_action_handler
().
action
(
A
,
B
);
}
}
// namespace math
}
// namespace stan
#endif
This diff is collapsed.
Click to expand it.
stan/math/prim/mat/fun/scale_matrix_exp_multiply.hpp
0 → 100644
View file @
ac75bde4
#ifndef STAN_MATH_PRIM_MAT_FUN_SCALE_MATRIX_EXP_MULTIPLY_HPP
#define STAN_MATH_PRIM_MAT_FUN_SCALE_MATRIX_EXP_MULTIPLY_HPP
#include <stan/math/prim/mat.hpp>
#include <stan/math/prim/mat/fun/matrix_exp_action_handler.hpp>
namespace
stan
{
namespace
math
{
/**
* Return product of exp(At) and B, where A is a NxN double matrix,
* B is a NxCb double matrix, and t is a double
* @tparam Cb Columns matrix B
* @param[in] A Matrix
* @param[in] B Matrix
* @param[in] t double
* @return exponential of At multiplies B
*/
template
<
int
Cb
>
inline
Eigen
::
Matrix
<
double
,
-
1
,
Cb
>
scale_matrix_exp_multiply
(
const
double
&
t
,
const
Eigen
::
MatrixXd
&
A
,
const
Eigen
::
Matrix
<
double
,
-
1
,
Cb
>&
B
)
{
check_nonzero_size
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
A
);
check_nonzero_size
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
B
);
check_multiplicable
(
"scale_matrix_exp_multiply"
,
"A"
,
A
,
"B"
,
B
);
check_square
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
A
);
return
matrix_exp_action_handler
().
action
(
A
,
B
,
t
);
}
}
// namespace math
}
// namespace stan
#endif
This diff is collapsed.
Click to expand it.
stan/math/rev/mat.hpp
View file @
ac75bde4
...
...
@@ -30,6 +30,7 @@
#include <stan/math/rev/mat/fun/log_determinant_spd.hpp>
#include <stan/math/rev/mat/fun/log_softmax.hpp>
#include <stan/math/rev/mat/fun/log_sum_exp.hpp>
#include <stan/math/rev/mat/fun/matrix_exp_multiply.hpp>
#include <stan/math/rev/mat/fun/mdivide_left.hpp>
#include <stan/math/rev/mat/fun/mdivide_left_ldlt.hpp>
#include <stan/math/rev/mat/fun/mdivide_left_spd.hpp>
...
...
@@ -39,6 +40,7 @@
#include <stan/math/rev/mat/fun/quad_form.hpp>
#include <stan/math/rev/mat/fun/quad_form_sym.hpp>
#include <stan/math/rev/mat/fun/rows_dot_product.hpp>
#include <stan/math/rev/mat/fun/scale_matrix_exp_multiply.hpp>
#include <stan/math/rev/mat/fun/sd.hpp>
#include <stan/math/rev/mat/fun/softmax.hpp>
#include <stan/math/rev/mat/fun/squared_distance.hpp>
...
...
This diff is collapsed.
Click to expand it.
stan/math/rev/mat/fun/matrix_exp_
action
.hpp
→
stan/math/rev/mat/fun/matrix_exp_
multiply
.hpp
View file @
ac75bde4
#ifndef STAN_MATH_REV_MAT_FUN_MATRIX_EXP_
ACTION
_HPP
#define STAN_MATH_REV_MAT_FUN_MATRIX_EXP_
ACTION
_HPP
#ifndef STAN_MATH_REV_MAT_FUN_MATRIX_EXP_
MULTIPLY
_HPP
#define STAN_MATH_REV_MAT_FUN_MATRIX_EXP_
MULTIPLY
_HPP
#include <stan/math/rev/mat.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/
rev
/mat/fun/matrix_exp_action_handler.hpp>
#include <stan/math/
prim
/mat/fun/matrix_exp_action_handler.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/rev/mat/fun/to_var.hpp>
#include <stan/math/prim/mat/fun/matrix_exp.hpp>
...
...
@@ -20,47 +21,48 @@ namespace math {
* Calculate adjoint of matrix exponential action
* exp(At)*B when A is data and B is var, used for chaining action.
*
* @tparam N integer rows and cols of matrix A
* @param Ad double array pointer to the data of matrix A
* @param n dim of square matrix A
* @param adjexpAB MatrixXd adjoint of exp(At)*B
* @param t double time data
* @return MatrixXd The adjoint of B.
*/
template
<
int
N
>
Eigen
::
MatrixXd
exp_action_chain_dv
(
double
*
Ad
,
const
Eigen
::
MatrixXd
&
adjexpAB
,
const
double
t
)
{
inline
Eigen
::
MatrixXd
exp_action_chain_dv
(
double
*
Ad
,
const
int
&
n
,
const
Eigen
::
MatrixXd
&
adjexpAB
,
const
double
t
)
{
using
Eigen
::
Map
;
matrix_exp_action_handler
handle
;
return
handle
.
action
(
Map
<
Eigen
::
MatrixXd
>
(
Ad
,
N
,
N
).
transpose
(),
adjexpAB
,
t
);
return
handle
.
action
(
Map
<
Eigen
::
MatrixXd
>
(
Ad
,
n
,
n
).
transpose
(),
adjexpAB
,
t
);
}
/**
* Calculate adjoint of matrix exponential action
* exp(At)*B when A is var and B is data, used for chaining action.
*
* @tparam N integer rows and cols of matrix A
* @param Ad double array pointer to the data of matrix A
* @param Bd double array pointer to the data of matrix B
* @param n dim(nb. of rows) of square matrix A
* @param m nb. of cols of matrix B
* @param adjexpAB MatrixXd adjoint of exp(At)*B
* @param t double time data
* @return MatrixXd The adjoint of A.
*/
template
<
int
N
,
int
M
>
Eigen
::
MatrixXd
exp_action_chain_vd
(
double
*
Ad
,
double
*
Bd
,
const
Eigen
::
MatrixXd
&
adjexpAB
,
const
double
t
)
{
inline
Eigen
::
MatrixXd
exp_action_chain_vd
(
double
*
Ad
,
double
*
Bd
,
const
int
&
n
,
const
int
&
m
,
const
Eigen
::
MatrixXd
&
adjexpAB
,
const
double
t
)
{
using
Eigen
::
Map
;
using
Eigen
::
Matrix
;
using
Eigen
::
MatrixXd
;
Eigen
::
MatrixXd
adjexpA
=
Eigen
::
MatrixXd
::
Zero
(
N
,
N
);
Eigen
::
MatrixXd
adjA
=
Eigen
::
MatrixXd
::
Zero
(
N
,
N
);
Eigen
::
MatrixXd
adjexpA
=
Eigen
::
MatrixXd
::
Zero
(
n
,
n
);
Eigen
::
MatrixXd
adjA
=
Eigen
::
MatrixXd
::
Zero
(
n
,
n
);
// TODO(yizhang): a better way such as complex step approximation
try
{
start_nested
();
adjexpA
=
adjexpAB
*
Map
<
Matrix
<
double
,
N
,
M
>
>
(
Bd
).
transpose
();
Eigen
::
Matrix
<
stan
::
math
::
var
,
Eigen
::
Dynamic
,
Eigen
::
Dynamic
>
Av
(
N
,
N
);
adjexpA
=
adjexpAB
*
Map
<
Matrix
Xd
>
(
Bd
,
n
,
m
).
transpose
();
Eigen
::
Matrix
<
stan
::
math
::
var
,
Eigen
::
Dynamic
,
Eigen
::
Dynamic
>
Av
(
n
,
n
);
for
(
int
i
=
0
;
i
<
Av
.
size
();
++
i
)
{
Av
(
i
)
=
to_var
(
Ad
[
i
]);
}
...
...
@@ -163,8 +165,8 @@ class matrix_exp_action_vari : public vari {
for
(
size_type
i
=
0
;
i
<
adjexpAB
.
size
();
++
i
)
adjexpAB
(
i
)
=
variRefexpAB_
[
i
]
->
adj_
;
MatrixXd
adjA
=
exp_action_chain_vd
<
N
,
Cb
>
(
Ad_
,
Bd_
,
adjexpAB
,
t_
);
MatrixXd
adjB
=
exp_action_chain_dv
<
N
>
(
Ad_
,
adjexpAB
,
t_
);
MatrixXd
adjA
=
exp_action_chain_vd
(
Ad_
,
Bd_
,
n_
,
B_cols_
,
adjexpAB
,
t_
);
MatrixXd
adjB
=
exp_action_chain_dv
(
Ad
_
,
n
_
,
adjexpAB
,
t_
);
for
(
size_type
i
=
0
;
i
<
A_size_
;
++
i
)
{
variRefA_
[
i
]
->
adj_
+=
adjA
(
i
);
...
...
@@ -261,7 +263,7 @@ class matrix_exp_action_vari<double, N, Tb, Cb> : public vari {
for
(
size_type
i
=
0
;
i
<
adjexpAB
.
size
();
++
i
)
adjexpAB
(
i
)
=
variRefexpAB_
[
i
]
->
adj_
;
MatrixXd
adjB
=
exp_action_chain_dv
<
N
>
(
Ad_
,
adjexpAB
,
t_
);
MatrixXd
adjB
=
exp_action_chain_dv
(
Ad
_
,
n
_
,
adjexpAB
,
t_
);
for
(
size_type
i
=
0
;
i
<
B_size_
;
++
i
)
{
variRefB_
[
i
]
->
adj_
+=
adjB
(
i
);
...
...
@@ -352,7 +354,7 @@ class matrix_exp_action_vari<Ta, N, double, Cb> : public vari {
for
(
size_type
i
=
0
;
i
<
adjexpAB
.
size
();
++
i
)
adjexpAB
(
i
)
=
variRefexpAB_
[
i
]
->
adj_
;
MatrixXd
adjA
=
exp_action_chain_vd
<
N
,
Cb
>
(
Ad_
,
Bd_
,
adjexpAB
,
t_
);
MatrixXd
adjA
=
exp_action_chain_vd
(
Ad_
,
Bd_
,
n_
,
B_cols_
,
adjexpAB
,
t_
);
for
(
size_type
i
=
0
;
i
<
A_size_
;
++
i
)
{
variRefA_
[
i
]
->
adj_
+=
adjA
(
i
);
...
...
@@ -388,23 +390,23 @@ matrix_exp_action(const Eigen::Matrix<Ta, N, N>& A,
}
/**
*
Return product of exp(At) and B, where A is a NxN double matrix,
*
B is a NxCb double matrix, and t is a double
* @tparam
N Rows and cols matrix A, also rows of
matrix B
*
Wrapper of matrix_exp_action function for a more literal name
*
@tparam Ta scalar type matrix A
* @tparam
Tb scalar type
matrix B
* @tparam Cb Columns matrix B
* @param[in] A Matrix
* @param[in] B Matrix
* @param[in] t double
* @return exponential of At multiplies B
* @return exponential of A multiplies B
*/
template
<
int
N
,
int
Cb
>
inline
Eigen
::
Matrix
<
double
,
N
,
Cb
>
matrix_exp_action
(
const
Eigen
::
Matrix
<
double
,
N
,
N
>&
A
,
const
Eigen
::
Matrix
<
double
,
N
,
Cb
>&
B
,
const
double
&
t
=
1.0
)
{
Eigen
::
Matrix
<
double
,
N
,
Cb
>
expAB
;
matrix_exp_action_handler
handle
;
expAB
=
handle
.
action
(
A
,
B
,
t
);
return
expAB
;
template
<
typename
Ta
,
typename
Tb
,
int
Cb
>
inline
Eigen
::
Matrix
<
typename
stan
::
return_type
<
Ta
,
Tb
>::
type
,
-
1
,
Cb
>
matrix_exp_multiply
(
const
Eigen
::
Matrix
<
Ta
,
-
1
,
-
1
>&
A
,
const
Eigen
::
Matrix
<
Tb
,
-
1
,
Cb
>&
B
)
{
check_nonzero_size
(
"matrix_exp_multiply"
,
"input matrix"
,
A
);
check_nonzero_size
(
"matrix_exp_multiply"
,
"input matrix"
,
B
);
check_multiplicable
(
"matrix_exp_multiply"
,
"A"
,
A
,
"B"
,
B
);
check_square
(
"matrix_exp_multiply"
,
"input matrix"
,
A
);
return
matrix_exp_action
(
A
,
B
);
}
}
// namespace math
...
...
This diff is collapsed.
Click to expand it.
stan/math/rev/mat/fun/scale_matrix_exp_multiply.hpp
0 → 100644
View file @
ac75bde4
#ifndef STAN_MATH_REV_MAT_FUN_SCALE_MATRIX_EXP_MULTIPLY_HPP
#define STAN_MATH_REV_MAT_FUN_SCALE_MATRIX_EXP_MULTIPLY_HPP
#include <stan/math/prim/mat.hpp>
#include <stan/math/rev/mat/fun/matrix_exp_multiply.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <boost/math/tools/promotion.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <vector>
namespace
stan
{
namespace
math
{
/**
* Wrapper of matrix_exp_action function for a more literal name.
* @tparam Ta scalar type matrix A
* @tparam Tb scalar type matrix B
* @tparam Cb Columns matrix B
* @param[in] A Matrix
* @param[in] B Matrix
* @param[in] t double
* @return exponential of At multiplies B
*/
template
<
typename
Ta
,
typename
Tb
,
int
Cb
>
inline
Eigen
::
Matrix
<
typename
stan
::
return_type
<
Ta
,
Tb
>::
type
,
-
1
,
Cb
>
scale_matrix_exp_multiply
(
const
double
&
t
,
const
Eigen
::
Matrix
<
Ta
,
-
1
,
-
1
>&
A
,
const
Eigen
::
Matrix
<
Tb
,
-
1
,
Cb
>&
B
)
{
check_nonzero_size
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
A
);
check_nonzero_size
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
B
);
check_multiplicable
(
"scale_matrix_exp_multiply"
,
"A"
,
A
,
"B"
,
B
);
check_square
(
"scale_matrix_exp_multiply"
,
"input matrix"
,
A
);
return
matrix_exp_action
(
A
,
B
,
t
);
}
}
// namespace math
}
// namespace stan
#endif
This diff is collapsed.
Click to expand it.
test/unit/math/prim/mat/fun/matrix_exp_multiply_test.cpp
0 → 100644
View file @
ac75bde4
#include <gtest/gtest.h>
#include <test/unit/math/prim/mat/util.hpp>
#include <stan/math/prim/mat/fun/matrix_exp.hpp>
#include <stan/math/prim/mat/fun/matrix_exp_multiply.hpp>
#include <vector>
template
<
int
N
,
int
M
>
inline
void
test_matrix_exp_multiply
()
{
using
Eigen
::
Dynamic
;
using
Eigen
::
Matrix
;
using
stan
::
math
::
matrix_exp_multiply
;
std
::
srand
(
1999
);
Eigen
::
MatrixXd
A
=
Eigen
::
MatrixXd
::
Random
(
N
,
N
);
Eigen
::
Matrix
<
double
,
-
1
,
M
>
B
=
Eigen
::
MatrixXd
::
Random
(
N
,
M
);
Eigen
::
Matrix
<
double
,
Dynamic
,
Dynamic
>
A0
=
A
;
// brute force
Eigen
::
Matrix
<
double
,
N
,
M
>
expAB
=
stan
::
math
::
multiply
(
stan
::
math
::
matrix_exp
(
A0
),
B
);
// matrix_exp_multiply
Eigen
::
Matrix
<
double
,
N
,
M
>
res
=
matrix_exp_multiply
(
A
,
B
);
EXPECT_EQ
(
res
.
size
(),
expAB
.
size
());
for
(
int
l
=
0
;
l
<
res
.
size
();
++
l
)
{
EXPECT_FLOAT_EQ
(
res
(
l
),
expAB
(
l
));
}
}
TEST
(
MathMatrix
,
matrix_exp_multiply
)
{
test_matrix_exp_multiply
<
1
,
1
>
();
test_matrix_exp_multiply
<
1
,
5
>
();
test_matrix_exp_multiply
<
5
,
1
>
();
test_matrix_exp_multiply
<
5
,
5
>
();
test_matrix_exp_multiply
<
20
,
2
>
();
}
TEST
(
MathMatrix
,
matrix_exp_multiply_exception
)
{
using
stan
::
math
::
matrix_exp_multiply
;
{
// nonzero size
Eigen
::
MatrixXd
A
(
0
,
0
);
Eigen
::
MatrixXd
B
=
Eigen
::
MatrixXd
::
Random
(
1
,
2
);
EXPECT_THROW
(
matrix_exp_multiply
(
A
,
B
),
std
::
invalid_argument
);
EXPECT_THROW
(
matrix_exp_multiply
(
B
,
A
),
std
::
invalid_argument
);
}
{
// multiplicable
Eigen
::
MatrixXd
A
=
Eigen
::
MatrixXd
::
Random
(
2
,
2
);
Eigen
::
MatrixXd
B
=
Eigen
::
MatrixXd
::
Random
(
3
,
2
);
EXPECT_THROW
(
matrix_exp_multiply
(
A
,
B
),
std
::
invalid_argument
);
}
{
// square
Eigen
::
MatrixXd
A
=
Eigen
::
MatrixXd
::
Random
(
2
,
3
);
Eigen
::
MatrixXd
B
=
Eigen
::
MatrixXd
::
Random
(
3
,
2
);
EXPECT_THROW
(
matrix_exp_multiply
(
A
,
B
),
std
::
invalid_argument
);
}
}
This diff is collapsed.
Click to expand it.
test/unit/math/prim/mat/fun/scale_matrix_exp_multiply_test.cpp
0 → 100644
View file @
ac75bde4
#include <gtest/gtest.h>
#include <test/unit/math/prim/mat/util.hpp>
#include <stan/math/prim/mat/fun/matrix_exp.hpp>
#include <stan/math/prim/mat/fun/scale_matrix_exp_multiply.hpp>
#include <vector>
template
<
int
N
,
int
M
>
inline
void
test_scale_matrix_exp_multiply
()
{
using
Eigen
::
Dynamic
;
using
Eigen
::
Matrix
;
using
stan
::
math
::
scale_matrix_exp_multiply
;
std
::
srand
(
1999
);
Eigen
::
MatrixXd
A
=
Eigen
::
MatrixXd
::
Random
(
N
,
N
);
Eigen
::
Matrix
<
double
,
-
1
,
M
>
B
=
Eigen
::
MatrixXd
::
Random
(
N
,
M
);
Eigen
::
Matrix
<
double
,
Dynamic
,
Dynamic
>
A0
=
A
;
// brute force
Eigen
::
Matrix
<
double
,
N
,
M
>
expAB
=
stan
::
math
::
multiply
(
stan
::
math
::
matrix_exp
(
A0
),
B
);
// matrix_exp_multiply
const
double
t
=
1.0
;
Eigen
::
Matrix
<
double
,
N
,
M
>
res
=
scale_matrix_exp_multiply
(
t
,
A
,
B
);
EXPECT_EQ
(
res
.
size
(),
expAB
.
size
());
for
(
int
l
=
0
;
l
<
res
.
size
();
++
l
)
{
EXPECT_FLOAT_EQ
(
res
(
l
),
expAB
(
l
));
}
}
TEST
(
MathMatrix
,
scale_matrix_exp_multiply
)
{
test_scale_matrix_exp_multiply
<
1
,
1
>
();
test_scale_matrix_exp_multiply
<
1
,
5
>
();
test_scale_matrix_exp_multiply
<
5
,
1
>
();
test_scale_matrix_exp_multiply
<
5
,
5
>
();
test_scale_matrix_exp_multiply
<
20
,
2
>
();
}
TEST
(
MathMatrix
,
scale_matrix_exp_multiply_exception
)
{
using
stan
::
math
::
scale_matrix_exp_multiply
;
const
double
t
=
1.0
;
{
// nonzero size
Eigen
::
MatrixXd
A
(
0
,
0
);
Eigen
::
MatrixXd
B
=
Eigen
::
MatrixXd
::
Random
(
1
,
2
);
EXPECT_THROW
(
scale_matrix_exp_multiply
(
t
,
A
,
B
),
std
::
invalid_argument
);
EXPECT_THROW
(
scale_matrix_exp_multiply
(
t
,
B
,
A
),
std
::
invalid_argument
);
}
{
// multiplicable
Eigen
::
MatrixXd
A
=
Eigen
::
MatrixXd
::
Random
(
2
,
2
);
Eigen
::
MatrixXd
B
=
Eigen
::
MatrixXd
::
Random
(
3
,
2
);
EXPECT_THROW
(
scale_matrix_exp_multiply
(
t
,
A
,
B
),
std
::
invalid_argument
);
}
{
// square
Eigen
::
MatrixXd
A
=
Eigen
::
MatrixXd
::
Random
(
2
,
3
);
Eigen
::
MatrixXd
B
=
Eigen
::
MatrixXd
::
Random
(
3
,
2
);
EXPECT_THROW
(
scale_matrix_exp_multiply
(
t
,
A
,
B
),
std
::
invalid_argument
);
}
}
This diff is collapsed.
Click to expand it.
test/unit/math/rev/mat/fun/matrix_exp_action_handler_test.cpp
0 → 100644
View file @
ac75bde4
#include <gtest/gtest.h>
// #include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <test/unit/math/prim/mat/util.hpp>
#include <stan/math/prim/mat/fun/matrix_exp.hpp>
#include <stan/math/prim/mat/fun/matrix_exp_action_handler.hpp>
#include <vector>
TEST
(
MathMatrix
,
matrix_exp_action_diag
)
{
using
Eigen
::
MatrixXd
;
using
Eigen
::
VectorXd
;
stan
::
math
::
matrix_exp_action_handler
handler
;
{
double
t
=
0.5
;
MatrixXd
m1
(
2
,
2
);
VectorXd
b
(
2
);
m1
<<
2
,
0
,
0
,
2
;
b
<<
1
,
1
;
auto
res
=
handler
.
action
(
m1
,
b
,
t
);
EXPECT_NEAR
(
res
(
0
),
M_E
,
1.e-8
);
EXPECT_NEAR
(
res
(
1
),
M_E
,
1.e-8
);
}
{
double
t
=
1.0
;
MatrixXd
m1
(
2
,
2
);
VectorXd
b
=
VectorXd
::
Random
(
2
);
m1
<<
1
,
0
,
0
,
2
;
auto
res
=
handler
.
action
(
m1
,
b
,
t
);
EXPECT_NEAR
(
res
(
0
),
b
(
0
)
*
M_E
,
1.e-8
);
EXPECT_NEAR
(
res
(
1
),
b
(
1
)
*
M_E
*
M_E
,
1.e-8
);
}
{
double
t
=
1.0
;
std
::
srand
(
1299
);
MatrixXd
m1
(
2
,
2
);
VectorXd
b
=
VectorXd
::
Random
(
2
);
m1
<<
-
4.0
,
0
,
0
,
-
5.0
;
auto
res
=
handler
.
action
(
m1
,
b
,
t
);
EXPECT_NEAR
(
res
(
0
),
b
(
0
)
/
(
M_E
*
M_E
*
M_E
*
M_E
),
1.e-8
);
EXPECT_NEAR
(
res
(
1
),
b
(
1
)
/
(
M_E
*
M_E
*
M_E
*
M_E
*
M_E
),
1.e-8
);
}
{
std
::
srand
(
999
);
double
t
=
static_cast
<
double
>
((
std
::
rand
())
/
RAND_MAX
);
VectorXd
b
=
VectorXd
::
Random
(
5
);
VectorXd
d
=
VectorXd
::
Random
(
5
);
MatrixXd
m
=
d
.
asDiagonal
();
auto
res
=
handler
.
action
(
m
,
b
,
t
);
for
(
int
i
=
0
;
i
<
5
;
++
i
)
{
EXPECT_NEAR
(
res
(
i
),
b
(
i
)
*
std
::
exp
(
t
*
d
(
i
)),
1.e-8
);
}
}
}
TEST
(
MathMatrix
,
matrix_exp_action_vector
)
{
using
Eigen
::
MatrixXd
;
using
Eigen
::
VectorXd
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
999
);
for
(
size_t
n
=
2
;
n
<
10
;
++
n
)
{
MatrixXd
A
=
MatrixXd
::
Random
(
n
,
n
);
VectorXd
b
=
VectorXd
::
Random
(
n
);
VectorXd
res
=
handler
.
action
(
A
,
b
);
MatrixXd
expA
=
stan
::
math
::
matrix_exp
(
A
);
VectorXd
expb
=
expA
*
b
;
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
{
EXPECT_NEAR
(
res
(
i
),
expb
(
i
),
1.e-6
);
}
int
m1
,
s1
,
m2
,
s2
;
const
double
t1
=
9.9
,
t2
=
1.0
;
handler
.
set_approximation_parameter
(
A
,
t1
,
m1
,
s1
);
A
*=
t1
;
handler
.
set_approximation_parameter
(
A
,
t2
,
m2
,
s2
);
EXPECT_EQ
(
m1
,
m2
);
EXPECT_EQ
(
s1
,
s2
);
}
}
TEST
(
MathMatrix
,
matrix_exp_action_matrix
)
{
using
Eigen
::
MatrixXd
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
999
);
constexpr
int
N
=
10
;
constexpr
int
M
=
4
;
Eigen
::
Matrix
<
double
,
N
,
N
>
A
=
Eigen
::
Matrix
<
double
,
N
,
N
>::
Random
();
Eigen
::
Matrix
<
double
,
N
,
M
>
B
=
Eigen
::
Matrix
<
double
,
N
,
M
>::
Random
();
Eigen
::
Matrix
<
double
,
N
,
M
>
res
=
handler
.
action
(
A
,
B
);
MatrixXd
Ad
(
A
);
MatrixXd
expa
=
stan
::
math
::
matrix_exp
(
Ad
);
Eigen
::
Matrix
<
double
,
N
,
M
>
expb
=
expa
*
B
;
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
for
(
int
j
=
0
;
j
<
M
;
++
j
)
{
EXPECT_FLOAT_EQ
(
res
(
i
,
j
),
expb
(
i
,
j
));
}
}
}
TEST
(
MathMatrix
,
matrix_exp_action_matrix_transpose
)
{
using
Eigen
::
MatrixXd
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
1999
);
constexpr
int
N
=
10
;
constexpr
int
M
=
4
;
Eigen
::
Matrix
<
double
,
N
,
N
>
A
=
Eigen
::
Matrix
<
double
,
N
,
N
>::
Random
();
Eigen
::
Matrix
<
double
,
N
,
M
>
B
=
Eigen
::
Matrix
<
double
,
N
,
M
>::
Random
();
Eigen
::
Matrix
<
double
,
N
,
M
>
res
=
handler
.
action
(
A
.
transpose
(),
B
);
MatrixXd
Ad
(
A
);
MatrixXd
expa
=
stan
::
math
::
matrix_exp
(
Ad
).
transpose
();
Eigen
::
Matrix
<
double
,
N
,
M
>
expb
=
expa
*
B
;
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
for
(
int
j
=
0
;
j
<
M
;
++
j
)
{
EXPECT_NEAR
(
res
(
i
,
j
),
expb
(
i
,
j
),
1.e-6
);
}
}
}
This diff is collapsed.
Click to expand it.
test/unit/math/rev/mat/fun/matrix_exp_
action
_test.cpp
→
test/unit/math/rev/mat/fun/matrix_exp_
multiply
_test.cpp
View file @
ac75bde4
...
...
@@ -3,161 +3,33 @@
// #include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <test/unit/math/rev/mat/fun/util.hpp>
#include <test/unit/math/rev/mat/util.hpp>
#include <stan/math/rev/mat/fun/matrix_exp_action_handler.hpp>
#include <stan/math/rev/mat/fun/matrix_exp_action.hpp>
#include <stan/math/rev/mat/fun/matrix_exp_multiply.hpp>
#include <stan/math/rev/mat/fun/to_var.hpp>
#include <vector>
TEST
(
MathMatrix
,
matrix_exp_action_diag
)
{
using
MatrixType
=
Eigen
::
Matrix
<
double
,
Eigen
::
Dynamic
,
Eigen
::
Dynamic
>
;
using
VectorType
=
Eigen
::
Matrix
<
double
,
Eigen
::
Dynamic
,
1
>
;
stan
::
math
::
matrix_exp_action_handler
handler
;
{
double
t
=
0.5
;
MatrixType
m1
(
2
,
2
);
VectorType
b
(
2
);
m1
<<
2
,
0
,
0
,
2
;
b
<<
1
,
1
;
auto
res
=
handler
.
action
(
m1
,
b
,
t
);
EXPECT_NEAR
(
res
(
0
),
M_E
,
1.e-8
);
EXPECT_NEAR
(
res
(
1
),
M_E
,
1.e-8
);
}
{
double
t
=
1.0
;
MatrixType
m1
(
2
,
2
);
VectorType
b
=
VectorType
::
Random
(
2
);
m1
<<
1
,
0
,
0
,
2
;
auto
res
=
handler
.
action
(
m1
,
b
,
t
);
EXPECT_NEAR
(
res
(
0
),
b
(
0
)
*
M_E
,
1.e-8
);
EXPECT_NEAR
(
res
(
1
),
b
(
1
)
*
M_E
*
M_E
,
1.e-8
);
}
{
double
t
=
1.0
;
std
::
srand
(
1299
);
MatrixType
m1
(
2
,
2
);
VectorType
b
=
VectorType
::
Random
(
2
);
m1
<<
-
4.0
,
0
,
0
,
-
5.0
;
auto
res
=
handler
.
action
(
m1
,
b
,
t
);
EXPECT_NEAR
(
res
(
0
),
b
(
0
)
/
(
M_E
*
M_E
*
M_E
*
M_E
),
1.e-8
);
EXPECT_NEAR
(
res
(
1
),
b
(
1
)
/
(
M_E
*
M_E
*
M_E
*
M_E
*
M_E
),
1.e-8
);
}
{
std
::
srand
(
999
);
double
t
=
static_cast
<
double
>
((
std
::
rand
())
/
RAND_MAX
);
VectorType
b
=
VectorType
::
Random
(
5
);
VectorType
d
=
VectorType
::
Random
(
5
);
MatrixType
m
=
d
.
asDiagonal
();
auto
res
=
handler
.
action
(
m
,
b
,
t
);
for
(
int
i
=
0
;
i
<
5
;
++
i
)
{
EXPECT_NEAR
(
res
(
i
),
b
(
i
)
*
std
::
exp
(
t
*
d
(
i
)),
1.e-8
);
}
}
}
TEST
(
MathMatrix
,
matrix_exp_action_vector
)
{
using
MatrixType
=
Eigen
::
Matrix
<
double
,
Eigen
::
Dynamic
,
Eigen
::
Dynamic
>
;
using
VectorType
=
Eigen
::
Matrix
<
double
,
Eigen
::
Dynamic
,
1
>
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
999
);
for
(
size_t
n
=
2
;
n
<
10
;
++
n
)
{
MatrixType
A
=
MatrixType
::
Random
(
n
,
n
);
VectorType
b
=
VectorType
::
Random
(
n
);
VectorType
res
=
handler
.
action
(
A
,
b
);
MatrixType
expA
=
stan
::
math
::
matrix_exp
(
A
);
VectorType
expb
=
expA
*
b
;
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
{
EXPECT_NEAR
(
res
(
i
),
expb
(
i
),
1.e-6
);
}
int
m1
,
s1
,
m2
,
s2
;
const
double
t1
=
9.9
,
t2
=
1.0
;
handler
.
set_approximation_parameter
(
A
,
t1
,
m1
,
s1
);
A
*=
t1
;
handler
.
set_approximation_parameter
(
A
,
t2
,
m2
,
s2
);
EXPECT_EQ
(
m1
,
m2
);
EXPECT_EQ
(
s1
,
s2
);
}
}
TEST
(
MathMatrix
,
matrix_exp_action_matrix
)
{
using
MatrixType
=
Eigen
::
Matrix
<
double
,
Eigen
::
Dynamic
,
Eigen
::
Dynamic
>
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
999
);
constexpr
int
N
=
10
;
constexpr
int
M
=
4
;
Eigen
::
Matrix
<
double
,
N
,
N
>
A
=
Eigen
::
Matrix
<
double
,
N
,
N
>::
Random
();
Eigen
::
Matrix
<
double
,
N
,
M
>
B
=
Eigen
::
Matrix
<
double
,
N
,
M
>::
Random
();
Eigen
::
Matrix
<
double
,
N
,
M
>
res
=
handler
.
action
(
A
,
B
);
MatrixType
Ad
(
A
);
MatrixType
expa
=
stan
::
math
::
matrix_exp
(
Ad
);
Eigen
::
Matrix
<
double
,
N
,
M
>
expb
=
expa
*
B
;
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
for
(
int
j
=
0
;
j
<
M
;
++
j
)
{
EXPECT_FLOAT_EQ
(
res
(
i
,
j
),
expb
(
i
,
j
));
}
}
}
TEST
(
MathMatrix
,
matrix_exp_action_matrix_transpose
)
{
using
MatrixType
=
Eigen
::
Matrix
<
double
,
Eigen
::
Dynamic
,
Eigen
::
Dynamic
>
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
1999
);
constexpr
int
N
=
10
;
constexpr
int
M
=
4
;
Eigen
::
Matrix
<
double
,
N
,
N
>
A
=
Eigen
::
Matrix
<
double
,
N
,
N
>::
Random
();
Eigen
::
Matrix
<
double
,
N
,
M
>
B
=
Eigen
::
Matrix
<
double
,
N
,
M
>::
Random
();
Eigen
::
Matrix
<
double
,
N
,
M
>
res
=
handler
.
action
(
A
.
transpose
(),
B
);
MatrixType
Ad
(
A
);
MatrixType
expa
=
stan
::
math
::
matrix_exp
(
Ad
).
transpose
();
Eigen
::
Matrix
<
double
,
N
,
M
>
expb
=
expa
*
B
;
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
for
(
int
j
=
0
;
j
<
M
;
++
j
)
{
EXPECT_NEAR
(
res
(
i
,
j
),
expb
(
i
,
j
),
1.e-6
);
}
}
}
template
<
int
N
,
int
M
>
inline
void
test_matrix_exp_action_dv
()
{
inline
void
test_matrix_exp_multiply_dv
(
int
N
,
int
M
)
{
using
stan
::
math
::
value_of
;
using
stan
::
math
::
var
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
1999
);
Eigen
::
Matrix
<
var
,
N
,
N
>
Av
=
Eigen
::
Matrix
<
var
,
N
,
N
>::
Random
();
Eigen
::
Matrix
<
var
,
N
,
M
>
Bv
=
Eigen
::
Matrix
<
var
,
N
,
M
>::
Random
();
std
::
vector
<
stan
::
math
::
var
>
B
vec
(
Bv
.
data
(),
Bv
.
data
()
+
Bv
.
size
()
);
std
::
vector
<
stan
::
math
::
var
>
A
vec
(
Av
.
data
(),
Av
.
data
()
+
Av
.
size
()
);
Eigen
::
Matrix
<
double
,
N
,
N
>
A
=
value_of
(
Av
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Av
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
N
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Bv
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
M
);
std
::
vector
<
stan
::
math
::
var
>
A
vec
=
stan
::
math
::
to_array_1d
(
Av
);
std
::
vector
<
stan
::
math
::
var
>
B
vec
=
stan
::
math
::
to_array_1d
(
Bv
);
Eigen
::
Matrix
Xd
A
=
value_of
(
Av
);
// brute force
Eigen
::
Matrix
<
double
,
N
,
N
>
expA
=
stan
::
math
::
matrix_exp
(
A
);
Eigen
::
Matrix
<
var
,
N
,
M
>
expAB
;
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
for
(
int
j
=
0
;
j
<
M
;
++
j
)
{
expAB
(
i
,
j
)
=
0.0
;
for
(
int
k
=
0
;
k
<
N
;
++
k
)
{
expAB
(
i
,
j
)
+=
expA
(
i
,
k
)
*
Bv
(
k
,
j
);
}
}
}
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
expAB
=
stan
::
math
::
multiply
(
stan
::
math
::
matrix_exp
(
A
),
Bv
);
// matrix_exp_action
Eigen
::
Matrix
<
var
,
N
,
M
>
res_dv
=
stan
::
math
::
matrix_exp_action
(
A
,
Bv
);
// matrix_exp_multiply
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
res_dv
=
stan
::
math
::
matrix_exp_multiply
(
A
,
Bv
);
EXPECT_EQ
(
res_dv
.
size
(),
expAB
.
size
());
for
(
int
l
=
0
;
l
<
res_dv
.
size
();
++
l
)
{
EXPECT_FLOAT_EQ
(
res_dv
(
l
).
val
(),
expAB
(
l
).
val
());
}
// compare adjoints
std
::
vector
<
double
>
g
,
g0
;
for
(
int
l
=
0
;
l
<
M
;
++
l
)
{
...
...
@@ -184,39 +56,32 @@ inline void test_matrix_exp_action_dv() {
}
}
TEST
(
MathMatrix
,
matrix_exp_
action
_dv
)
{
test_matrix_exp_
action
_dv
<
1
,
1
>
(
);
test_matrix_exp_
action
_dv
<
1
,
5
>
(
);
test_matrix_exp_
action
_dv
<
5
,
1
>
(
);
test_matrix_exp_
action
_dv
<
5
,
5
>
(
);
TEST
(
MathMatrix
,
matrix_exp_
multiply
_dv
)
{
test_matrix_exp_
multiply
_dv
(
1
,
1
);
test_matrix_exp_
multiply
_dv
(
1
,
5
);
test_matrix_exp_
multiply
_dv
(
5
,
1
);
test_matrix_exp_
multiply
_dv
(
5
,
5
);
}
template
<
int
N
,
int
M
>
inline
void
test_matrix_exp_action_vd
()
{
inline
void
test_matrix_exp_multiply_vd
(
int
N
,
int
M
)
{
using
stan
::
math
::
value_of
;
using
stan
::
math
::
var
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
1999
);
Eigen
::
Matrix
<
var
,
N
,
N
>
Av
=
Eigen
::
Matrix
<
var
,
N
,
N
>::
Random
();
Eigen
::
Matrix
<
var
,
N
,
M
>
Bv
=
Eigen
::
Matrix
<
var
,
N
,
M
>::
Random
();
std
::
vector
<
stan
::
math
::
var
>
B
vec
(
Bv
.
data
(),
Bv
.
data
()
+
Bv
.
size
()
);
std
::
vector
<
stan
::
math
::
var
>
A
vec
(
Av
.
data
(),
Av
.
data
()
+
Av
.
size
()
);
Eigen
::
Matrix
<
double
,
N
,
M
>
B
=
value_of
(
Bv
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Av
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
N
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Bv
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
M
);
std
::
vector
<
stan
::
math
::
var
>
A
vec
=
stan
::
math
::
to_array_1d
(
Av
);
std
::
vector
<
stan
::
math
::
var
>
B
vec
=
stan
::
math
::
to_array_1d
(
Bv
);
Eigen
::
Matrix
Xd
B
=
value_of
(
Bv
);
// brute force
Eigen
::
Matrix
<
var
,
N
,
N
>
expA
=
stan
::
math
::
matrix_exp
(
Av
);
Eigen
::
Matrix
<
var
,
N
,
M
>
expAB
;
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
for
(
int
j
=
0
;
j
<
M
;
++
j
)
{
expAB
(
i
,
j
)
=
0.0
;
for
(
int
k
=
0
;
k
<
N
;
++
k
)
{
expAB
(
i
,
j
)
+=
expA
(
i
,
k
)
*
B
(
k
,
j
);
}
}
}
// matrix_exp_action
Eigen
::
Matrix
<
var
,
N
,
M
>
res_vd
=
stan
::
math
::
matrix_exp_action
(
Av
,
B
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
expAB
=
stan
::
math
::
multiply
(
stan
::
math
::
matrix_exp
(
Av
),
B
);
// matrix_exp_multiply
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
res_vd
=
stan
::
math
::
matrix_exp_multiply
(
Av
,
B
);
EXPECT_EQ
(
res_vd
.
size
(),
expAB
.
size
());
for
(
int
l
=
0
;
l
<
res_vd
.
size
();
++
l
)
{
EXPECT_FLOAT_EQ
(
res_vd
(
l
).
val
(),
expAB
(
l
).
val
());
}
...
...
@@ -247,44 +112,37 @@ inline void test_matrix_exp_action_vd() {
}
}
TEST
(
MathMatrix
,
matrix_exp_
action
_vd
)
{
test_matrix_exp_
action
_vd
<
1
,
1
>
(
);
test_matrix_exp_
action
_vd
<
1
,
5
>
(
);
test_matrix_exp_
action
_vd
<
5
,
1
>
(
);
test_matrix_exp_
action
_vd
<
5
,
5
>
(
);
TEST
(
MathMatrix
,
matrix_exp_
multiply
_vd
)
{
test_matrix_exp_
multiply
_vd
(
1
,
1
);
test_matrix_exp_
multiply
_vd
(
1
,
5
);
test_matrix_exp_
multiply
_vd
(
5
,
1
);
test_matrix_exp_
multiply
_vd
(
5
,
5
);
}
template
<
int
N
,
int
M
>
inline
void
test_matrix_exp_action_vv
()
{
inline
void
test_matrix_exp_multiply_vv
(
int
N
,
int
M
)
{
using
stan
::
math
::
value_of
;
using
stan
::
math
::
var
;
stan
::
math
::
matrix_exp_action_handler
handler
;
std
::
srand
(
2999
);
Eigen
::
Matrix
<
var
,
N
,
N
>
Av
=
Eigen
::
Matrix
<
var
,
N
,
N
>::
Random
();
Eigen
::
Matrix
<
var
,
N
,
M
>
Bv
=
Eigen
::
Matrix
<
var
,
N
,
M
>::
Random
();
std
::
vector
<
stan
::
math
::
var
>
B
vec
(
Bv
.
data
(),
Bv
.
data
()
+
Bv
.
size
()
);
std
::
vector
<
stan
::
math
::
var
>
A
vec
(
Av
.
data
(),
Av
.
data
()
+
Av
.
size
()
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Av
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
N
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Bv
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
M
);
std
::
vector
<
stan
::
math
::
var
>
A
vec
=
stan
::
math
::
to_array_1d
(
Av
);
std
::
vector
<
stan
::
math
::
var
>
B
vec
=
stan
::
math
::
to_array_1d
(
Bv
);
// brute force
Eigen
::
Matrix
<
var
,
N
,
N
>
expA
=
stan
::
math
::
matrix_exp
(
Av
);
Eigen
::
Matrix
<
var
,
N
,
M
>
expAB
;
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
for
(
int
j
=
0
;
j
<
M
;
++
j
)
{
expAB
(
i
,
j
)
=
0.0
;
for
(
int
k
=
0
;
k
<
N
;
++
k
)
{
expAB
(
i
,
j
)
+=
expA
(
i
,
k
)
*
Bv
(
k
,
j
);
}
}
}
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
expAB
=
stan
::
math
::
multiply
(
stan
::
math
::
matrix_exp
(
Av
),
Bv
);
// matrix_exp_action
Eigen
::
Matrix
<
var
,
N
,
M
>
res_vv
=
stan
::
math
::
matrix_exp_action
(
Av
,
Bv
);
// matrix_exp_multiply
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
res_vv
=
stan
::
math
::
matrix_exp_multiply
(
Av
,
Bv
);
EXPECT_EQ
(
res_vv
.
size
(),
expAB
.
size
());
for
(
int
l
=
0
;
l
<
res_vv
.
size
();
++
l
)
{
EXPECT_FLOAT_EQ
(
res_vv
(
l
).
val
(),
expAB
(
l
).
val
());
}
Avec
.
insert
(
Avec
.
end
(),
Bvec
.
begin
(),
Bvec
.
end
());
// compare adjoints
Avec
.
insert
(
Avec
.
end
(),
Bvec
.
begin
(),
Bvec
.
end
());
std
::
vector
<
double
>
g
,
g0
;
for
(
int
l
=
0
;
l
<
M
;
++
l
)
{
for
(
int
k
=
0
;
k
<
N
;
++
k
)
{
...
...
@@ -310,19 +168,41 @@ inline void test_matrix_exp_action_vv() {
}
}
TEST
(
MathMatrix
,
matrix_exp_action_vv
)
{
test_matrix_exp_action_vv
<
1
,
1
>
();
test_matrix_exp_action_vv
<
1
,
5
>
();
test_matrix_exp_action_vv
<
5
,
1
>
();
test_matrix_exp_action_vv
<
5
,
5
>
();
test_matrix_exp_action_vv
<
10
,
2
>
();
TEST
(
MathMatrix
,
matrix_exp_multiply_vv
)
{
test_matrix_exp_multiply_vv
(
1
,
1
);
test_matrix_exp_multiply_vv
(
1
,
5
);
test_matrix_exp_multiply_vv
(
5
,
1
);
test_matrix_exp_multiply_vv
(
5
,
5
);
test_matrix_exp_multiply_vv
(
8
,
2
);
}
TEST
(
MathMatrix
,
matrix_exp_multiply_exception
)
{
using
stan
::
math
::
matrix_exp_multiply
;
using
stan
::
math
::
var
;
{
// nonzero size
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
A
(
0
,
0
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
B
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
1
,
2
);
EXPECT_THROW
(
matrix_exp_multiply
(
A
,
B
),
std
::
invalid_argument
);
EXPECT_THROW
(
matrix_exp_multiply
(
B
,
A
),
std
::
invalid_argument
);
}
{
// multiplicable
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
A
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
2
,
2
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
B
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
3
,
2
);
EXPECT_THROW
(
matrix_exp_multiply
(
A
,
B
),
std
::
invalid_argument
);
}
{
// square
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
A
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
2
,
3
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
B
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
3
,
2
);
EXPECT_THROW
(
matrix_exp_multiply
(
A
,
B
),
std
::
invalid_argument
);
}
}
// TEST(MathMatrix, matrix_exp_
action
_clock) {
// TEST(MathMatrix, matrix_exp_
multiply
_clock) {
// using Eigen::MatrixXd;
// using stan::math::var;
// using stan::math::value_of;
// stan::math::matrix_exp_action_handler handler;
// std::srand(2999);
// for (int i = 1; i < 50; ++i) {
...
...
@@ -347,7 +227,6 @@ TEST(MathMatrix, matrix_exp_action_vv) {
// using Eigen::MatrixXd;
// using stan::math::var;
// using stan::math::value_of;
// stan::math::matrix_exp_action_handler handler;
// std::srand(2999);
// for (int i = 1; i < 50; ++i) {
...
...
This diff is collapsed.
Click to expand it.
test/unit/math/rev/mat/fun/scale_matrix_exp_multiply_test.cpp
0 → 100644
View file @
ac75bde4
#include <stan/math/rev/mat.hpp>
#include <gtest/gtest.h>
// #include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <test/unit/math/rev/mat/fun/util.hpp>
#include <test/unit/math/rev/mat/util.hpp>
#include <stan/math/rev/mat/fun/scale_matrix_exp_multiply.hpp>
#include <stan/math/rev/mat/fun/to_var.hpp>
#include <vector>
inline
void
test_scale_matrix_exp_multiply_dv
(
int
N
,
int
M
)
{
using
stan
::
math
::
value_of
;
using
stan
::
math
::
var
;
std
::
srand
(
1999
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Av
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
N
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Bv
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
M
);
std
::
vector
<
stan
::
math
::
var
>
Avec
=
stan
::
math
::
to_array_1d
(
Av
);
std
::
vector
<
stan
::
math
::
var
>
Bvec
=
stan
::
math
::
to_array_1d
(
Bv
);
Eigen
::
MatrixXd
A
=
value_of
(
Av
);
// brute force
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
expAB
=
stan
::
math
::
multiply
(
stan
::
math
::
matrix_exp
(
A
),
Bv
);
// matrix_exp_multiply
const
double
t
=
1.0
;
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
res_dv
=
stan
::
math
::
scale_matrix_exp_multiply
(
t
,
A
,
Bv
);
EXPECT_EQ
(
res_dv
.
size
(),
expAB
.
size
());
for
(
int
l
=
0
;
l
<
res_dv
.
size
();
++
l
)
{
EXPECT_FLOAT_EQ
(
res_dv
(
l
).
val
(),
expAB
(
l
).
val
());
}
// compare adjoints
std
::
vector
<
double
>
g
,
g0
;
for
(
int
l
=
0
;
l
<
M
;
++
l
)
{
for
(
int
k
=
0
;
k
<
N
;
++
k
)
{
stan
::
math
::
set_zero_all_adjoints
();
res_dv
(
k
,
l
).
grad
(
Bvec
,
g
);
stan
::
math
::
set_zero_all_adjoints
();
expAB
(
k
,
l
).
grad
(
Bvec
,
g0
);
for
(
size_t
j
=
0
;
j
<
g
.
size
();
++
j
)
{
EXPECT_FLOAT_EQ
(
g
[
j
],
g0
[
j
]);
}
}
}
// test a single function of expA*B
var
f
=
sum
(
res_dv
);
var
f0
=
sum
(
expAB
);
stan
::
math
::
set_zero_all_adjoints
();
f
.
grad
(
Bvec
,
g
);
stan
::
math
::
set_zero_all_adjoints
();
f0
.
grad
(
Bvec
,
g0
);
for
(
size_t
j
=
0
;
j
<
g
.
size
();
++
j
)
{
EXPECT_FLOAT_EQ
(
g
[
j
],
g0
[
j
]);
}
}
TEST
(
MathMatrix
,
scale_matrix_exp_multiply_dv
)
{
test_scale_matrix_exp_multiply_dv
(
1
,
1
);
test_scale_matrix_exp_multiply_dv
(
1
,
5
);
test_scale_matrix_exp_multiply_dv
(
5
,
1
);
test_scale_matrix_exp_multiply_dv
(
5
,
5
);
}
inline
void
test_scale_matrix_exp_multiply_vd
(
int
N
,
int
M
)
{
using
stan
::
math
::
value_of
;
using
stan
::
math
::
var
;
std
::
srand
(
1999
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Av
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
N
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Bv
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
M
);
std
::
vector
<
stan
::
math
::
var
>
Avec
=
stan
::
math
::
to_array_1d
(
Av
);
std
::
vector
<
stan
::
math
::
var
>
Bvec
=
stan
::
math
::
to_array_1d
(
Bv
);
Eigen
::
MatrixXd
B
=
value_of
(
Bv
);
// brute force
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
expAB
=
stan
::
math
::
multiply
(
stan
::
math
::
matrix_exp
(
Av
),
B
);
// matrix_exp_multiply
const
double
t
=
1.0
;
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
res_vd
=
stan
::
math
::
scale_matrix_exp_multiply
(
t
,
Av
,
B
);
EXPECT_EQ
(
res_vd
.
size
(),
expAB
.
size
());
for
(
int
l
=
0
;
l
<
res_vd
.
size
();
++
l
)
{
EXPECT_FLOAT_EQ
(
res_vd
(
l
).
val
(),
expAB
(
l
).
val
());
}
// compare adjoints
std
::
vector
<
double
>
g
,
g0
;
for
(
int
l
=
0
;
l
<
M
;
++
l
)
{
for
(
int
k
=
0
;
k
<
N
;
++
k
)
{
stan
::
math
::
set_zero_all_adjoints
();
res_vd
(
k
,
l
).
grad
(
Avec
,
g
);
stan
::
math
::
set_zero_all_adjoints
();
expAB
(
k
,
l
).
grad
(
Avec
,
g0
);
for
(
size_t
j
=
0
;
j
<
g
.
size
();
++
j
)
{
EXPECT_FLOAT_EQ
(
g
[
j
],
g0
[
j
]);
}
}
}
// test a single function of expA*B
var
f
=
sum
(
res_vd
);
var
f0
=
sum
(
expAB
);
stan
::
math
::
set_zero_all_adjoints
();
f
.
grad
(
Avec
,
g
);
stan
::
math
::
set_zero_all_adjoints
();
f0
.
grad
(
Avec
,
g0
);
for
(
size_t
j
=
0
;
j
<
g
.
size
();
++
j
)
{
EXPECT_FLOAT_EQ
(
g
[
j
],
g0
[
j
]);
}
}
TEST
(
MathMatrix
,
scale_matrix_exp_multiply_vd
)
{
test_scale_matrix_exp_multiply_vd
(
1
,
1
);
test_scale_matrix_exp_multiply_vd
(
1
,
5
);
test_scale_matrix_exp_multiply_vd
(
5
,
1
);
test_scale_matrix_exp_multiply_vd
(
5
,
5
);
}
inline
void
test_scale_matrix_exp_multiply_vv
(
int
N
,
int
M
)
{
using
stan
::
math
::
value_of
;
using
stan
::
math
::
var
;
std
::
srand
(
2999
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Av
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
N
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
Bv
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
N
,
M
);
std
::
vector
<
stan
::
math
::
var
>
Avec
=
stan
::
math
::
to_array_1d
(
Av
);
std
::
vector
<
stan
::
math
::
var
>
Bvec
=
stan
::
math
::
to_array_1d
(
Bv
);
// brute force
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
expAB
=
stan
::
math
::
multiply
(
stan
::
math
::
matrix_exp
(
Av
),
Bv
);
// matrix_exp_multiply
const
double
t
=
1.0
;
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
res_vv
=
stan
::
math
::
scale_matrix_exp_multiply
(
t
,
Av
,
Bv
);
EXPECT_EQ
(
res_vv
.
size
(),
expAB
.
size
());
for
(
int
l
=
0
;
l
<
res_vv
.
size
();
++
l
)
{
EXPECT_FLOAT_EQ
(
res_vv
(
l
).
val
(),
expAB
(
l
).
val
());
}
// compare adjoints
Avec
.
insert
(
Avec
.
end
(),
Bvec
.
begin
(),
Bvec
.
end
());
std
::
vector
<
double
>
g
,
g0
;
for
(
int
l
=
0
;
l
<
M
;
++
l
)
{
for
(
int
k
=
0
;
k
<
N
;
++
k
)
{
stan
::
math
::
set_zero_all_adjoints
();
res_vv
(
k
,
l
).
grad
(
Avec
,
g
);
stan
::
math
::
set_zero_all_adjoints
();
expAB
(
k
,
l
).
grad
(
Avec
,
g0
);
for
(
size_t
j
=
0
;
j
<
g
.
size
();
++
j
)
{
EXPECT_FLOAT_EQ
(
g
[
j
],
g0
[
j
]);
}
}
}
// test a single function of expA*B
var
f
=
sum
(
res_vv
);
var
f0
=
sum
(
expAB
);
stan
::
math
::
set_zero_all_adjoints
();
f
.
grad
(
Avec
,
g
);
stan
::
math
::
set_zero_all_adjoints
();
f0
.
grad
(
Avec
,
g0
);
for
(
size_t
j
=
0
;
j
<
g
.
size
();
++
j
)
{
EXPECT_FLOAT_EQ
(
g
[
j
],
g0
[
j
]);
}
}
TEST
(
MathMatrix
,
scale_matrix_exp_multiply_vv
)
{
test_scale_matrix_exp_multiply_vv
(
1
,
1
);
test_scale_matrix_exp_multiply_vv
(
1
,
5
);
test_scale_matrix_exp_multiply_vv
(
5
,
1
);
test_scale_matrix_exp_multiply_vv
(
5
,
5
);
test_scale_matrix_exp_multiply_vv
(
8
,
2
);
}
TEST
(
MathMatrix
,
scale_matrix_exp_multiply_exception
)
{
using
stan
::
math
::
var
;
const
double
t
=
1.0
;
{
// nonzero size
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
A
(
0
,
0
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
B
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
1
,
2
);
EXPECT_THROW
(
scale_matrix_exp_multiply
(
t
,
A
,
B
),
std
::
invalid_argument
);
EXPECT_THROW
(
scale_matrix_exp_multiply
(
t
,
B
,
A
),
std
::
invalid_argument
);
}
{
// multiplicable
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
A
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
2
,
2
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
B
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
3
,
2
);
EXPECT_THROW
(
scale_matrix_exp_multiply
(
t
,
A
,
B
),
std
::
invalid_argument
);
}
{
// square
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
A
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
2
,
3
);
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>
B
=
Eigen
::
Matrix
<
var
,
-
1
,
-
1
>::
Random
(
3
,
2
);
EXPECT_THROW
(
scale_matrix_exp_multiply
(
t
,
A
,
B
),
std
::
invalid_argument
);
}
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help