Skip to content

Commit d71d3a4

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/experimental/laplace' into experimental/laplace
2 parents 7969803 + b08b077 commit d71d3a4

2 files changed

Lines changed: 45 additions & 49 deletions

File tree

stan/math/mix/functor/laplace_marginal_density.hpp

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ inline void block_matrix_sqrt(WRootMat& W_root,
139139

140140
template <typename WRootMat>
141141
inline void block_matrix_chol_L(WRootMat& W_root,
142-
const Eigen::SparseMatrix<double>& W,
143-
const Eigen::Index block_size) {
142+
const Eigen::SparseMatrix<double>& W,
143+
const Eigen::Index block_size) {
144144
int n_block = W.cols() / block_size;
145145
Eigen::MatrixXd local_block(block_size, block_size);
146146
Eigen::MatrixXd local_block_sqrt(block_size, block_size);
@@ -161,13 +161,13 @@ inline void block_matrix_chol_L(WRootMat& W_root,
161161
// Compute square root of T
162162
Eigen::LLT<Eigen::Ref<Eigen::MatrixXd>> llt(local_block);
163163
if (llt.info() != Eigen::Success) {
164-
throw std::runtime_error("Cholesky failed on block " + std::to_string(i));
164+
throw std::runtime_error("Cholesky failed on block "
165+
+ std::to_string(i));
165166
}
166167
const auto Lb = llt.matrixL();
167168
for (int k = 0; k < block_size; k++) {
168169
for (int j = k; j < block_size; j++) {
169-
W_root.coeffRef(i * block_size + j, i * block_size + k)
170-
= Lb(j, k);
170+
W_root.coeffRef(i * block_size + j, i * block_size + k) = Lb(j, k);
171171
}
172172
}
173173
} catch (const std::exception& e) {
@@ -210,7 +210,6 @@ inline void block_matrix_chol_L(WRootMat& W_root,
210210
}
211211
}
212212

213-
214213
/**
215214
* @brief Performs a simple line search
216215
*
@@ -492,16 +491,15 @@ inline auto laplace_marginal_density_est(LLFun&& ll_fun, LLTupleArgs&& ll_args,
492491
}
493492
}
494493
B.noalias() = MatrixXd::Identity(theta_size, theta_size)
495-
+ W_r.asDiagonal() * covariance
496-
* W_r.asDiagonal();
494+
+ W_r.asDiagonal() * covariance * W_r.asDiagonal();
497495
Eigen::LLT<Eigen::Ref<Eigen::MatrixXd>> llt_B(B);
498496
auto L = llt_B.matrixL();
499497
auto LT = llt_B.matrixU();
500498
b.noalias() = W.diagonal().cwiseProduct(theta) + theta_grad;
501-
a.noalias() = b
502-
- W_r.asDiagonal()
503-
* LT.solve(L.solve(
504-
W_r.cwiseProduct(covariance * b)));
499+
a.noalias()
500+
= b
501+
- W_r.asDiagonal()
502+
* LT.solve(L.solve(W_r.cwiseProduct(covariance * b)));
505503
// Simple Newton step
506504
theta.noalias() = covariance * a;
507505
objective_old = objective_new;
@@ -1005,21 +1003,38 @@ inline auto laplace_marginal_density(const LLFun& ll_fun, LLTupleArgs&& ll_args,
10051003
partial_parm, ll_args_filter);
10061004
if (options.solver == 1) {
10071005
if (options.hessian_block_size == 1) {
1008-
// TODO(Steve): Solve without casting from sparse to dense
1009-
Eigen::MatrixXd tmp
1010-
= md_est.L.template triangularView<Eigen::Lower>().solve(
1011-
md_est.W_r.toDense());
1012-
R = tmp.transpose() * tmp;
1013-
arena_t<Eigen::MatrixXd> C
1014-
= md_est.L.template triangularView<Eigen::Lower>().solve(
1015-
md_est.W_r * md_est.covariance);
1016-
if constexpr (!ll_args_contain_var) {
1017-
s2.deep_copy(
1018-
(0.5
1019-
* (md_est.covariance.diagonal() - (C.transpose() * C).diagonal())
1020-
.cwiseProduct(laplace_likelihood::third_diff(
1021-
ll_fun, md_est.theta, value_of(ll_args_copy), msgs))));
1006+
// TODO(Steve): Solve without casting from sparse to dense
1007+
Eigen::MatrixXd tmp
1008+
= md_est.L.template triangularView<Eigen::Lower>().solve(
1009+
md_est.W_r.toDense());
1010+
R = tmp.transpose() * tmp;
1011+
arena_t<Eigen::MatrixXd> C
1012+
= md_est.L.template triangularView<Eigen::Lower>().solve(
1013+
md_est.W_r * md_est.covariance);
1014+
if constexpr (!ll_args_contain_var) {
1015+
s2.deep_copy(
1016+
(0.5
1017+
* (md_est.covariance.diagonal() - (C.transpose() * C).diagonal())
1018+
.cwiseProduct(laplace_likelihood::third_diff(
1019+
ll_fun, md_est.theta, value_of(ll_args_copy), msgs))));
1020+
} else {
1021+
arena_t<Eigen::MatrixXd> A = md_est.covariance - C.transpose() * C;
1022+
auto s2_tmp = laplace_likelihood::compute_s2(
1023+
ll_fun, md_est.theta, A, options.hessian_block_size, ll_args_copy,
1024+
msgs);
1025+
s2.deep_copy(s2_tmp);
1026+
copy_compute_s2(partial_parm, ll_args_filter);
1027+
set_zero_adjoint(ll_args_filter);
1028+
}
1029+
10221030
} else {
1031+
Eigen::MatrixXd tmp
1032+
= md_est.L.template triangularView<Eigen::Lower>().solve(
1033+
md_est.W_r.toDense());
1034+
R = tmp.transpose() * tmp;
1035+
arena_t<Eigen::MatrixXd> C
1036+
= md_est.L.template triangularView<Eigen::Lower>().solve(
1037+
md_est.W_r * md_est.covariance);
10231038
arena_t<Eigen::MatrixXd> A = md_est.covariance - C.transpose() * C;
10241039
auto s2_tmp = laplace_likelihood::compute_s2(ll_fun, md_est.theta, A,
10251040
options.hessian_block_size,
@@ -1028,23 +1043,6 @@ inline auto laplace_marginal_density(const LLFun& ll_fun, LLTupleArgs&& ll_args,
10281043
copy_compute_s2(partial_parm, ll_args_filter);
10291044
set_zero_adjoint(ll_args_filter);
10301045
}
1031-
1032-
} else {
1033-
Eigen::MatrixXd tmp
1034-
= md_est.L.template triangularView<Eigen::Lower>().solve(
1035-
md_est.W_r.toDense());
1036-
R = tmp.transpose() * tmp;
1037-
arena_t<Eigen::MatrixXd> C
1038-
= md_est.L.template triangularView<Eigen::Lower>().solve(
1039-
md_est.W_r * md_est.covariance);
1040-
arena_t<Eigen::MatrixXd> A = md_est.covariance - C.transpose() * C;
1041-
auto s2_tmp = laplace_likelihood::compute_s2(ll_fun, md_est.theta, A,
1042-
options.hessian_block_size,
1043-
ll_args_copy, msgs);
1044-
s2.deep_copy(s2_tmp);
1045-
copy_compute_s2(partial_parm, ll_args_filter);
1046-
set_zero_adjoint(ll_args_filter);
1047-
}
10481046
} else if (options.solver == 2) {
10491047
R = md_est.W_r
10501048
- md_est.W_r * md_est.K_root

stan/math/mix/prob/laplace_latent_poisson_log_exposure_rng.hpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,10 @@ inline auto laplace_latent_tol_poisson_2_log_rng(
8888
template <typename YeVec, typename ThetaVec, typename CovarFun,
8989
typename CovarArgs, typename RNG,
9090
require_eigen_t<ThetaVec>* = nullptr>
91-
inline auto laplace_latent_poisson_2_log_rng(const std::vector<int>& y,
92-
const std::vector<int>& y_index,
93-
const YeVec& ye, ThetaVec&& theta_0,
94-
CovarFun&& covariance_function,
95-
CovarArgs&& covar_args, RNG& rng,
96-
std::ostream* msgs) {
91+
inline auto laplace_latent_poisson_2_log_rng(
92+
const std::vector<int>& y, const std::vector<int>& y_index, const YeVec& ye,
93+
ThetaVec&& theta_0, CovarFun&& covariance_function, CovarArgs&& covar_args,
94+
RNG& rng, std::ostream* msgs) {
9795
constexpr laplace_options ops{1, 1, 0, 1e-6, 100};
9896
return laplace_base_rng(poisson_log_exposure_likelihood{},
9997
std::forward_as_tuple(y, y_index, ye),

0 commit comments

Comments
 (0)