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;