Skip to content

Commit f3cbe21

Browse files
authored
Merge pull request #1727 from andrjohns/feature/issue-1723-elem-vec
Eigen::Map and elementwise functions
2 parents 3a66a33 + 2ca03e7 commit f3cbe21

27 files changed

Lines changed: 441 additions & 335 deletions

stan/math/prim/fun/acos.hpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,30 @@ struct acos_fun {
2727
* Returns the elementwise `acos()` of the input,
2828
* which may be a scalar or any Stan container of numeric scalars.
2929
*
30-
* @tparam T type of container
30+
* @tparam Container type of container
3131
* @param x container
3232
* @return Arc cosine of each variable in the container, in radians.
3333
*/
34-
template <typename T, typename = require_not_eigen_vt<std::is_arithmetic, T>>
35-
inline auto acos(const T& x) {
36-
return apply_scalar_unary<acos_fun, T>::apply(x);
34+
template <
35+
typename Container,
36+
require_not_container_st<is_container, std::is_arithmetic, Container>...>
37+
inline auto acos(const Container& x) {
38+
return apply_scalar_unary<acos_fun, Container>::apply(x);
3739
}
3840

3941
/**
40-
* Version of `acos()` that accepts Eigen Matrix or matrix expressions.
41-
* @tparam Derived derived type of x
42-
* @param x Matrix or matrix expression
42+
* Version of `acos()` that accepts std::vectors, Eigen Matrix/Array objects
43+
* or expressions, and containers of these.
44+
*
45+
* @tparam Container Type of x
46+
* @param x Container
4347
* @return Arc cosine of each variable in the container, in radians.
4448
*/
45-
template <typename Derived,
46-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
47-
inline auto acos(const Eigen::MatrixBase<Derived>& x) {
48-
return x.derived().array().acos().matrix().eval();
49+
template <typename Container,
50+
require_container_st<is_container, std::is_arithmetic, Container>...>
51+
inline auto acos(const Container& x) {
52+
return apply_vector_unary<Container>::apply(
53+
x, [](const auto& v) { return v.array().acos(); });
4954
}
5055

5156
} // namespace math

stan/math/prim/fun/asin.hpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,30 @@ struct asin_fun {
2727
* Returns the elementwise `asin()` of the input,
2828
* which may be a scalar or any Stan container of numeric scalars.
2929
*
30-
* @tparam T type of container
30+
* @tparam Container type of container
3131
* @param x container
3232
* @return Arcsine of each variable in the container, in radians.
3333
*/
34-
template <typename T, typename = require_not_eigen_vt<std::is_arithmetic, T>>
35-
inline auto asin(const T& x) {
36-
return apply_scalar_unary<asin_fun, T>::apply(x);
34+
template <
35+
typename Container,
36+
require_not_container_st<is_container, std::is_arithmetic, Container>...>
37+
inline auto asin(const Container& x) {
38+
return apply_scalar_unary<asin_fun, Container>::apply(x);
3739
}
3840

3941
/**
40-
* Version of `asin()` that accepts Eigen Matrix or matrix expressions.
42+
* Version of `asin()` that accepts std::vectors, Eigen Matrix/Array objects,
43+
* or expressions, and containers of these.
4144
*
42-
* @tparam Derived derived type of x
43-
* @param x Matrix or matrix expression
45+
* @tparam Container Type of x
46+
* @param x Container
4447
* @return Arcsine of each variable in the container, in radians.
4548
*/
46-
template <typename Derived,
47-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
48-
inline auto asin(const Eigen::MatrixBase<Derived>& x) {
49-
return x.derived().array().asin().matrix().eval();
49+
template <typename Container,
50+
require_container_st<is_container, std::is_arithmetic, Container>...>
51+
inline auto asin(const Container& x) {
52+
return apply_vector_unary<Container>::apply(
53+
x, [](const auto& v) { return v.array().asin(); });
5054
}
5155

5256
} // namespace math

stan/math/prim/fun/atan.hpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,30 @@ struct atan_fun {
2727
* Returns the elementwise \c atan() of the input,
2828
* which may be a scalar or any Stan container of numeric scalars.
2929
*
30-
* @tparam T type of container
30+
* @tparam Container type of container
3131
* @param x container
3232
* @return Arctan of each value in x, in radians.
3333
*/
34-
template <typename T, typename = require_not_eigen_vt<std::is_arithmetic, T>>
35-
inline typename apply_scalar_unary<atan_fun, T>::return_t atan(const T& x) {
36-
return apply_scalar_unary<atan_fun, T>::apply(x);
34+
template <
35+
typename Container,
36+
require_not_container_st<is_container, std::is_arithmetic, Container>...>
37+
inline auto atan(const Container& x) {
38+
return apply_scalar_unary<atan_fun, Container>::apply(x);
3739
}
3840

3941
/**
40-
* Version of atan() that accepts Eigen Matrix or matrix expressions.
42+
* Version of atan() that accepts std::vectors, Eigen Matrix/Array objects,
43+
* or expressions, and containers of these.
4144
*
42-
* @tparam Derived derived type of x
43-
* @param x Matrix or matrix expression
45+
* @tparam Container Type of x
46+
* @param x Container
4447
* @return Elementwise atan of members of container.
4548
*/
46-
template <typename Derived,
47-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
48-
inline auto atan(const Eigen::MatrixBase<Derived>& x) {
49-
return x.derived().array().atan().matrix().eval();
49+
template <typename Container,
50+
require_container_st<is_container, std::is_arithmetic, Container>...>
51+
inline auto atan(const Container& x) {
52+
return apply_vector_unary<Container>::apply(
53+
x, [](const auto& v) { return v.array().atan(); });
5054
}
5155

5256
} // namespace math

stan/math/prim/fun/ceil.hpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,30 @@ struct ceil_fun {
2727
* Returns the elementwise `ceil()` of the input,
2828
* which may be a scalar or any Stan container of numeric scalars.
2929
*
30-
* @tparam T type of container
30+
* @tparam Container type of container
3131
* @param x container
3232
* @return Least integer >= each value in x.
3333
*/
34-
template <typename T, typename = require_not_eigen_vt<std::is_arithmetic, T>>
35-
inline auto ceil(const T& x) {
36-
return apply_scalar_unary<ceil_fun, T>::apply(x);
34+
template <
35+
typename Container,
36+
require_not_container_st<is_container, std::is_arithmetic, Container>...>
37+
inline auto ceil(const Container& x) {
38+
return apply_scalar_unary<ceil_fun, Container>::apply(x);
3739
}
3840

3941
/**
40-
* Version of `ceil()` that accepts Eigen Matrix or matrix expressions.
42+
* Version of `ceil()` that accepts std::vectors, Eigen Matrix/Array objects
43+
* or expressions, and containers of these.
4144
*
42-
* @tparam Derived derived type of x
43-
* @param x Matrix or matrix expression
45+
* @tparam Container Type of x
46+
* @param x Container
4447
* @return Least integer >= each value in x.
4548
*/
46-
template <typename Derived,
47-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
48-
inline auto ceil(const Eigen::MatrixBase<Derived>& x) {
49-
return x.derived().array().ceil().matrix().eval();
49+
template <typename Container,
50+
require_container_st<is_container, std::is_arithmetic, Container>...>
51+
inline auto ceil(const Container& x) {
52+
return apply_vector_unary<Container>::apply(
53+
x, [](const auto& v) { return v.array().ceil(); });
5054
}
5155

5256
} // namespace math

stan/math/prim/fun/cos.hpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,30 @@ struct cos_fun {
2727
* Returns the elementwise `cos()` of the input,
2828
* which may be a scalar or any Stan container of numeric scalars.
2929
*
30-
* @tparam T type of container
30+
* @tparam Container type of container
3131
* @param x angles in radians
3232
* @return Cosine of each value in x.
3333
*/
34-
template <typename T, typename = require_not_eigen_vt<std::is_arithmetic, T>>
35-
inline auto cos(const T& x) {
36-
return apply_scalar_unary<cos_fun, T>::apply(x);
34+
template <
35+
typename Container,
36+
require_not_container_st<is_container, std::is_arithmetic, Container>...>
37+
inline auto cos(const Container& x) {
38+
return apply_scalar_unary<cos_fun, Container>::apply(x);
3739
}
3840

3941
/**
40-
* Version of `cos()` that accepts Eigen Matrix or matrix expressions.
42+
* Version of `cos()` that accepts std::vectors, Eigen Matrix/Array objects
43+
* or expressions, and containers of these.
4144
*
42-
* @tparam Derived derived type of x
43-
* @param x Matrix or matrix expression
45+
* @tparam Container Type of x
46+
* @param x Container
4447
* @return Cosine of each value in x.
4548
*/
46-
template <typename Derived,
47-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
48-
inline auto cos(const Eigen::MatrixBase<Derived>& x) {
49-
return x.derived().array().cos().matrix().eval();
49+
template <typename Container,
50+
require_container_st<is_container, std::is_arithmetic, Container>...>
51+
inline auto cos(const Container& x) {
52+
return apply_vector_unary<Container>::apply(
53+
x, [](const auto& v) { return v.array().cos(); });
5054
}
5155

5256
} // namespace math

stan/math/prim/fun/cosh.hpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,31 @@ struct cosh_fun {
2727
* Returns the elementwise `cosh()` of the input,
2828
* which may be a scalar or any Stan container of numeric scalars.
2929
*
30-
* @tparam T type of container
30+
* @tparam Container type of container
3131
* @param x angles in radians
3232
* @return Hyberbolic cosine of x.
3333
*/
34-
template <typename T, typename = require_not_eigen_vt<std::is_arithmetic, T>>
35-
inline typename apply_scalar_unary<cosh_fun, T>::return_t cosh(const T& x) {
36-
return apply_scalar_unary<cosh_fun, T>::apply(x);
34+
template <
35+
typename Container,
36+
require_not_container_st<is_container, std::is_arithmetic, Container>...>
37+
inline auto cosh(const Container& x) {
38+
return apply_scalar_unary<cosh_fun, Container>::apply(x);
3739
}
3840

3941
/**
40-
* Version of `cosh()` that accepts Eigen Matrix or matrix expressions.
42+
* Version of `cosh()` that accepts std::vectors, Eigen Matrix/Array objects
43+
* or expressions, and containers of these.
4144
*
42-
* @tparam Derived derived type of x
43-
* @param x Matrix or matrix expression
45+
* @tparam Container Type of x
46+
* @param x Container
4447
* @return Hyberbolic cosine of x.
4548
*/
46-
template <typename Derived,
47-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
48-
inline auto cosh(const Eigen::MatrixBase<Derived>& x) {
49-
return x.derived().array().cosh().matrix().eval();
49+
template <typename Container,
50+
require_container_st<is_container, std::is_arithmetic, Container>...>
51+
inline auto cosh(const Container& x) {
52+
return apply_vector_unary<Container>::apply(
53+
x, [](const auto& v) { return v.array().cosh(); });
5054
}
51-
5255
} // namespace math
5356
} // namespace stan
5457

stan/math/prim/fun/exp.hpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
namespace stan {
99
namespace math {
10-
1110
/**
1211
* Structure to wrap `exp()` so that it can be
1312
* vectorized.
@@ -32,25 +31,30 @@ struct exp_fun {
3231
* which may be a scalar or any Stan container of numeric scalars.
3332
* The return type is the same as the argument type.
3433
*
35-
* @tparam T type of container
34+
* @tparam Container type of container
3635
* @param[in] x container
3736
* @return Elementwise application of exponentiation to the argument.
3837
*/
39-
template <typename T, typename = require_not_eigen_vt<std::is_arithmetic, T>>
40-
inline auto exp(const T& x) {
41-
return apply_scalar_unary<exp_fun, T>::apply(x);
38+
template <
39+
typename Container,
40+
require_not_container_st<is_container, std::is_arithmetic, Container>...>
41+
inline auto exp(const Container& x) {
42+
return apply_scalar_unary<exp_fun, Container>::apply(x);
4243
}
4344

4445
/**
45-
* Version of `exp()` that accepts Eigen Matrix or matrix expressions.
46-
* @tparam Derived derived type of x
47-
* @param x Matrix or matrix expression
46+
* Version of `exp()` that accepts std::vectors, Eigen Matrix/Array objects
47+
* or expressions, and containers of these.
48+
*
49+
* @tparam Container Type of x
50+
* @param x Container
4851
* @return Elementwise application of exponentiation to the argument.
4952
*/
50-
template <typename Derived,
51-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
52-
inline auto exp(const Eigen::MatrixBase<Derived>& x) {
53-
return x.derived().array().exp().matrix().eval();
53+
template <typename Container,
54+
require_container_st<is_container, std::is_arithmetic, Container>...>
55+
inline auto exp(const Container& x) {
56+
return apply_vector_unary<Container>::apply(
57+
x, [](const auto& v) { return v.array().exp(); });
5458
}
5559

5660
} // namespace math

stan/math/prim/fun/fabs.hpp

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,39 +27,30 @@ struct fabs_fun {
2727
* Returns the elementwise `fabs()` of the input,
2828
* which may be a scalar or any Stan container of numeric scalars.
2929
*
30-
* @tparam T type of container
30+
* @tparam Container type of container
3131
* @param x container
3232
* @return Absolute value of each value in x.
3333
*/
34-
template <typename T, typename = require_not_eigen_vt<std::is_arithmetic, T>>
35-
inline typename apply_scalar_unary<fabs_fun, T>::return_t fabs(const T& x) {
36-
return apply_scalar_unary<fabs_fun, T>::apply(x);
34+
template <
35+
typename Container,
36+
require_not_container_st<is_container, std::is_arithmetic, Container>...>
37+
inline auto fabs(const Container& x) {
38+
return apply_scalar_unary<fabs_fun, Container>::apply(x);
3739
}
3840

3941
/**
40-
* Version of `fabs()` that accepts Eigen Matrix or matrix expressions.
42+
* Version of `fabs()` that accepts std::vectors, Eigen Matrix/Array objects
43+
* or expressions, and containers of these.
4144
*
42-
* @tparam Derived derived type of x
43-
* @param x Matrix or matrix expression
45+
* @tparam Container Type of x
46+
* @param x Container
4447
* @return Absolute value of each value in x.
4548
*/
46-
template <typename Derived,
47-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
48-
inline auto fabs(const Eigen::MatrixBase<Derived>& x) {
49-
return x.derived().array().abs().matrix().eval();
50-
}
51-
52-
/**
53-
* Version of \c fabs() that accepts Eigen Array or array expressions.
54-
*
55-
* @tparam Derived derived type of x
56-
* @param x Matrix or matrix expression
57-
* @return Absolute value of each value in x.
58-
*/
59-
template <typename Derived,
60-
typename = require_eigen_vt<std::is_arithmetic, Derived>>
61-
inline auto fabs(const Eigen::ArrayBase<Derived>& x) {
62-
return x.derived().abs().eval();
49+
template <typename Container,
50+
require_container_st<is_container, std::is_arithmetic, Container>...>
51+
inline auto fabs(const Container& x) {
52+
return apply_vector_unary<Container>::apply(
53+
x, [](const auto& v) { return v.array().abs(); });
6354
}
6455

6556
} // namespace math

0 commit comments

Comments
 (0)