Skip to content

Commit a31c1d7

Browse files
committed
Avoid uneccesary LDLT computation
1 parent a013922 commit a31c1d7

File tree

1 file changed

+26
-22
lines changed

1 file changed

+26
-22
lines changed

include/albatross/src/models/sparse_gp.hpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,11 @@ class SparseGaussianProcessRegression
296296
const MarginalDistribution &targets) const {
297297

298298
BlockDiagonalLDLT A_ldlt;
299-
Eigen::SerializableLDLT K_uu_ldlt;
300299
Eigen::MatrixXd K_fu;
301300
Eigen::VectorXd y;
301+
302302
compute_internal_components(old_fit.train_features, features, targets,
303-
&A_ldlt, &K_uu_ldlt, &K_fu, &y);
303+
old_fit.train_covariance, &A_ldlt, &K_fu, &y);
304304

305305
const Eigen::Index n_old = old_fit.sigma_R.rows();
306306
const Eigen::Index n_new = A_ldlt.rows();
@@ -368,16 +368,16 @@ class SparseGaussianProcessRegression
368368
const MarginalDistribution &targets) const {
369369

370370
// Determine the set of inducing points, u.
371-
const auto u =
372-
inducing_point_strategy_(this->covariance_function_, features);
373-
ALBATROSS_ASSERT(u.size() > 0 && "Empty inducing points!");
371+
auto u = inducing_point_strategy_(this->covariance_function_, features);
372+
ALBATROSS_ASSERT(!u.empty() && "Empty inducing points!");
373+
374+
const auto K_uu_ldlt = compute_kuu_ldlt(&u);
374375

375376
BlockDiagonalLDLT A_ldlt;
376-
Eigen::SerializableLDLT K_uu_ldlt;
377377
Eigen::MatrixXd K_fu;
378378
Eigen::VectorXd y;
379-
compute_internal_components(u, features, targets, &A_ldlt, &K_uu_ldlt,
380-
&K_fu, &y);
379+
compute_internal_components(u, features, targets, K_uu_ldlt, &A_ldlt, &K_fu,
380+
&y);
381381
const auto B_qr = compute_sigma_qr(K_uu_ldlt, A_ldlt, K_fu);
382382

383383
Eigen::VectorXd y_augmented = Eigen::VectorXd::Zero(B_qr.matrixR().rows());
@@ -526,15 +526,17 @@ class SparseGaussianProcessRegression
526526

527527
template <typename FeatureType>
528528
double log_likelihood(const RegressionDataset<FeatureType> &dataset) const {
529-
const auto u =
529+
auto u =
530530
inducing_point_strategy_(this->covariance_function_, dataset.features);
531531

532+
const auto K_uu_ldlt = compute_kuu_ldlt(&u);
533+
532534
BlockDiagonalLDLT A_ldlt;
533-
Eigen::SerializableLDLT K_uu_ldlt;
534535
Eigen::MatrixXd K_fu;
535536
Eigen::VectorXd y;
536-
compute_internal_components(u, dataset.features, dataset.targets, &A_ldlt,
537-
&K_uu_ldlt, &K_fu, &y);
537+
compute_internal_components(u, dataset.features, dataset.targets, K_uu_ldlt,
538+
&A_ldlt, &K_fu, &y);
539+
538540
const auto B_qr = compute_sigma_qr(K_uu_ldlt, A_ldlt, K_fu);
539541
// The log likelihood for y ~ N(0, K) is:
540542
//
@@ -596,6 +598,16 @@ class SparseGaussianProcessRegression
596598
}
597599

598600
private:
601+
template <typename InducingFeatureType>
602+
auto
603+
compute_kuu_ldlt(std::vector<InducingFeatureType> *inducing_features) const {
604+
auto K_uu =
605+
this->covariance_function_(*inducing_features, Base::threads_.get());
606+
K_uu.diagonal() +=
607+
inducing_nugget_.value * Eigen::VectorXd::Ones(K_uu.rows());
608+
return Eigen::SerializableLDLT(K_uu);
609+
}
610+
599611
// This method takes care of a lot of the common book keeping required to
600612
// setup the Sparse Gaussian Process problem. Namely, we want to get from
601613
// possibly unordered features to a structured representation
@@ -607,11 +619,10 @@ class SparseGaussianProcessRegression
607619
const std::vector<InducingFeatureType> &inducing_features,
608620
const std::vector<FeatureType> &out_of_order_features,
609621
const MarginalDistribution &out_of_order_targets,
610-
BlockDiagonalLDLT *A_ldlt, Eigen::SerializableLDLT *K_uu_ldlt,
622+
const Eigen::SerializableLDLT &K_uu_ldlt, BlockDiagonalLDLT *A_ldlt,
611623
Eigen::MatrixXd *K_fu, Eigen::VectorXd *y) const {
612624

613625
ALBATROSS_ASSERT(A_ldlt != nullptr);
614-
ALBATROSS_ASSERT(K_uu_ldlt != nullptr);
615626
ALBATROSS_ASSERT(K_fu != nullptr);
616627
ALBATROSS_ASSERT(y != nullptr);
617628

@@ -645,18 +656,11 @@ class SparseGaussianProcessRegression
645656
*K_fu = this->covariance_function_(features, inducing_features,
646657
Base::threads_.get());
647658

648-
auto K_uu =
649-
this->covariance_function_(inducing_features, Base::threads_.get());
650-
651-
K_uu.diagonal() +=
652-
inducing_nugget_.value * Eigen::VectorXd::Ones(K_uu.rows());
653-
654-
*K_uu_ldlt = K_uu.ldlt();
655659
// P is such that:
656660
// Q_ff = K_fu K_uu^-1 K_uf
657661
// = K_fu K_uu^-T/2 K_uu^-1/2 K_uf
658662
// = P^T P
659-
const Eigen::MatrixXd P = K_uu_ldlt->sqrt_solve(K_fu->transpose());
663+
const Eigen::MatrixXd P = K_uu_ldlt.sqrt_solve(K_fu->transpose());
660664

661665
// We only need the diagonal blocks of Q_ff to get A
662666
BlockDiagonal Q_ff_diag;

0 commit comments

Comments
 (0)