34 const auto isotropic =
35 std::dynamic_pointer_cast<noiseModel::Isotropic>(model);
37 throw std::invalid_argument(
"FastSync requires isotropic noise model");
39 return isotropic->sigma();
44 const auto addMeasurement = [
this](
Key key1,
Key key2,
47 size_t expectedNoiseDimension) {
48 if (model->dim() != expectedNoiseDimension) {
49 throw std::invalid_argument(
50 "fastSync noise dimension does not match the factor residual");
52 const double sigma = isotropicSigma(model);
53 if (!std::isfinite(sigma) || sigma <= 0.0) {
54 throw std::invalid_argument(
55 "FastSync requires finite, positive measurement sigmas");
57 const MatrixN firstBlock = -measurement.matrix().transpose();
60 key1, firstBlock, key2, MatrixN::Identity(), VectorN::Zero(),
63 const auto addPrior = [
this](
Key key,
const T& value) {
64 if (++priorCount_ > 1) {
65 throw std::invalid_argument(
66 "fastSync supports at most one matching prior");
72 for (
const auto& factor : graph) {
73 if (
const auto between =
75 addMeasurement(between->key1(), between->key2(), between->measured(),
76 between->noiseModel(), T::dimension);
77 }
else if (
const auto between =
80 addMeasurement(between->key1(), between->key2(), between->measured(),
81 between->noiseModel(), N * N);
82 }
else if (
const auto prior =
84 addPrior(prior->key(), prior->prior());
85 }
else if (
const auto prior =
87 addPrior(prior->key(),
91 if (reducedGraph_.empty()) {
92 throw std::invalid_argument(
93 "FastSync requires at least one between measurement");
98void FastSync<T>::backSubstituteConditional(
102 if (frontalKey == gaugeKey)
return;
104 throw std::runtime_error(
105 "FastSync expected one frontal variable per conditional");
110 MatrixN sum = MatrixN::Zero();
111 size_t parentIndex = 0;
112 for (
const Key parentKey : conditional.
parents()) {
113 if (!solution.
exists(parentKey)) {
114 throw std::runtime_error(
115 "FastSync encountered an unsolved separator variable");
117 const MatrixN parentBlock = conditional.
S().template block<N, N>(
118 0,
static_cast<Eigen::Index
>(parentIndex * N));
119 sum.noalias() += solution.
at<MatrixN>(parentKey) * parentBlock.transpose();
123 const MatrixN R = conditional.
R();
124 const MatrixN transposeEstimate =
125 -R.template triangularView<Eigen::Upper>().solve(sum.transpose());
126 solution.
insert(frontalKey, MatrixN(transposeEstimate.transpose()));
131 return solveOrdered(Ordering::Create(orderingType, reducedGraph_));
136 const KeySet graphKeys = reducedGraph_.
keys();
137 const KeySet orderingKeys(ordering);
138 if (ordering.size() != graphKeys.size() || orderingKeys != graphKeys) {
139 throw std::invalid_argument(
140 "FastSync ordering must contain every measurement graph key exactly "
143 return solveOrdered(ordering);
148 const MatrixN identity = MatrixN::Identity();
149 const VectorN zero = VectorN::Zero();
152 const Key gaugeKey = ordering.back();
156 const auto bayesNet =
158 if (!bayesNet || bayesNet->
size() != ordering.size()) {
159 throw std::runtime_error(
"FastSync sequential Cholesky elimination failed");
163 solution.insert(gaugeKey, identity);
164 for (
size_t reverseIndex = bayesNet->
size(); reverseIndex > 0;
166 const auto& conditional = bayesNet->at(reverseIndex - 1);
167 backSubstituteConditional(*conditional, gaugeKey, solution);
170 if (solution.size() != ordering.size()) {
171 throw std::runtime_error(
"FastSync block back-substitution failed");
179 for (
const Key key : relaxed.
keys()) {
184 if (priorCount_ == 0)
return projected;
185 if (!projected.
exists(priorKey_)) {
186 throw std::invalid_argument(
187 "fastSync prior key is not in the measurement graph");
191 const T estimatedPrior = projected.
at<T>(priorKey_);
195 for (
const auto& keyValue : projected.
extract<T>()) {
196 aligned.
insert(keyValue.first,
Variable ordering for the elimination algorithm.
Chordal Bayes Net, the result of eliminating a factor graph.
Linear Factor Graph where all factors are Gaussians.
Various factors that minimize some Frobenius norm.
std::pair< std::shared_ptr< GaussianConditional >, std::shared_ptr< GaussianFactor > > EliminatePreferCholesky(const GaussianFactorGraph &factors, const Ordering &keys)
Densely partially eliminate with Cholesky factorization.
Definition HessianFactor.cpp:646
Global functions in a separate testing namespace.
Definition chartTesting.h:28
Values fastSync(const NonlinearFactorGraph &graph, Ordering::OrderingType orderingType)
Initialize a synchronization graph using FAST-Sync.
Definition FastSync-inl.h:204
noiseModel::Base::shared_ptr SharedNoiseModel
Aliases.
Definition NoiseModel.h:846
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
Matrix Lie Group Concept.
Definition MatrixLieGroup.h:358
IsDerived< DERIVEDFACTOR > emplace_shared(Args &&... args)
Emplace a shared pointer to factor of given type.
Definition FactorGraph.h:153
Key firstFrontalKey() const
Convenience function to get the first frontal key.
Definition Conditional.h:139
Parents parents() const
return a view of the parent keys
Definition Conditional.h:150
size_t nrFrontals() const
return the number of frontals
Definition Conditional.h:133
std::shared_ptr< BayesNetType > eliminateSequential(OptionalOrderingType orderingType={}, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex={}) const
Do sequential elimination of all variables to produce a Bayes net.
Definition EliminateableFactorGraph-inst.h:36
size_t size() const
Definition Factor.h:160
OrderingType
Type of ordering to use.
Definition Ordering.h:40
A GaussianConditional functions as the node in a Bayes network.
Definition GaussianConditional.h:43
constABlock R() const
Return a view of the upper-triangular R block of the conditional.
Definition GaussianConditional.h:237
constABlock S() const
Get a view of the parent blocks.
Definition GaussianConditional.h:240
A Linear Factor Graph is a factor graph where all factors are Gaussian, i.e.
Definition GaussianFactorGraph.h:77
A Gaussian factor in the squared-error form.
Definition JacobianFactor.h:92
static shared_ptr Sigma(size_t dim, double sigma, bool smart=true)
An isotropic noise model created by specifying a standard deviation sigma.
Definition NoiseModel.cpp:706
static shared_ptr Create(size_t dim)
Create a unit covariance noise model.
Definition NoiseModel.h:673
Definition NonlinearFactorGraph.h:57
A class for a soft prior on any Value type.
Definition PriorFactor.h:36
A non-templated config holding any types of Manifold-group elements.
Definition Values.h:65
const ValueType at(Key j) const
Retrieve a variable by key j.
Definition Values-inl.h:260
void insert(Key j, const Value &val)
Add a variable with the given j, throws KeyAlreadyExists<J> if j is already present.
Definition Values.cpp:170
KeyVector keys() const
Returns a vector of keys in the config.
Definition Values.cpp:235
Values extract(const KeyVector &keys) const
Returns a new Values holding copies of the values at the given keys, whatever their types.
Definition Values.cpp:252
bool exists(Key j) const
Check if a value exists with key j.
Definition Values.cpp:95
A class for a measurement predicted by "between(config[key1],config[key2])".
Definition BetweenFactor.h:45
Projection customization point used by fastSync().
Definition FastSync.h:54
Solver for the fixed-size ambient linear problem underlying FAST-Sync.
Definition FastSync.h:198
Values solve(Ordering::OrderingType orderingType=Ordering::METIS) const
Solve the relaxed ambient matrix problem and return one matrix per key.
Definition FastSync-inl.h:130
Values projectAndAlign(const Values &relaxed) const
Project relaxed matrices to T and align them to the optional matching prior stored by the constructor...
Definition FastSync-inl.h:177
FastSync(const NonlinearFactorGraph &graph)
Extract matching factors, validate their noise models, and build the reduced Gaussian graph.
Definition FastSync-inl.h:43
FrobeniusPrior calculates the Frobenius norm between a given matrix and a fixed-size matrix Lie group...
Definition FrobeniusFactor.h:100
FrobeniusBetweenFactor uses ||T2 - T1*T12_||_F, which only works if the Frobenius error is invariant ...
Definition FrobeniusFactor.h:366
In nonlinear factors, the error function returns the negative log-likelihood as a non-linear function...