28 const std::string& indent,
const KeyFormatter& keyFormatter) {
31 if(boost::dynamic_pointer_cast<LinearContainerFactor>(factor)) {
37 std::cout << keyFormatter(
key) <<
" ";
39 std::cout <<
")" << std::endl;
41 std::cout <<
"{ nullptr }" << std::endl;
47 const std::string& indent,
const std::string& title,
const KeyFormatter& keyFormatter) {
48 std::cout << indent << title << std::endl;
56 const std::string& indent,
const std::string& title,
const KeyFormatter& keyFormatter) {
57 std::cout << indent << title << std::endl;
58 for(
size_t slot: slots) {
65 const std::string& indent,
const KeyFormatter& keyFormatter) {
78 std::cout << keyFormatter(
key) <<
" ";
80 std::cout <<
")" << std::endl;
82 std::cout <<
"{ nullptr }" << std::endl;
88 const std::string& indent,
const std::string& title,
const KeyFormatter& keyFormatter) {
89 std::cout << indent << title << std::endl;
122 const boost::optional<
FastList<Key> >& keysToMove,
const boost::optional< std::vector<size_t> >& removeFactorIndices) {
127 const bool debug =
false;
129 if(debug) std::cout <<
"ConcurrentBatchFilter::update Begin" << std::endl;
134 if(debug) std::cout <<
"ConcurrentBatchFilter::update Augmenting System ..." << std::endl;
137 gttic(augment_system);
142 for(
const auto key_value: newTheta) {
151 if(removeFactorIndices){
153 std::cout <<
"ConcurrentBatchFilter::update removeFactorIndices " << std::endl;
158 gttoc(augment_system);
160 if(debug) std::cout <<
"ConcurrentBatchFilter::update Reordering System ..." << std::endl;
167 if(debug) std::cout <<
"ConcurrentBatchFilter::update Optimizing System ..." << std::endl;
176 if(debug) std::cout <<
"ConcurrentBatchFilter::update Moving Separator ..." << std::endl;
178 gttic(move_separator);
179 if(keysToMove && keysToMove->size() > 0){
182 gttoc(move_separator);
184 if(debug) std::cout <<
"ConcurrentBatchFilter::update End" << std::endl;
205 const bool debug =
false;
207 if(debug) std::cout <<
"ConcurrentBatchFilter::synchronize Begin" << std::endl;
213 std::set<Key> newKeys = smootherSummarization.
keys();
214 assert(oldKeys.size() == newKeys.size());
215 assert(
std::equal(oldKeys.begin(), oldKeys.end(), newKeys.begin()));
226 newSeparatorKeys.insert(key_value.key);
229 if(debug) {
PrintKeys(newSeparatorKeys,
"ConcurrentBatchFilter::synchronize ",
"Current Separator Keys:"); }
238 values.
insert(smootherSummarizationValues);
239 for(
const auto key_value: separatorValues_) {
240 if(!values.
exists(key_value.key)) {
241 values.
insert(key_value.key, key_value.value);
273 if(debug) std::cout <<
"ConcurrentBatchFilter::synchronize End" << std::endl;
281 gttic(get_summarized_factors);
287 gttoc(get_summarized_factors);
293 gttic(get_smoother_factors);
299 gttoc(get_smoother_factors);
317 gttic(insert_factors);
320 std::vector<size_t> slots;
321 slots.reserve(factors.
size());
334 slots.push_back(slot);
337 gttoc(insert_factors);
345 gttic(remove_factors);
348 for(
size_t slot: slots) {
357 gttoc(remove_factors);
364 if(keysToMove && keysToMove->size() > 0) {
378 const bool debug =
false;
380 if(debug) std::cout <<
"ConcurrentBatchFilter::optimize Begin" << std::endl;
390 double lambdaLowerBound = 1.0e-10;
394 double errorTol = parameters.
errorTol;
401 if(result.
error <= errorTol) {
402 if(debug) { std::cout <<
"Exiting, as error = " << result.
error <<
" < " << errorTol << std::endl; }
406 std::cout <<
"linearValues: " << linearValues.
size() << std::endl;
407 std::cout <<
"Initial error: " << result.
error << std::endl;
411 double previousError;
414 previousError = result.
error;
417 gttic(optimizer_iteration);
425 if(debug) { std::cout <<
"trying lambda = " << lambda << std::endl; }
435 size_t dim = key_value.second.size();
436 Matrix A = Matrix::Identity(dim,dim);
450 evalpoint = theta.
retract(newDelta);
454 gttic(compute_error);
456 gttoc(compute_error);
459 std::cout <<
"linear delta norm = " << newDelta.
norm() << std::endl;
460 std::cout <<
"next error = " << error << std::endl;
463 if(error < result.
error) {
472 if(linearValues.
size() > 0) {
473 theta.
update(linearValues);
474 for(
const auto key_value: linearValues) {
475 delta.at(key_value.key) = newDelta.
at(key_value.key);
480 lambda /= lambdaFactor;
481 if(lambda < lambdaLowerBound) {
482 lambda = lambdaLowerBound;
488 if(lambda >= lambdaUpperBound) {
490 std::cout <<
"Warning: Levenberg-Marquardt giving up because cannot decrease error with maximum lambda" << std::endl;
494 lambda *= lambdaFactor;
499 gttoc(optimizer_iteration);
501 if(debug) { std::cout <<
"using lambda = " << lambda << std::endl; }
507 if(debug) { std::cout <<
"newError: " << result.
error << std::endl; }
509 if(debug) std::cout <<
"ConcurrentBatchFilter::optimize End" << std::endl;
528 const bool debug =
false;
530 if(debug) std::cout <<
"ConcurrentBatchFilter::moveSeparator Begin" << std::endl;
536 std::vector<size_t> removedFactorSlots;
538 for(
Key key: keysToMove) {
539 const auto& slots = variableIndex[
key];
540 removedFactorSlots.insert(removedFactorSlots.end(), slots.begin(), slots.end());
544 std::sort(removedFactorSlots.begin(), removedFactorSlots.end());
545 removedFactorSlots.erase(std::unique(removedFactorSlots.begin(), removedFactorSlots.end()), removedFactorSlots.end());
548 removedFactorSlots.erase(std::remove(removedFactorSlots.begin(), removedFactorSlots.end(), index), removedFactorSlots.end());
553 std::cout <<
"ConcurrentBatchFilter::moveSeparator Removed Factor Slots: ";
554 for(
size_t slot: removedFactorSlots) {
555 std::cout << slot <<
" ";
557 std::cout << std::endl;
562 for(
size_t slot: removedFactorSlots) {
576 KeySet newSeparatorKeys = removedFactors.
keys();
578 newSeparatorKeys.insert(key_value.key);
580 for(
Key key: keysToMove) {
581 newSeparatorKeys.erase(
key);
587 KeySet shortcutKeys = newSeparatorKeys;
589 shortcutKeys.insert(
key);
629 separatorSummarizationSlots_ =
insertFactors(separatorSummarization);
634 separatorValues_.clear();
644 for(
Key key: keysToMove) {
649 for(
Key key: keysToMove) {
655 if(debug) std::cout <<
"ConcurrentBatchFilter::moveSeparator End" << std::endl;
bool equals(const ConcurrentFilter &rhs, double tol=1e-9) const override
static void optimize(const NonlinearFactorGraph &factors, Values &theta, const Ordering &ordering, VectorValues &delta, const Values &linearValues, const LevenbergMarquardtParams ¶meters, Result &result)
A Levenberg-Marquardt Batch Filter that implements the Concurrent Filtering and Smoothing interface...
void replace(size_t index, sharedFactor factor)
VectorValues optimize(const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
NonlinearFactorGraph smootherSummarization_
The smoother summarization on the old separator sent by the smoother during the last synchronization...
GTSAM_EXPORT bool equals(const Ordering &other, double tol=1e-9) const
Wrap Jacobian and Hessian linear factors to allow simple injection into a nonlinear graph...
double error
The final factor graph error.
std::vector< size_t > newFactorsIndices
Point2 prior(const Point2 &x)
Prior on a single pose.
noiseModel::Diagonal::shared_ptr model
void insert(Key j, const Value &val)
static enum @843 ordering
void moveSeparator(const FastList< Key > &keysToMove)
double lambdaFactor
The amount by which to multiply or divide lambda when adjusting lambda (default: 10.0)
static const double sigma
void removeFactors(const std::vector< size_t > &slots)
Values separatorValues_
The linearization points of the separator variables. These should not be updated during optimization...
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
GaussianFactorGraph factors(list_of(factor1)(factor2)(factor3))
Values retract(const VectorValues &delta) const
std::queue< size_t > availableSlots_
The set of available factor graph slots caused by deleting factors.
IsDerived< DERIVEDFACTOR > push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
size_t lambdas
The number of different L-M lambda factors that were tried during optimization.
NonlinearFactorGraph graph
static const KeyFormatter DefaultKeyFormatter
bool equals(const Values &other, double tol=1e-9) const
double absoluteErrorTol
The maximum absolute error decrease to stop iterating (default 1e-5)
static Ordering Colamd(const FACTOR_GRAPH &graph)
double relativeErrorTol
The maximum relative error decrease to stop iterating (default 1e-5)
static void PrintLinearFactor(const GaussianFactor::shared_ptr &factor, const std::string &indent="", const KeyFormatter &keyFormatter=DefaultKeyFormatter)
static void PrintKeys(const Container &keys, const std::string &indent, const std::string &title, const KeyFormatter &keyFormatter=DefaultKeyFormatter)
Implementation of PrintKeys.
double errorTol
The maximum total error to stop iterating (default 0.0)
bool equals(const NonlinearFactorGraph &other, double tol=1e-9) const
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
bool checkConvergence(double relativeErrorTreshold, double absoluteErrorTreshold, double errorThreshold, double currentError, double newError, NonlinearOptimizerParams::Verbosity verbosity)
const ValueType at(Key j) const
virtual Result update(const NonlinearFactorGraph &newFactors=NonlinearFactorGraph(), const Values &newTheta=Values(), const boost::optional< FastList< Key > > &keysToMove=boost::none, const boost::optional< std::vector< size_t > > &removeFactorIndices=boost::none)
void print(const std::string &s="Concurrent Batch Filter:\n", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
boost::shared_ptr< This > shared_ptr
boost::shared_ptr< This > shared_ptr
A shared_ptr to this class.
GaussianFactorGraph::Eliminate getEliminationFunction() const
void reorder(const boost::optional< FastList< Key > > &keysToMove=boost::none)
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
NonlinearFactorGraph smootherShortcut_
A set of conditional factors from the old separator to the current separator (recursively calculated ...
NonlinearFactorGraph calculateMarginalFactors(const NonlinearFactorGraph &graph, const Values &theta, const KeySet &remainingKeys, const GaussianFactorGraph::Eliminate &eliminateFunction)
size_t linearVariables
The number of variables that must keep a constant linearization point.
size_t nonlinearVariables
The number of variables that can be relinearized.
static Ordering ColamdConstrainedFirst(const FACTOR_GRAPH &graph, const KeyVector &constrainFirst, bool forceOrder=false)
bool equals(const VectorValues &x, double tol=1e-9) const
value_type KeyValuePair
Typedef to pair<Key, Vector>
LevenbergMarquardtParams parameters_
LM parameters.
Values theta_
Current linearization point of all variables in the filter.
boost::shared_ptr< This > shared_ptr
shared_ptr to this class
static ConjugateGradientParameters parameters
cout<< "The eigenvalues of A are:"<< endl<< ces.eigenvalues()<< endl;cout<< "The matrix of eigenvectors, V, is:"<< endl<< ces.eigenvectors()<< endl<< endl;complex< float > lambda
size_t iterations
The number of optimizer iterations performed.
const mpreal dim(const mpreal &a, const mpreal &b, mp_rnd_t r=mpreal::get_default_rnd())
noiseModel::Diagonal::shared_ptr SharedDiagonal
const sharedFactor at(size_t i) const
static void PrintNonlinearFactorGraph(const NonlinearFactorGraph &factors, const std::string &indent="", const std::string &title="", const KeyFormatter &keyFormatter=DefaultKeyFormatter)
NonlinearFactorGraph smootherFactors_
A temporary holding place for the set of full nonlinear factors being sent to the smoother...
VectorValues delta_
The current set of linear deltas from the linearization point.
Ordering ordering_
The current ordering used to calculate the linear deltas.
A Gaussian factor using the canonical parameters (information form)
void update(Key j, const Value &val)
void reserve(size_t size)
NonlinearFactorGraph factors_
The set of all factors currently in the filter.
void getSmootherFactors(NonlinearFactorGraph &smootherFactors, Values &smootherValues) override
double error(const Values &values) const
NonlinearFactorGraph filterSummarization_
A temporary holding place for calculated filter summarization factors to be sent to the smoother...
double lambdaUpperBound
The maximum lambda to try before assuming the optimization has failed (default: 1e5) ...
std::vector< size_t > separatorSummarizationSlots_
The slots in factor graph that correspond to the current smoother summarization on the current separa...
boost::shared_ptr< This > shared_ptr
shared_ptr to this class
void synchronize(const NonlinearFactorGraph &smootherSummarization, const Values &smootherSummarizationValues) override
boost::shared_ptr< GaussianFactorGraph > linearize(const Values &linearizationPoint) const
Linearize a nonlinear factor graph.
void getSummarizedFactors(NonlinearFactorGraph &filterSummarization, Values &filterSummarizationValues) override
bool equal(const T &obj1, const T &obj2, double tol)
iterator insert(const std::pair< Key, Vector > &key_value)
std::uint64_t Key
Integer nonlinear key type.
static void PrintLinearFactorGraph(const GaussianFactorGraph &factors, const std::string &indent="", const std::string &title="", const KeyFormatter &keyFormatter=DefaultKeyFormatter)
static void PrintNonlinearFactor(const NonlinearFactor::shared_ptr &factor, const std::string &indent="", const KeyFormatter &keyFormatter=DefaultKeyFormatter)
size_t maxIterations
The maximum iterations to stop iterating (default 100)
static shared_ptr Sigma(size_t dim, double sigma, bool smart=true)
double lambdaInitial
The initial Levenberg-Marquardt damping term (default: 1e-5)
Values smootherValues_
A temporary holding place for the linearization points of all keys being sent to the smoother...
std::vector< size_t > insertFactors(const NonlinearFactorGraph &factors)