19 #if EIGEN_VERSION_AT_LEAST(3, 1, 0) // Requires Eigen>=3.1
20 #include <Eigen/SparseCore>
21 #include <Eigen/SparseQR>
87 Eigen::VectorXd& solved_x_inc,
89 Eigen::VectorXd* solved_variances)
95 #if EIGEN_VERSION_AT_LEAST(3, 1, 0)
99 solved_x_inc.setZero(
n);
103 const size_t m = m1 + m2;
109 std::vector<Eigen::Triplet<double>> A_tri;
110 A_tri.reserve(m1 + 2 * m2);
115 int edge_counter = 0;
120 const double w = std::sqrt(e->getInformation());
122 e->evalJacobian(dr_dx);
123 const int node_id = e->node_id;
125 Eigen::Triplet<double>(edge_counter, node_id,
w * dr_dx));
127 g[edge_counter] -=
w * e->evaluateResidual();
135 const double w = std::sqrt(e->getInformation());
136 double dr_dxi, dr_dxj;
137 e->evalJacobian(dr_dxi, dr_dxj);
138 const int node_id_i = e->node_id_i, node_id_j = e->node_id_j;
140 Eigen::Triplet<double>(edge_counter, node_id_i,
w * dr_dxi));
142 Eigen::Triplet<double>(edge_counter, node_id_j,
w * dr_dxj));
144 g[edge_counter] -=
w * e->evaluateResidual();
152 Eigen::SparseMatrix<double> A(m,
n);
157 A.setFromTriplets(A_tri.begin(), A_tri.end());
163 Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int>>
169 solved_x_inc = solver.solve(
g);
174 if (solved_variances)
178 solved_variances->resize(
n);
184 MRPT_TODO(
"Use compressed access instead of coeff() below");
186 Eigen::SparseMatrix<double> UT = solver.matrixR();
187 Eigen::SparseMatrix<double> solved_covariance(
n,
n);
188 solved_covariance.reserve(UT.nonZeros());
191 const int show_progress_steps = std::max(
int(20),
int(
n / 20));
192 for (
int l =
n - 1; l >= 0; l--)
194 if (!(l % show_progress_steps))
196 "Computing variance %6.02f%%... \r",
197 (100.0 * (
n - l - 1)) /
n);
200 double subSigmas = 0.0;
201 for (
size_t j = l + 1; j <
n; j++)
203 if (UT.coeff(l, j) != 0)
209 for (
size_t i = l + 1; i <= j; i++)
211 if (UT.coeff(l, i) != 0)
214 UT.coeff(l, i) * solved_covariance.coeff(i, j);
218 for (
size_t i = j + 1; i <
n; ++i)
220 if (UT.coeff(l, i) != 0)
223 UT.coeff(l, i) * solved_covariance.coeff(j, i);
227 solved_covariance.insert(l, j) = (-
sum / UT.coeff(l, l));
228 subSigmas += UT.coeff(l, j) * solved_covariance.coeff(l, j);
232 solved_covariance.insert(l, l) =
233 (1 / UT.coeff(l, l)) * (1 / UT.coeff(l, l) - subSigmas);
238 for (
unsigned int i = 0; i <
n; i++)
240 const int idx = (int)solver.colsPermutation().indices().coeff(i);
241 const double variance = solved_covariance.coeff(i, i);
242 (*solved_variances)[idx] = variance;