37 const double tolerance,
38 const std::vector<size_t> &pivot) {
40 const auto n = A.rows();
42 std::vector<double> d(n);
44 auto error = A.diagonal()[0];
45 for (
size_t i = 0; i < n; ++i) {
46 d[i] = A.diagonal()[i];
47 error = std::max(d[i], error);
51 Eigen::MatrixXd L(n, n);
57 std::vector<size_t> piv;
59 for (
size_t i = 0; i < n; ++i) {
60 piv.push_back(pivot[i]);
63 while (error > tolerance && m < n) {
66 std::vector<double> err(d.size());
67 for (
size_t i = 0; i < d.size(); ++i) {
71 std::vector<double> err2(err.begin() + m, err.end());
72 std::vector<size_t> idx(err2.size());
73 for (
size_t i = 0; i < idx.size(); ++i) {
77 std::sort(idx.begin(), idx.end(),
78 [&err2](
size_t i1,
size_t i2) { return err2[i1] > err2[i2]; });
80 std::vector<size_t> piv_subvec(piv.size() - m);
81 for (
size_t i = 0; i < piv_subvec.size(); ++i) {
82 piv_subvec[i] = piv[i + m];
85 for (
size_t i = 0; i < idx.size(); ++i) {
86 piv[i + m] = piv_subvec[idx[i]];
94 L(m, pim) = std::sqrt(d[pim]);
97 for (
size_t i = m + 1; i < n; ++i) {
101 (m > 0) ? (A(pim, pii) - L.col(pim).head(m).dot(L.col(pii).head(m))) /
103 : (A(pim, pii)) / L(m, pim);
105 d[pii] -= L(m, pii) * L(m, pii);
109 error = d[piv[m + 1]];
110 for (
size_t i = m + 1; i < n; ++i) {
111 error = std::max(d[piv[i]], error);
118 L.transposeInPlace();
120 L.conservativeResize(n, m);
123 std::vector<size_t> reduced_piv;
124 reduced_piv.reserve(m);
125 for (
size_t i = 0; i < m; ++i) {
126 reduced_piv.push_back(piv[i]);
std::vector< size_t > pivoted_cholesky(const Eigen::MatrixXd &A, const double tolerance, const std::vector< size_t > &pivot)
computes the pivoted Cholesky decomposition of a symmetric positive definite matrix
Definition pivoted_cholesky.h:36