Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonlinear Hybrid #1263

Merged
merged 42 commits into from
Aug 21, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2927d92
add HybridNonlinearFactor and nonlinear HybridFactorGraph
varunagrawal May 28, 2022
78ea90b
Add MixtureFactor for nonlinear factor types
varunagrawal May 28, 2022
e91a354
convert to cpp
varunagrawal May 29, 2022
9cbd2ef
Base Hybrid Factor Graph
varunagrawal May 29, 2022
01b9a65
make GaussianMixtureFactor a subclass of HybridGaussianFactor
varunagrawal May 29, 2022
fe0d666
HybridFactorGraph fixes
varunagrawal May 29, 2022
cdd030b
Make MixtureFactor only work with NonlinearFactors and make some impr…
varunagrawal May 29, 2022
08fab8a
HybridNonlinearFactor linearize method
varunagrawal May 29, 2022
9279bd6
push_back for GaussianHybridFactor
varunagrawal May 29, 2022
3274cb1
clean up testHybridFactorGraph, need to add more tests
varunagrawal May 29, 2022
6c36b2c
GaussianHybridFactorGraph inherits from HybridFactorGraph
varunagrawal May 29, 2022
85f4b48
Improvements to GaussianHybridFactorGraph, make MixtureFactor a subcl…
varunagrawal May 30, 2022
53e8c32
Add NonlinearHybridFactorGraph class
varunagrawal May 30, 2022
7e18277
fix base class
varunagrawal May 30, 2022
119679a
linearize returns object instead of pointer
varunagrawal May 30, 2022
3212dde
remove unneeded method
varunagrawal May 30, 2022
0c16799
GaussianMixtureFactor inherits from HybridFactor
varunagrawal May 30, 2022
e711a62
More tests working
varunagrawal May 30, 2022
3780b8c
Merge branch 'develop' into feature/nonlinear-hybrid
varunagrawal Jul 26, 2022
8ddc2ea
rename to HybridNonlinearFactorGraph
varunagrawal Jul 26, 2022
7a55341
add IsGaussian template check
varunagrawal Jul 26, 2022
43c28e7
renaming fixes
varunagrawal Jul 26, 2022
987448f
remove derived push_back in HybridNonlinearFactorGraph and HybridFact…
varunagrawal Jul 26, 2022
8471c97
add nonlinear switching system tests
varunagrawal Jul 30, 2022
8907922
get more nonlinear tests to work and make some updates
varunagrawal Aug 1, 2022
16124f3
get all but 2 tests passing
varunagrawal Aug 2, 2022
ee124c3
fix discrete only elimination (use EliminateForMPE)
varunagrawal Aug 2, 2022
b39c231
all tests pass!!!
varunagrawal Aug 2, 2022
0f732d7
fix discrete conditional test
varunagrawal Aug 3, 2022
6670779
Wrap DiscreteLookupTable
varunagrawal Aug 3, 2022
92a5868
Merge branch 'develop' into feature/nonlinear-hybrid
varunagrawal Aug 3, 2022
db56909
Merge branch 'hybrid/pruning' into feature/nonlinear-hybrid
varunagrawal Aug 3, 2022
5965d8f
change discrete key variable from C to M
varunagrawal Aug 8, 2022
f5e046f
split HybridNonlinearFactorGraph to .h and .cpp
varunagrawal Aug 8, 2022
51d2f07
fix printing and key bug in MixtureFactor linearize
varunagrawal Aug 8, 2022
a3eacaa
fix adding priors in Switching
varunagrawal Aug 8, 2022
588f56e
HybridGaussianISAM unit tests
varunagrawal Aug 8, 2022
60c88e3
fix print tests
varunagrawal Aug 10, 2022
4ea897c
cleaner printing
varunagrawal Aug 10, 2022
fbceda3
got some more tests working
varunagrawal Aug 10, 2022
0e4db30
use templetized constructor for MixtureFactor
varunagrawal Aug 10, 2022
2a974a4
Address review comments
varunagrawal Aug 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add NonlinearHybridFactorGraph class
  • Loading branch information
varunagrawal committed May 30, 2022
commit 53e8c32b40fc934f6491778c3638f5972214c8ab
209 changes: 209 additions & 0 deletions gtsam/hybrid/NonlinearHybridFactorGraph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/* ----------------------------------------------------------------------------

* GTSAM Copyright 2010, Georgia Tech Research Corporation,
* Atlanta, Georgia 30332-0415
* All Rights Reserved
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)

* See LICENSE for the license information

* -------------------------------------------------------------------------- */

/**
* @file NonlinearHybridFactorGraph.h
* @brief Nonlinear hybrid factor graph that uses type erasure
* @author Varun Agrawal
* @date May 28, 2022
*/

#pragma once

#include <gtsam/hybrid/GaussianHybridFactorGraph.h>
#include <gtsam/hybrid/HybridFactor.h>
#include <gtsam/hybrid/HybridFactorGraph.h>
#include <gtsam/hybrid/HybridNonlinearFactor.h>
#include <gtsam/hybrid/MixtureFactor.h>
#include <gtsam/inference/Ordering.h>
#include <gtsam/nonlinear/NonlinearFactor.h>

#include <boost/format.hpp>
namespace gtsam {

/**
* Nonlinear Hybrid Factor Graph
* -----------------------
* This is the non-linear version of a hybrid factor graph.
* Everything inside needs to be hybrid factor or hybrid conditional.
*/
class GTSAM_EXPORT NonlinearHybridFactorGraph : public HybridFactorGraph {
protected:
/// Check if FACTOR type is derived from NonlinearFactor.
template <typename FACTOR>
using IsNonlinear = typename std::enable_if<
std::is_base_of<NonlinearFactor, FACTOR>::value>::type;

public:
using Base = FactorGraph<HybridFactor>;
using This = NonlinearHybridFactorGraph; ///< this class
using shared_ptr = boost::shared_ptr<This>; ///< shared_ptr to This

using Values = gtsam::Values; ///< backwards compatibility
using Indices = KeyVector; ///> map from keys to values

/// @name Constructors
/// @{

NonlinearHybridFactorGraph() = default;

/**
* Implicit copy/downcast constructor to override explicit template container
* constructor. In BayesTree this is used for:
* `cachedSeparatorMarginal_.reset(*separatorMarginal)`
* */
template <class DERIVEDFACTOR>
NonlinearHybridFactorGraph(const FactorGraph<DERIVEDFACTOR>& graph)
: Base(graph) {}

/// @}

// Allow use of selected FactorGraph methods:
using Base::empty;
using Base::reserve;
using Base::size;
using Base::operator[];
using Base::add;
using Base::push_back;
using Base::resize;

/**
* Add a nonlinear factor *pointer* to the internal nonlinear factor graph
* @param nonlinearFactor - boost::shared_ptr to the factor to add
*/
template <typename FACTOR>
IsNonlinear<FACTOR> push_nonlinear(
const boost::shared_ptr<FACTOR>& nonlinearFactor) {
Base::push_back(boost::make_shared<HybridNonlinearFactor>(nonlinearFactor));
}

/// Construct a factor and add (shared pointer to it) to factor graph.
template <class FACTOR, class... Args>
IsNonlinear<FACTOR> emplace_nonlinear(Args&&... args) {
auto factor = boost::allocate_shared<FACTOR>(
Eigen::aligned_allocator<FACTOR>(), std::forward<Args>(args)...);
push_nonlinear(factor);
}

/**
* @brief Add a single factor shared pointer to the hybrid factor graph.
* Dynamically handles the factor type and assigns it to the correct
* underlying container.
*
* @tparam FACTOR The factor type template
* @param sharedFactor The factor to add to this factor graph.
*/
template <typename FACTOR>
void push_back(const boost::shared_ptr<FACTOR>& sharedFactor) {
if (auto p = boost::dynamic_pointer_cast<NonlinearFactor>(sharedFactor)) {
push_nonlinear(p);
} else {
Base::push_back(sharedFactor);
}
}

/** Constructor from iterator over factors (shared_ptr or plain objects) */
template <typename ITERATOR>
void push_back(ITERATOR firstFactor, ITERATOR lastFactor) {
for (auto&& it = firstFactor; it != lastFactor; it++) {
push_back(*it);
}
}

// /// Add a nonlinear factor to the factor graph.
// void add(NonlinearFactor&& factor) {
// Base::add(boost::make_shared<HybridNonlinearFactor>(std::move(factor)));
// }

/// Add a nonlinear factor as a shared ptr.
void add(boost::shared_ptr<NonlinearFactor> factor) {
FactorGraph::add(boost::make_shared<HybridNonlinearFactor>(factor));
}

/**
* Simply prints the factor graph.
*/
void print(
const std::string& str = "NonlinearHybridFactorGraph",
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const override {}

/**
* @return true if all internal graphs of `this` are equal to those of
* `other`
*/
bool equals(const NonlinearHybridFactorGraph& other,
double tol = 1e-9) const {
return false;
}

/**
* @brief Linearize all the continuous factors in the
* NonlinearHybridFactorGraph.
*
* @param continuousValues: Dictionary of continuous values.
* @return GaussianHybridFactorGraph::shared_ptr
*/
GaussianHybridFactorGraph::shared_ptr linearize(
const Values& continuousValues) const {
// create an empty linear FG
GaussianHybridFactorGraph::shared_ptr linearFG =
boost::make_shared<GaussianHybridFactorGraph>();

linearFG->reserve(size());

// linearize all hybrid factors
for (auto&& factor : factors_) {
// First check if it is a valid factor
if (factor) {
// Check if the factor is a hybrid factor.
// It can be either a nonlinear MixtureFactor or a linear
// GaussianMixtureFactor.
if (factor->isHybrid()) {
// Check if it is a nonlinear mixture factor
if (auto nlmf = boost::dynamic_pointer_cast<MixtureFactor>(factor)) {
linearFG->push_back(nlmf->linearize(continuousValues));
} else {
linearFG->push_back(factor);
}

// Now check if the factor is a continuous only factor.
} else if (factor->isContinuous()) {
// In this case, we check if factor->inner() is nonlinear since
// HybridFactors wrap over continuous factors.
auto nlhf =
boost::dynamic_pointer_cast<HybridNonlinearFactor>(factor);
if (auto nlf =
boost::dynamic_pointer_cast<NonlinearFactor>(nlhf->inner())) {
auto hgf = boost::make_shared<HybridGaussianFactor>(
nlf->linearize(continuousValues));
linearFG->push_back(hgf);
} else {
linearFG->push_back(factor);
}
// Finally if nothing else, we are discrete-only which doesn't need
// lineariztion.
} else {
linearFG->push_back(factor);
}

} else {
linearFG->push_back(GaussianFactor::shared_ptr());
}
}
return linearFG;
}
};

template <>
struct traits<NonlinearHybridFactorGraph>
: public Testable<NonlinearHybridFactorGraph> {};

} // namespace gtsam
3 changes: 3 additions & 0 deletions gtsam/hybrid/tests/Switching.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ using gtsam::symbol_shorthand::C;
using gtsam::symbol_shorthand::X;

namespace gtsam {

using MotionModel = BetweenFactor<double>;

inline GaussianHybridFactorGraph::shared_ptr makeSwitchingChain(
size_t n, std::function<Key(int)> keyFunc = X,
std::function<Key(int)> dKeyFunc = C) {
Expand Down
Loading