20 #if EIGEN_VERSION_AT_LEAST(3, 1, 0) // Requires Eigen>=3.1 21 #include <Eigen/SparseCore> 22 #include <Eigen/SparseQR> 27 : COutputLogger(
"GMRF"), m_enable_profiler(false)
88 Eigen::VectorXd& solved_x_inc,
90 Eigen::VectorXd* solved_variances)
96 #if EIGEN_VERSION_AT_LEAST(3, 1, 0) 100 solved_x_inc.setZero(
n);
104 const size_t m = m1 + m2;
110 std::vector<Eigen::Triplet<double>> A_tri;
111 A_tri.reserve(m1 + 2 * m2);
116 int edge_counter = 0;
121 const double w = std::sqrt(e->getInformation());
123 e->evalJacobian(dr_dx);
124 const int node_id = e->node_id;
126 Eigen::Triplet<double>(edge_counter, node_id,
w * dr_dx));
128 g[edge_counter] -=
w * e->evaluateResidual();
136 const double w = std::sqrt(e->getInformation());
137 double dr_dxi, dr_dxj;
138 e->evalJacobian(dr_dxi, dr_dxj);
139 const int node_id_i = e->node_id_i, node_id_j = e->node_id_j;
141 Eigen::Triplet<double>(edge_counter, node_id_i,
w * dr_dxi));
143 Eigen::Triplet<double>(edge_counter, node_id_j,
w * dr_dxj));
145 g[edge_counter] -=
w * e->evaluateResidual();
153 Eigen::SparseMatrix<double> A(m,
n);
158 A.setFromTriplets(A_tri.begin(), A_tri.end());
164 Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int>>
170 solved_x_inc = solver.solve(
g);
175 if (solved_variances)
179 solved_variances->resize(
n);
185 MRPT_TODO(
"Use compressed access instead of coeff() below");
187 Eigen::SparseMatrix<double> UT = solver.matrixR();
188 Eigen::SparseMatrix<double> solved_covariance(
n,
n);
189 solved_covariance.reserve(UT.nonZeros());
192 const int show_progress_steps = std::max(
int(20),
int(
n / 20));
193 for (
int l =
n - 1; l >= 0; l--)
195 if (!(l % show_progress_steps))
197 "Computing variance %6.02f%%... \r",
198 (100.0 * (
n - l - 1)) /
n);
201 double subSigmas = 0.0;
202 for (
size_t j = l + 1; j <
n; j++)
204 if (UT.coeff(l, j) != 0)
210 for (
size_t i = l + 1; i <= j; i++)
212 if (UT.coeff(l, i) != 0)
215 UT.coeff(l, i) * solved_covariance.coeff(i, j);
219 for (
size_t i = j + 1; i <
n; ++i)
221 if (UT.coeff(l, i) != 0)
224 UT.coeff(l, i) * solved_covariance.coeff(j, i);
228 solved_covariance.insert(l, j) = (-
sum / UT.coeff(l, l));
229 subSigmas += UT.coeff(l, j) * solved_covariance.coeff(l, j);
233 solved_covariance.insert(l, l) =
234 (1 / UT.coeff(l, l)) * (1 / UT.coeff(l, l) - subSigmas);
239 for (
unsigned int i = 0; i <
n; i++)
241 const int idx = (int)solver.colsPermutation().indices().coeff(i);
242 const double variance = solved_covariance.coeff(i, i);
243 (*solved_variances)[idx] = variance;
void initialize(const size_t nodeCount)
Initialize the GMRF internal state and copy the prior factors.
Simple, scalar (1-dim) constraint (edge) for a GMRF.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
bool eraseConstraint(const FactorBase &c)
Removes a constraint.
#define THROW_EXCEPTION(msg)
Abstract graph and tree data structures, plus generic graph algorithms.
#define MRPT_LOG_DEBUG_FMT(_FMT_STRING,...)
std::deque< const BinaryFactorVirtualBase * > m_factors_binary
const_iterator find(const KEY &key) const
GLubyte GLubyte GLubyte GLubyte w
void enable(bool enabled=true)
std::deque< const UnaryFactorVirtualBase * > m_factors_unary
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
mrpt::utils::CTimeLogger m_timelogger
#define MRPT_LOG_DEBUG(_STRING)
void addConstraint(const UnaryFactorVirtualBase &listOfConstraints)
Insert constraints into the GMRF problem.
size_t m_numNodes
number of nodes in the graph
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A safe way to call enter() and leave() of a mrpt::utils::CTimeLogger upon construction and destructio...
double leave(const char *func_name)
End of a named section.
void clear()
Reset state: remove all constraints and nodes.
Simple, scalar (1-dim) constraint (edge) for a GMRF.
void enter(const char *func_name)
Start of a named section.
#define MRPT_LOG_DEBUG_STREAM(__CONTENTS)
#define ASSERTMSG_(f, __ERROR_MSG)
void updateEstimation(Eigen::VectorXd &solved_x_inc, Eigen::VectorXd *solved_variances=nullptr)