Skip to content

Commit e9cca92

Browse files
committed
Merge commit '6025c339b0fad05ac568a678d38cc6e74cddf57b' into HEAD
2 parents 44529fd + 6025c33 commit e9cca92

File tree

91 files changed

+1749
-640
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1749
-640
lines changed

make/compiler_flags

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ endif
162162
## makes reentrant version lgamma_r available from cmath
163163
CXXFLAGS_OS += -D_REENTRANT
164164

165+
ifeq (gcc,$(CXX_TYPE))
166+
CXXFLAGS_WARNINGS += -Wno-int-in-bool-context -Wno-attributes
167+
endif
168+
165169
################################################################################
166170
# Setup OpenCL
167171
#

stan/math/fwd/fun.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
#include <stan/math/fwd/fun/proj.hpp>
9494
#include <stan/math/fwd/fun/quad_form.hpp>
9595
#include <stan/math/fwd/fun/quad_form_sym.hpp>
96+
#include <stan/math/fwd/fun/read_fvar.hpp>
9697
#include <stan/math/fwd/fun/rising_factorial.hpp>
9798
#include <stan/math/fwd/fun/round.hpp>
9899
#include <stan/math/fwd/fun/sin.hpp>

stan/math/fwd/fun/Eigen_NumTraits.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <stan/math/prim/fun/Eigen.hpp>
55
#include <stan/math/prim/core.hpp>
6+
#include <stan/math/fwd/fun/read_fvar.hpp>
67
#include <stan/math/fwd/core.hpp>
78
#include <stan/math/fwd/core/std_numeric_limits.hpp>
89
#include <limits>
@@ -163,5 +164,17 @@ struct ScalarBinaryOpTraits<std::complex<stan::math::fvar<T>>,
163164
using ReturnType = std::complex<stan::math::fvar<T>>;
164165
};
165166

167+
namespace internal {
168+
169+
/**
170+
* Enable linear access of inputs when using read_fvar.
171+
*/
172+
template <typename EigFvar, typename EigOut>
173+
struct functor_has_linear_access<
174+
stan::math::read_fvar_functor<EigFvar, EigOut>> {
175+
enum { ret = 1 };
176+
};
177+
178+
} // namespace internal
166179
} // namespace Eigen
167180
#endif

stan/math/fwd/fun/quad_form.hpp

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,43 @@ namespace math {
1414
* Symmetry of the resulting matrix is not guaranteed due to numerical
1515
* precision.
1616
*
17-
* @tparam Ta type of elements in the square matrix
18-
* @tparam Ra number of rows in the square matrix, can be Eigen::Dynamic
19-
* @tparam Ca number of columns in the square matrix, can be Eigen::Dynamic
20-
* @tparam Tb type of elements in the second matrix
21-
* @tparam Rb number of rows in the second matrix, can be Eigen::Dynamic
22-
* @tparam Cb number of columns in the second matrix, can be Eigen::Dynamic
17+
* @tparam EigMat1 type of the first (square) matrix
18+
* @tparam EigMat2 type of the second matrix
2319
*
2420
* @param A square matrix
2521
* @param B second matrix
2622
* @return The quadratic form, which is a symmetric matrix of size Cb.
2723
* @throws std::invalid_argument if A is not square, or if A cannot be
2824
* multiplied by B
2925
*/
30-
template <typename Ta, int Ra, int Ca, typename Tb, int Rb, int Cb,
31-
require_any_fvar_t<Ta, Tb>...>
32-
inline Eigen::Matrix<return_type_t<Ta, Tb>, Cb, Cb> quad_form(
33-
const Eigen::Matrix<Ta, Ra, Ca>& A, const Eigen::Matrix<Tb, Rb, Cb>& B) {
26+
template <typename EigMat1, typename EigMat2,
27+
require_all_eigen_t<EigMat1, EigMat2>* = nullptr,
28+
require_not_eigen_col_vector_t<EigMat2>* = nullptr,
29+
require_any_vt_fvar<EigMat1, EigMat2>* = nullptr>
30+
inline promote_scalar_t<return_type_t<EigMat1, EigMat2>, EigMat2> quad_form(
31+
const EigMat1& A, const EigMat2& B) {
3432
check_square("quad_form", "A", A);
3533
check_multiplicable("quad_form", "A", A, "B", B);
36-
return multiply(transpose(B), multiply(A, B));
34+
return multiply(B.transpose(), multiply(A, B));
3735
}
3836

3937
/**
4038
* Return the quadratic form \f$ B^T A B \f$.
4139
*
42-
* @tparam Ta type of elements in the square matrix
43-
* @tparam Ra number of rows in the square matrix, can be Eigen::Dynamic
44-
* @tparam Ca number of columns in the square matrix, can be Eigen::Dynamic
45-
* @tparam Tb type of elements in the vector
46-
* @tparam Rb number of rows in the vector, can be Eigen::Dynamic
40+
* @tparam EigMat type of the matrix
41+
* @tparam ColVec type of the vector
4742
*
4843
* @param A square matrix
4944
* @param B vector
5045
* @return The quadratic form (a scalar).
5146
* @throws std::invalid_argument if A is not square, or if A cannot be
5247
* multiplied by B
5348
*/
54-
template <typename Ta, int Ra, int Ca, typename Tb, int Rb,
55-
require_any_fvar_t<Ta, Tb>...>
56-
inline return_type_t<Ta, Tb> quad_form(const Eigen::Matrix<Ta, Ra, Ca>& A,
57-
const Eigen::Matrix<Tb, Rb, 1>& B) {
49+
template <typename EigMat, typename ColVec, require_eigen_t<EigMat>* = nullptr,
50+
require_eigen_col_vector_t<ColVec>* = nullptr,
51+
require_any_vt_fvar<EigMat, ColVec>* = nullptr>
52+
inline return_type_t<EigMat, ColVec> quad_form(const EigMat& A,
53+
const ColVec& B) {
5854
check_square("quad_form", "A", A);
5955
check_multiplicable("quad_form", "A", A, "B", B);
6056
return dot_product(B, multiply(A, B));

stan/math/fwd/fun/quad_form_sym.hpp

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,49 +13,45 @@ namespace math {
1313
*
1414
* Symmetry of the resulting matrix is guaranteed.
1515
*
16-
* @tparam TA type of elements in the symmetric matrix
17-
* @tparam RA number of rows in the symmetric matrix, can be Eigen::Dynamic
18-
* @tparam CA number of columns in the symmetric matrix, can be Eigen::Dynamic
19-
* @tparam TB type of elements in the second matrix
20-
* @tparam RB number of rows in the second matrix, can be Eigen::Dynamic
21-
* @tparam CB number of columns in the second matrix, can be Eigen::Dynamic
16+
* @tparam EigMat1 type of the first (symmetric) matrix
17+
* @tparam EigMat2 type of the second matrix
2218
*
2319
* @param A symmetric matrix
2420
* @param B second matrix
2521
* @return The quadratic form, which is a symmetric matrix of size CB.
2622
* @throws std::invalid_argument if A is not symmetric, or if A cannot be
2723
* multiplied by B
2824
*/
29-
template <typename TA, int RA, int CA, typename TB, int RB, int CB,
30-
require_any_fvar_t<TA, TB>...>
31-
inline Eigen::Matrix<return_type_t<TA, TB>, CB, CB> quad_form_sym(
32-
const Eigen::Matrix<TA, RA, CA>& A, const Eigen::Matrix<TB, RB, CB>& B) {
33-
using T = return_type_t<TA, TB>;
25+
template <typename EigMat1, typename EigMat2,
26+
require_all_eigen_t<EigMat1, EigMat2>* = nullptr,
27+
require_not_eigen_col_vector_t<EigMat2>* = nullptr,
28+
require_any_vt_fvar<EigMat1, EigMat2>* = nullptr>
29+
inline promote_scalar_t<return_type_t<EigMat1, EigMat2>, EigMat2> quad_form_sym(
30+
const EigMat1& A, const EigMat2& B) {
31+
using T_ret = return_type_t<EigMat1, EigMat2>;
3432
check_multiplicable("quad_form_sym", "A", A, "B", B);
3533
check_symmetric("quad_form_sym", "A", A);
36-
Eigen::Matrix<T, CB, CB> ret(multiply(transpose(B), multiply(A, B)));
37-
return T(0.5) * (ret + transpose(ret));
34+
promote_scalar_t<T_ret, EigMat2> ret(multiply(B.transpose(), multiply(A, B)));
35+
return T_ret(0.5) * (ret + ret.transpose());
3836
}
3937

4038
/**
4139
* Return the quadratic form \f$ B^T A B \f$ of a symmetric matrix.
4240
*
43-
* @tparam TA type of elements in the symmetric matrix
44-
* @tparam RA number of rows in the symmetric matrix, can be Eigen::Dynamic
45-
* @tparam CA number of columns in the symmetric matrix, can be Eigen::Dynamic
46-
* @tparam TB type of elements in the vector
47-
* @tparam RB number of rows in the vector, can be Eigen::Dynamic
41+
* @tparam EigMat type of the (symmetric) matrix
42+
* @tparam ColVec type of the vector
4843
*
4944
* @param A symmetric matrix
5045
* @param B vector
5146
* @return The quadratic form (a scalar).
5247
* @throws std::invalid_argument if A is not symmetric, or if A cannot be
5348
* multiplied by B
5449
*/
55-
template <typename TA, int RA, int CA, typename TB, int RB,
56-
require_any_fvar_t<TA, TB>...>
57-
inline return_type_t<TA, TB> quad_form_sym(const Eigen::Matrix<TA, RA, CA>& A,
58-
const Eigen::Matrix<TB, RB, 1>& B) {
50+
template <typename EigMat, typename ColVec, require_eigen_t<EigMat>* = nullptr,
51+
require_eigen_col_vector_t<ColVec>* = nullptr,
52+
require_any_vt_fvar<EigMat, ColVec>* = nullptr>
53+
inline return_type_t<EigMat, ColVec> quad_form_sym(const EigMat& A,
54+
const ColVec& B) {
5955
check_multiplicable("quad_form_sym", "A", A, "B", B);
6056
check_symmetric("quad_form_sym", "A", A);
6157
return dot_product(B, multiply(A, B));

stan/math/fwd/fun/read_fvar.hpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#ifndef STAN_MATH_FWD_FUN_READ_FVAR_HPP
2+
#define STAN_MATH_FWD_FUN_READ_FVAR_HPP
3+
4+
#include <stan/math/fwd/meta.hpp>
5+
6+
namespace stan {
7+
namespace math {
8+
9+
/**
10+
* Functor for extracting the values and tangents from a matrix of fvar.
11+
* This functor is called using Eigen's NullaryExpr framework.
12+
*/
13+
template <typename EigFvar, typename EigOut>
14+
class read_fvar_functor {
15+
const EigFvar& var_mat;
16+
EigOut& val_mat;
17+
18+
public:
19+
read_fvar_functor(const EigFvar& arg1, EigOut& arg2)
20+
: var_mat(arg1), val_mat(arg2) {}
21+
22+
inline decltype(auto) operator()(Eigen::Index row, Eigen::Index col) const {
23+
val_mat.coeffRef(row, col) = var_mat.coeffRef(row, col).val_;
24+
return var_mat.coeffRef(row, col).d_;
25+
}
26+
27+
inline decltype(auto) operator()(Eigen::Index index) const {
28+
val_mat.coeffRef(index) = var_mat.coeffRef(index).val_;
29+
return var_mat.coeffRef(index).d_;
30+
}
31+
};
32+
33+
/**
34+
* Function applying the read_fvar_functor to extract the values
35+
* and tangets of a given fvar matrix into separate matrices.
36+
*
37+
* @tparam EigFvar type of the Eigen container of fvar.
38+
* @tparam EigOut type of the Eigen containers to copy to
39+
* @param[in] FvarMat Input Eigen container of fvar.
40+
* @param[in] ValMat Output Eigen container of values.
41+
* @param[in] DMat Output Eigen container of tangents.
42+
*/
43+
template <typename EigFvar, typename EigOut>
44+
inline void read_fvar(const EigFvar& FvarMat, EigOut& ValMat, EigOut& DMat) {
45+
DMat = EigOut::NullaryExpr(
46+
FvarMat.rows(), FvarMat.cols(),
47+
read_fvar_functor<const EigFvar, EigOut>(FvarMat, ValMat));
48+
}
49+
50+
} // namespace math
51+
} // namespace stan
52+
#endif

stan/math/fwd/fun/softmax.hpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,39 @@
88
namespace stan {
99
namespace math {
1010

11-
template <typename T>
12-
inline Eigen::Matrix<fvar<T>, Eigen::Dynamic, 1> softmax(
13-
const Eigen::Matrix<fvar<T>, Eigen::Dynamic, 1>& alpha) {
11+
template <typename ColVec,
12+
require_eigen_col_vector_vt<is_fvar, ColVec>* = nullptr>
13+
inline auto softmax(const ColVec& alpha) {
1414
using Eigen::Dynamic;
1515
using Eigen::Matrix;
16+
using T = typename value_type_t<ColVec>::Scalar;
1617

1718
Matrix<T, Dynamic, 1> alpha_t(alpha.size());
1819
for (int k = 0; k < alpha.size(); ++k) {
19-
alpha_t(k) = alpha(k).val_;
20+
alpha_t.coeffRef(k) = alpha.coeff(k).val_;
2021
}
2122

2223
Matrix<T, Dynamic, 1> softmax_alpha_t = softmax(alpha_t);
2324

2425
Matrix<fvar<T>, Dynamic, 1> softmax_alpha(alpha.size());
2526
for (int k = 0; k < alpha.size(); ++k) {
26-
softmax_alpha(k).val_ = softmax_alpha_t(k);
27-
softmax_alpha(k).d_ = 0;
27+
softmax_alpha.coeffRef(k).val_ = softmax_alpha_t.coeff(k);
28+
softmax_alpha.coeffRef(k).d_ = 0;
2829
}
2930

3031
for (int m = 0; m < alpha.size(); ++m) {
3132
T negative_alpha_m_d_times_softmax_alpha_t_m
32-
= -alpha(m).d_ * softmax_alpha_t(m);
33+
= -alpha.coeff(m).d_ * softmax_alpha_t.coeff(m);
3334
for (int k = 0; k < alpha.size(); ++k) {
3435
if (m == k) {
35-
softmax_alpha(k).d_
36-
+= softmax_alpha_t(k)
37-
* (alpha(m).d_ + negative_alpha_m_d_times_softmax_alpha_t_m);
36+
softmax_alpha.coeffRef(k).d_
37+
+= softmax_alpha_t.coeff(k)
38+
* (alpha.coeff(m).d_
39+
+ negative_alpha_m_d_times_softmax_alpha_t_m);
3840
} else {
39-
softmax_alpha(k).d_
40-
+= negative_alpha_m_d_times_softmax_alpha_t_m * softmax_alpha_t(k);
41+
softmax_alpha.coeffRef(k).d_
42+
+= softmax_alpha_t.coeff(k)
43+
* negative_alpha_m_d_times_softmax_alpha_t_m;
4144
}
4245
}
4346
}

stan/math/fwd/fun/trace_quad_form.hpp

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,16 @@
1111
namespace stan {
1212
namespace math {
1313

14-
template <int RA, int CA, int RB, int CB, typename T>
15-
inline fvar<T> trace_quad_form(const Eigen::Matrix<fvar<T>, RA, CA> &A,
16-
const Eigen::Matrix<fvar<T>, RB, CB> &B) {
14+
template <typename EigMat1, typename EigMat2,
15+
require_all_eigen_t<EigMat1, EigMat2>* = nullptr,
16+
require_any_vt_fvar<EigMat1, EigMat2>* = nullptr>
17+
inline return_type_t<EigMat1, EigMat2> trace_quad_form(const EigMat1& A,
18+
const EigMat2& B) {
1719
check_square("trace_quad_form", "A", A);
1820
check_multiplicable("trace_quad_form", "A", A, "B", B);
19-
return trace(multiply(transpose(B), multiply(A, B)));
21+
return B.cwiseProduct(multiply(A, B)).sum();
2022
}
2123

22-
template <int RA, int CA, int RB, int CB, typename T>
23-
inline fvar<T> trace_quad_form(const Eigen::Matrix<fvar<T>, RA, CA> &A,
24-
const Eigen::Matrix<double, RB, CB> &B) {
25-
check_square("trace_quad_form", "A", A);
26-
check_multiplicable("trace_quad_form", "A", A, "B", B);
27-
return trace(multiply(transpose(B), multiply(A, B)));
28-
}
29-
30-
template <int RA, int CA, int RB, int CB, typename T>
31-
inline fvar<T> trace_quad_form(const Eigen::Matrix<double, RA, CA> &A,
32-
const Eigen::Matrix<fvar<T>, RB, CB> &B) {
33-
check_square("trace_quad_form", "A", A);
34-
check_multiplicable("trace_quad_form", "A", A, "B", B);
35-
return trace(multiply(transpose(B), multiply(A, B)));
36-
}
3724
} // namespace math
3825
} // namespace stan
3926

stan/math/opencl/kernel_generator/binary_operation.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ ADD_BINARY_OPERATION(addition_, operator+, common_scalar_t<T_a COMMA T_b>, "+");
187187
ADD_BINARY_OPERATION(subtraction_, operator-, common_scalar_t<T_a COMMA T_b>,
188188
"-");
189189
ADD_BINARY_OPERATION_WITH_CUSTOM_CODE(
190-
elewise_multiplication_, elewise_multiplication,
191-
common_scalar_t<T_a COMMA T_b>, "*",
190+
elt_multiply_, elt_multiply, common_scalar_t<T_a COMMA T_b>, "*",
192191
using view_transitivity = std::tuple<std::true_type, std::true_type>;
193192
inline std::pair<int, int> extreme_diagonals() const {
194193
std::pair<int, int> diags0
@@ -200,7 +199,7 @@ ADD_BINARY_OPERATION_WITH_CUSTOM_CODE(
200199
});
201200

202201
ADD_BINARY_OPERATION_WITH_CUSTOM_CODE(
203-
elewise_division_, elewise_division, common_scalar_t<T_a COMMA T_b>, "/",
202+
elt_divide_, elt_divide, common_scalar_t<T_a COMMA T_b>, "/",
204203
inline std::pair<int, int> extreme_diagonals() const {
205204
return {-rows() + 1, cols() - 1};
206205
});
@@ -246,7 +245,7 @@ ADD_BINARY_OPERATION_WITH_CUSTOM_CODE(
246245
*/
247246
template <typename T_a, typename T_b, typename = require_arithmetic_t<T_a>,
248247
typename = require_all_kernel_expressions_t<T_b>>
249-
inline elewise_multiplication_<scalar_<T_a>, as_operation_cl_t<T_b>> operator*(
248+
inline elt_multiply_<scalar_<T_a>, as_operation_cl_t<T_b>> operator*(
250249
T_a&& a, T_b&& b) { // NOLINT
251250
return {as_operation_cl(std::forward<T_a>(a)),
252251
as_operation_cl(std::forward<T_b>(b))};
@@ -263,7 +262,7 @@ inline elewise_multiplication_<scalar_<T_a>, as_operation_cl_t<T_b>> operator*(
263262
template <typename T_a, typename T_b,
264263
typename = require_all_kernel_expressions_t<T_a>,
265264
typename = require_arithmetic_t<T_b>>
266-
inline elewise_multiplication_<as_operation_cl_t<T_a>, scalar_<T_b>> operator*(
265+
inline elt_multiply_<as_operation_cl_t<T_a>, scalar_<T_b>> operator*(
267266
T_a&& a, const T_b b) { // NOLINT
268267
return {as_operation_cl(std::forward<T_a>(a)), as_operation_cl(b)};
269268
}

stan/math/opencl/kernel_generator/matrix_vector_multiply.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace math {
1515
template <typename T_matrix, typename T_vector,
1616
typename = require_all_kernel_expressions_t<T_matrix, T_vector>>
1717
inline auto matrix_vector_multiply(T_matrix&& matrix, T_vector&& vector) {
18-
return rowwise_sum(elewise_multiplication(
18+
return rowwise_sum(elt_multiply(
1919
std::forward<T_matrix>(matrix),
2020
colwise_broadcast(transpose(std::forward<T_vector>(vector)))));
2121
}

0 commit comments

Comments
 (0)