25#include "eos/morphablemodel/PcaModel.hpp"
28#include "Eigen/Eigenvalues"
76inline std::pair<Eigen::MatrixXf, Eigen::VectorXf>
pca(
const Eigen::Ref<const Eigen::MatrixXf> data,
79 using Eigen::MatrixXf;
80 using Eigen::VectorXf;
85 cov = data.adjoint() * data;
88 cov = data * data.adjoint();
92 cov /= (data.rows() - 1);
94 const Eigen::SelfAdjointEigenSolver<MatrixXf> eig(cov);
96 const auto num_eigenvectors_to_keep = data.rows() - 1;
100 VectorXf eigenvalues = eig.eigenvalues()
101 .bottomRows(num_eigenvectors_to_keep)
103 MatrixXf eigenvectors = eig.eigenvectors().rightCols(num_eigenvectors_to_keep).rowwise().reverse();
111 eigenvectors = data.adjoint() * eigenvectors;
116 const VectorXf one_over_sqrt_eigenvalues = eigenvalues.array().rsqrt();
117 eigenvectors *= one_over_sqrt_eigenvalues.asDiagonal();
120 eigenvectors /= std::sqrt(data.rows() - 1);
123 return { eigenvectors, eigenvalues };
140inline std::pair<Eigen::MatrixXf, Eigen::VectorXf>
pca(
const Eigen::Ref<const Eigen::MatrixXf> data,
141 int num_eigenvectors_to_keep,
144 using Eigen::MatrixXf;
145 using Eigen::VectorXf;
147 VectorXf eigenvalues;
148 MatrixXf eigenvectors;
149 std::tie(eigenvectors, eigenvalues) =
pca(data, covariance_type);
152 assert(num_eigenvectors_to_keep <= eigenvectors.size());
153 return { eigenvectors.leftCols(num_eigenvectors_to_keep), eigenvalues.topRows(num_eigenvectors_to_keep) };
170inline std::pair<Eigen::MatrixXf, Eigen::VectorXf>
pca(
const Eigen::Ref<const Eigen::MatrixXf> data,
171 float variance_to_keep,
174 using Eigen::MatrixXf;
175 using Eigen::VectorXf;
177 assert(variance_to_keep >= 0.0f && variance_to_keep <= 1.0f);
179 VectorXf eigenvalues;
180 MatrixXf eigenvectors;
181 std::tie(eigenvectors, eigenvalues) =
pca(data, covariance_type);
186 auto num_eigenvectors_to_keep = eigenvalues.size();
187 const auto total_sum = eigenvalues.sum();
188 float cum_sum = 0.0f;
189 for (
int i = 0; i < eigenvalues.size(); ++i)
191 cum_sum += eigenvalues(i);
194 if (cum_sum / total_sum >= variance_to_keep)
196 num_eigenvectors_to_keep = i + 1;
202 assert(num_eigenvectors_to_keep <= eigenvectors.size());
203 return { eigenvectors.leftCols(num_eigenvectors_to_keep), eigenvalues.topRows(num_eigenvectors_to_keep) };
222 std::vector<std::array<int, 3>> triangle_list,
225 using Eigen::MatrixXf;
226 using Eigen::VectorXf;
230 const VectorXf mean = data.colwise().mean();
231 const MatrixXf meanfree_data = data.rowwise() - mean.transpose();
234 VectorXf eigenvalues;
235 MatrixXf eigenvectors;
236 std::tie(eigenvectors, eigenvalues) =
pca(meanfree_data, covariance_type);
This class represents a PCA-model that consists of:
Definition: PcaModel.hpp:59
std::pair< Eigen::MatrixXf, Eigen::VectorXf > pca(const Eigen::Ref< const Eigen::MatrixXf > data, Covariance covariance_type=Covariance::AtA)
Compute PCA on a mean-centred data matrix, and return the eigenvectors and respective eigenvalues.
Definition: pca.hpp:76
Covariance
Definition: pca.hpp:41
@ AtA
Compute the traditional covariance matrix A^t*A.
@ AAt
Use the inner product, A*A^t, for the covariance matrix.
Namespace containing all of eos's 3D model fitting functionality.