@@ -97,21 +97,19 @@ template <typename FeatureType> struct Fit<SparseGPFit<FeatureType>> {
9797
9898 std::vector<FeatureType> train_features;
9999 Eigen::SerializableLDLT train_covariance;
100- Eigen::MatrixXd sigma_R ;
101- PermutationIndices permutation_indices ;
100+ Eigen::MatrixXd R ;
101+ Eigen::PermutationMatrixX P ;
102102 Eigen::VectorXd information;
103103 Eigen::Index numerical_rank;
104104
105105 Fit (){};
106106
107107 Fit (const std::vector<FeatureType> &features_,
108108 const Eigen::SerializableLDLT &train_covariance_,
109- const Eigen::MatrixXd &sigma_R_,
110- PermutationIndices &&permutation_indices_,
109+ const Eigen::MatrixXd &R_, const Eigen::PermutationMatrixX &P_,
111110 const Eigen::VectorXd &information_, Eigen::Index numerical_rank_)
112- : train_features(features_), train_covariance(train_covariance_),
113- sigma_R (sigma_R_), permutation_indices(std::move(permutation_indices_)),
114- information(information_), numerical_rank(numerical_rank_) {}
111+ : train_features(features_), train_covariance(train_covariance_), R(R_),
112+ P (P_), information(information_), numerical_rank(numerical_rank_) {}
115113
116114 void shift_mean (const Eigen::VectorXd &mean_shift) {
117115 ALBATROSS_ASSERT (mean_shift.size () == information.size ());
@@ -120,9 +118,8 @@ template <typename FeatureType> struct Fit<SparseGPFit<FeatureType>> {
120118
121119 bool operator ==(const Fit<SparseGPFit<FeatureType>> &other) const {
122120 return (train_features == other.train_features &&
123- train_covariance == other.train_covariance &&
124- sigma_R == other.sigma_R &&
125- permutation_indices == other.permutation_indices &&
121+ train_covariance == other.train_covariance && R == other.R &&
122+ P.indices () == other.P .indices () &&
126123 information == other.information &&
127124 numerical_rank == other.numerical_rank );
128125 }
@@ -325,20 +322,17 @@ class SparseGaussianProcessRegression
325322 compute_internal_components (old_fit.train_features , features, targets,
326323 &A_ldlt, &K_uu_ldlt, &K_fu, &y);
327324
328- const Eigen::Index n_old = old_fit.sigma_R .rows ();
325+ const Eigen::Index n_old = old_fit.R .rows ();
329326 const Eigen::Index n_new = A_ldlt.rows ();
330- const Eigen::Index k = old_fit.sigma_R .cols ();
327+ const Eigen::Index k = old_fit.R .cols ();
331328 Eigen::MatrixXd B = Eigen::MatrixXd::Zero (n_old + n_new, k);
332329
333330 ALBATROSS_ASSERT (n_old == k);
334331
335332 // Form:
336333 // B = |R_old P_old^T| = |Q_1| R P^T
337334 // |A^{-1/2} K_fu| |Q_2|
338- for (Eigen::Index i = 0 ; i < old_fit.permutation_indices .size (); ++i) {
339- const Eigen::Index &pi = old_fit.permutation_indices .coeff (i);
340- B.col (pi).topRows (i + 1 ) = old_fit.sigma_R .col (i).topRows (i + 1 );
341- }
335+ B.topRows (old_fit.P .rows ()) = old_fit.R * old_fit.P .transpose ();
342336 B.bottomRows (n_new) = A_ldlt.sqrt_solve (K_fu);
343337 const auto B_qr = QRImplementation::compute (B, Base::threads_.get ());
344338
@@ -347,13 +341,9 @@ class SparseGaussianProcessRegression
347341 // |A^{-1/2} y |
348342 ALBATROSS_ASSERT (old_fit.information .size () == n_old);
349343 Eigen::VectorXd y_augmented (n_old + n_new);
350- for (Eigen::Index i = 0 ; i < old_fit.permutation_indices .size (); ++i) {
351- y_augmented[i] =
352- old_fit.information [old_fit.permutation_indices .coeff (i)];
353- }
354344 y_augmented.topRows (n_old) =
355- old_fit.sigma_R .template triangularView <Eigen::Upper>() *
356- y_augmented. topRows (n_old );
345+ old_fit.R .template triangularView <Eigen::Upper>() *
346+ (old_fit. P . transpose () * old_fit. information );
357347
358348 y_augmented.bottomRows (n_new) = A_ldlt.sqrt_solve (y, Base::threads_.get ());
359349 const Eigen::VectorXd v = B_qr->solve (y_augmented);
@@ -365,10 +355,9 @@ class SparseGaussianProcessRegression
365355 Eigen::VectorXd::Constant (B_qr->cols (), details::cSparseRNugget);
366356 }
367357 using FitType = Fit<SparseGPFit<InducingPointFeatureType>>;
368- return FitType (
369- old_fit.train_features , old_fit.train_covariance , R,
370- B_qr->colsPermutation ().indices ().template cast <Eigen::Index>(), v,
371- B_qr->rank ());
358+
359+ return FitType (old_fit.train_features , old_fit.train_covariance , R,
360+ get_P (*B_qr), v, B_qr->rank ());
372361 }
373362
374363 // Here we create the QR decomposition of:
@@ -415,10 +404,7 @@ class SparseGaussianProcessRegression
415404 using InducingPointFeatureType = typename std::decay<decltype (u[0 ])>::type;
416405
417406 using FitType = Fit<SparseGPFit<InducingPointFeatureType>>;
418- return FitType (
419- u, K_uu_ldlt, get_R (*B_qr),
420- B_qr->colsPermutation ().indices ().template cast <Eigen::Index>(), v,
421- B_qr->rank ());
407+ return FitType (u, K_uu_ldlt, get_R (*B_qr), get_P (*B_qr), v, B_qr->rank ());
422408 }
423409
424410 template <typename FeatureType>
@@ -471,9 +457,8 @@ class SparseGaussianProcessRegression
471457 const Eigen::MatrixXd sigma_inv_sqrt = C_ldlt.sqrt_solve (K_zz);
472458 const auto B_qr = QRImplementation::compute (sigma_inv_sqrt, nullptr );
473459
474- new_fit.permutation_indices =
475- B_qr->colsPermutation ().indices ().template cast <Eigen::Index>();
476- new_fit.sigma_R = get_R (*B_qr);
460+ new_fit.P = get_P (*B_qr);
461+ new_fit.R = get_R (*B_qr);
477462 new_fit.numerical_rank = B_qr->rank ();
478463
479464 return output;
@@ -519,8 +504,8 @@ class SparseGaussianProcessRegression
519504 Q_sqrt.cwiseProduct (Q_sqrt).array ().colwise ().sum ();
520505 marginal_variance -= Q_diag;
521506
522- const Eigen::MatrixXd S_sqrt = sqrt_solve (
523- sparse_gp_fit.sigma_R , sparse_gp_fit.permutation_indices , cross_cov);
507+ const Eigen::MatrixXd S_sqrt =
508+ sqrt_solve ( sparse_gp_fit.R , sparse_gp_fit.P , cross_cov);
524509 const Eigen::VectorXd S_diag =
525510 S_sqrt.cwiseProduct (S_sqrt).array ().colwise ().sum ();
526511 marginal_variance += S_diag;
@@ -537,8 +522,8 @@ class SparseGaussianProcessRegression
537522 this ->covariance_function_ (sparse_gp_fit.train_features , features);
538523 const Eigen::MatrixXd prior_cov = this ->covariance_function_ (features);
539524
540- const Eigen::MatrixXd S_sqrt = sqrt_solve (
541- sparse_gp_fit.sigma_R , sparse_gp_fit.permutation_indices , cross_cov);
525+ const Eigen::MatrixXd S_sqrt =
526+ sqrt_solve ( sparse_gp_fit.R , sparse_gp_fit.P , cross_cov);
542527
543528 const Eigen::MatrixXd Q_sqrt =
544529 sparse_gp_fit.train_covariance .sqrt_solve (cross_cov);
0 commit comments