@@ -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
598600private:
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