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

Hybrid Factor Graph Implementation #1203

Merged
merged 76 commits into from
Jun 3, 2022
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
ea4ebb6
Fix typo
ProfFan Mar 11, 2022
0567303
Prototype a type-erased hybrid machinery
ProfFan Mar 11, 2022
efa37ff
Add better mocking for actual elimination
ProfFan Mar 12, 2022
3aac52c
Fix compilation error
ProfFan Mar 12, 2022
53551e0
Add shorthand for inserting raw JacobianFactor
ProfFan Mar 12, 2022
095f6ad
Add full elimination
ProfFan Mar 12, 2022
2bae286
More mock-ups added
ProfFan Mar 12, 2022
ee4f9d1
Added mixture factor functionality
ProfFan Mar 13, 2022
5ea614a
Added more mockups and color output of the elimination process
ProfFan Mar 14, 2022
0aeb596
add more comments
ProfFan Mar 14, 2022
fe5dde7
even better printing and comments
ProfFan Mar 14, 2022
f237438
Address comments
ProfFan Mar 15, 2022
36ee4ce
Missing pragma onces
ProfFan Mar 15, 2022
7ad2031
Now we have real multifrontal!
ProfFan Mar 22, 2022
d42fc21
Fully working Multifrontal
ProfFan Mar 24, 2022
1e8aae3
Add a test for EliminateSequential
ProfFan Mar 24, 2022
b4f8eea
Address comments
ProfFan Mar 24, 2022
4f8dfeb
Remove warning
ProfFan Mar 24, 2022
293ef61
Address comments
ProfFan Mar 24, 2022
a36c86a
Display debug messages only when DEBUG = true
ProfFan Mar 24, 2022
8b4283b
Add doxygen for GMM
ProfFan Mar 24, 2022
5f03e0f
Address compilation error on GCC
ProfFan Mar 24, 2022
8d88860
Fix GCC error
ProfFan Mar 24, 2022
d2dc620
Add Python bindings
ProfFan Mar 25, 2022
7f2fa61
Added more Python examples
ProfFan Mar 26, 2022
0f69b4c
Added plotting for nested dissection
ProfFan Mar 27, 2022
a9c1d43
Working iSAM for Hybrid
ProfFan Apr 1, 2022
1fe7e74
Merge remote-tracking branch 'origin/develop' into fan/prototype-hybr…
ProfFan Apr 16, 2022
2de3169
Fix compile
ProfFan Apr 20, 2022
1bf9952
Merge remote-tracking branch 'origin/develop' into fan/prototype-hybr…
ProfFan May 8, 2022
4e481ea
Fix the enable_if_t absence
ProfFan May 11, 2022
d012bcd
Remove most debug messages
ProfFan May 11, 2022
d5fd279
Merge remote-tracking branch 'origin/develop' into fan/prototype-hybr…
ProfFan May 21, 2022
2c4990b
Address Varun's comments
ProfFan May 21, 2022
04593cc
Fix compile error
ProfFan May 21, 2022
2ae2cb6
Don't crash anymore
ProfFan May 22, 2022
b8299d7
Don't use Python dict method since it is not
ProfFan May 23, 2022
74af969
Trying to make MSVC happy
ProfFan May 23, 2022
b215d3a
Address PR comments
ProfFan May 23, 2022
e36583e
include missing headers for msvc and fix warning
varunagrawal May 24, 2022
e325cd1
include GaussianJunctionTree
varunagrawal May 24, 2022
eb074e7
run formatting and rename wrappedFactors to asGaussianFactorGraphTree
varunagrawal May 24, 2022
3f239c2
fix equality checks
varunagrawal May 24, 2022
c3a92a4
Hybrid and Gaussian Mixture conditional docs and some refactor
varunagrawal May 27, 2022
b3cab1b
GaussianMixtureFactor docs
varunagrawal May 27, 2022
865d10d
Hybrid factor docs and minor refactor
varunagrawal May 27, 2022
573448f
make functional
varunagrawal May 27, 2022
6d26818
HybridDiscreteFactor docs and minor refactor
varunagrawal May 27, 2022
7bfa011
update tests
varunagrawal May 27, 2022
d60c4ac
add demarkers
varunagrawal May 27, 2022
adcbb65
HybridFactorGraph docs and minor updates
varunagrawal May 27, 2022
5d3ffb7
docs update
varunagrawal May 27, 2022
e2c7753
remove debug statements
varunagrawal May 27, 2022
30c8e1d
fix doxygen section
varunagrawal May 27, 2022
4ee4b37
HybridISAM docs
varunagrawal May 27, 2022
9d26a3d
remove debug statements and add docs
varunagrawal May 27, 2022
3bde044
add doc strings to python unit test and add assertions
varunagrawal May 27, 2022
f443cf3
add docs for HybridFactor
varunagrawal May 27, 2022
6cd20fb
break up EliminateHybrid into smaller functions
varunagrawal May 27, 2022
c3a59cf
update the EliminateHybrid note to be more specific
varunagrawal May 27, 2022
852a9b9
rename HybridFactorGraph to GaussianHybridFactorGraph
varunagrawal May 28, 2022
841e6b0
improved equality checks
varunagrawal May 28, 2022
1a8fa23
Merge pull request #46 from varunagrawal/feature/eliminate-hybrid
varunagrawal Jun 2, 2022
7c7b5dd
Rename files so that everything is HybridX
varunagrawal Jun 2, 2022
31ab1a3
update description of GaussianMixtureConditional
varunagrawal Jun 2, 2022
d2029f3
Add more information on conditionals requirement for GaussianMixture
varunagrawal Jun 2, 2022
c8bf9d3
rename GaussianMixtureConditional to GaussianMixture
varunagrawal Jun 2, 2022
2cc0611
Merge branch 'fan/prototype-hybrid-tr' into feature/GaussianHybridFac…
varunagrawal Jun 2, 2022
709bbb0
Merge pull request #47 from varunagrawal/feature/GaussianHybridFactor…
varunagrawal Jun 2, 2022
932e65c
Add GTSAM_EXPORT and Testable traits
varunagrawal Jun 2, 2022
2afa678
fix python test
varunagrawal Jun 2, 2022
3e10514
if checks for dynamic_cast
varunagrawal Jun 3, 2022
dd87747
separate out summing of frontals into separate function
varunagrawal Jun 3, 2022
92176db
add comments
varunagrawal Jun 3, 2022
b47cd9d
update GaussianMixture docstring
varunagrawal Jun 3, 2022
eeecb27
rename back to HybridJunctionTree
varunagrawal Jun 3, 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
1 change: 1 addition & 0 deletions gtsam/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set (gtsam_subdirs
inference
symbolic
discrete
hybrid
linear
nonlinear
sam
Expand Down
8 changes: 8 additions & 0 deletions gtsam/hybrid/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Install headers
set(subdir hybrid)
file(GLOB hybrid_headers "*.h")
# FIXME: exclude headers
install(FILES ${hybrid_headers} DESTINATION include/gtsam/hybrid)

# Add all tests
add_subdirectory(tests)
106 changes: 106 additions & 0 deletions gtsam/hybrid/GaussianMixtureConditional.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* ----------------------------------------------------------------------------

* 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 GaussianMixtureConditional.cpp
* @brief A hybrid conditional in the Conditional Linear Gaussian scheme
* @author Fan Jiang
* @author Varun Agrawal
* @author Frank Dellaert
* @date Mar 12, 2022
*/

#include <gtsam/base/utilities.h>
#include <gtsam/discrete/DecisionTree-inl.h>
#include <gtsam/hybrid/GaussianMixtureConditional.h>
#include <gtsam/inference/Conditional-inst.h>
#include <gtsam/linear/GaussianFactorGraph.h>

namespace gtsam {

GaussianMixtureConditional::GaussianMixtureConditional(
const KeyVector &continuousFrontals, const KeyVector &continuousParents,
const DiscreteKeys &discreteParents,
const GaussianMixtureConditional::Conditionals &conditionals)
: BaseFactor(CollectKeys(continuousFrontals, continuousParents),
discreteParents),
BaseConditional(continuousFrontals.size()),
conditionals_(conditionals) {}

/* *******************************************************************************/
const GaussianMixtureConditional::Conditionals &GaussianMixtureConditional::conditionals() {
return conditionals_;
}

/* *******************************************************************************/
GaussianMixtureConditional GaussianMixtureConditional::FromConditionalList(
const KeyVector &continuousFrontals, const KeyVector &continuousParents,
const DiscreteKeys &discreteParents,
const std::vector<GaussianConditional::shared_ptr> &conditionalsList) {
Conditionals dt(discreteParents, conditionalsList);

return GaussianMixtureConditional(continuousFrontals, continuousParents, discreteParents,
dt);
}

/* *******************************************************************************/
GaussianMixtureConditional::Sum GaussianMixtureConditional::add(
const GaussianMixtureConditional::Sum &sum) const {
using Y = GaussianFactorGraph;
auto add = [](const Y &graph1, const Y &graph2) {
auto result = graph1;
result.push_back(graph2);
return result;
};
const Sum wrapped = asGraph();
return sum.empty() ? wrapped : sum.apply(wrapped, add);
}

/* *******************************************************************************/
GaussianMixtureConditional::Sum GaussianMixtureConditional::asGraph() const {
auto lambda = [](const GaussianFactor::shared_ptr &factor) {
GaussianFactorGraph result;
result.push_back(factor);
return result;
};
return {conditionals_, lambda};
}

/* TODO(fan): this (for Testable) is not implemented! */
bool GaussianMixtureConditional::equals(const HybridFactor &lf, double tol) const {
return false;
}

/* *******************************************************************************/
void GaussianMixtureConditional::print(const std::string &s,
const KeyFormatter &formatter) const {
std::cout << s << ": ";
if (isContinuous_) std::cout << "Cont. ";
if (isDiscrete_) std::cout << "Disc. ";
if (isHybrid_) std::cout << "Hybr. ";
BaseConditional::print("", formatter);
std::cout << "Discrete Keys = ";
for (auto &dk : discreteKeys_) {
std::cout << "(" << formatter(dk.first) << ", " << dk.second << "), ";
}
std::cout << "\n";
conditionals_.print(
"", [&](Key k) { return formatter(k); },
[&](const GaussianConditional::shared_ptr &gf) -> std::string {
RedirectCout rd;
if (!gf->empty())
gf->print("", formatter);
else
return {"nullptr"};
return rd.str();
});
}
} // namespace gtsam
89 changes: 89 additions & 0 deletions gtsam/hybrid/GaussianMixtureConditional.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* ----------------------------------------------------------------------------

* 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 GaussianMixtureConditional.h
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be called GaussianMixture. I thought it was. Was it renamed?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In one of my reviews I asked it to be renamed to GaussianMixtureConditional so that it is obvious it is a conditional and contrasts with GaussianMixtureFactor. I can undo that if you'd like.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like you to undo it, yes.

* @brief A hybrid conditional in the Conditional Linear Gaussian scheme
* @author Fan Jiang
* @author Varun Agrawal
* @date Mar 12, 2022
*/

#pragma once

#include <gtsam/discrete/DecisionTree.h>
#include <gtsam/hybrid/HybridFactor.h>
#include <gtsam/inference/Conditional.h>
#include <gtsam/linear/GaussianConditional.h>

namespace gtsam {
class GaussianMixtureConditional : public HybridFactor,
public Conditional<HybridFactor, GaussianMixtureConditional> {
public:
using This = GaussianMixtureConditional;
using shared_ptr = boost::shared_ptr<GaussianMixtureConditional>;
using BaseFactor = HybridFactor;
using BaseConditional = Conditional<HybridFactor, GaussianMixtureConditional>;

using Conditionals = DecisionTree<Key, GaussianConditional::shared_ptr>;

Conditionals conditionals_;

public:
/**
* @brief Construct a new Gaussian Mixture object
*
* @param continuousFrontals the continuous frontals.
* @param continuousParents the continuous parents.
* @param discreteParents the discrete parents. Will be placed last.
* @param conditionals a decision tree of GaussianConditionals.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on the requirement of those conditionals. Do you check for it? Is an exception thrown when not correct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not resolved

*/
GaussianMixtureConditional(const KeyVector &continuousFrontals,
const KeyVector &continuousParents,
const DiscreteKeys &discreteParents,
const Conditionals &conditionals);

using Sum = DecisionTree<Key, GaussianFactorGraph>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One-line comment?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of the typedef Sum. It is not readable and would prefer another name such as GaussianFactorGraphTree or succinctly, GFGTree.


const Conditionals &conditionals();
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Combine Decision Trees
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved
*/
Sum add(const Sum &sum) const;

/**
* @brief Convert a DecisionTree of factors into a DT of Gaussian FGs.
*/
Sum asGraph() const;

/**
* @brief Make a Gaussian Mixture from a list of Gaussian conditionals
*
* @param continuousFrontals The continuous frontal variables
* @param continuousParents The continuous parent variables
* @param discreteParents Discrete parents variables
* @param conditionals List of conditionals
*/
static This FromConditionalList(
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved
const KeyVector &continuousFrontals, const KeyVector &continuousParents,
const DiscreteKeys &discreteParents,
const std::vector<GaussianConditional::shared_ptr> &conditionals);

/* TODO: this is only a stub */
bool equals(const HybridFactor &lf, double tol = 1e-9) const override;

/* print utility */
void print(
const std::string &s = "GaussianMixtureConditional\n",
const KeyFormatter &formatter = DefaultKeyFormatter) const override;
};
} // namespace gtsam
90 changes: 90 additions & 0 deletions gtsam/hybrid/GaussianMixtureFactor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* ----------------------------------------------------------------------------

* 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 GaussianMixtureFactor.cpp
* @brief A set of Gaussian factors indexed by a set of discrete keys.
* @author Fan Jiang
* @author Varun Agrawal
* @author Frank Dellaert
* @date Mar 12, 2022
*/

#include <gtsam/base/utilities.h>
#include <gtsam/discrete/DecisionTree-inl.h>
#include <gtsam/discrete/DecisionTree.h>
#include <gtsam/hybrid/GaussianMixtureFactor.h>
#include <gtsam/linear/GaussianFactorGraph.h>

namespace gtsam {

GaussianMixtureFactor::GaussianMixtureFactor(const KeyVector &continuousKeys,
const DiscreteKeys &discreteKeys,
const Factors &factors)
: Base(continuousKeys, discreteKeys), factors_(factors) {}
bool GaussianMixtureFactor::equals(const HybridFactor &lf, double tol) const {
return false;
}

/* *******************************************************************************/
GaussianMixtureFactor GaussianMixtureFactor::FromFactorList(
const KeyVector &continuousKeys, const DiscreteKeys &discreteKeys,
const std::vector<GaussianFactor::shared_ptr> &factorsList) {
Factors dt(discreteKeys, factorsList);

return GaussianMixtureFactor(continuousKeys, discreteKeys, dt);
}


/* *******************************************************************************/
void GaussianMixtureFactor::print(const std::string &s,
const KeyFormatter &formatter) const {
HybridFactor::print(s, formatter);
factors_.print(
"mixture = ", [&](Key k) { return formatter(k); },
[&](const GaussianFactor::shared_ptr &gf) -> std::string {
RedirectCout rd;
if (!gf->empty())
gf->print("", formatter);
else
return {"nullptr"};
return rd.str();
});
}

/* *******************************************************************************/
const GaussianMixtureFactor::Factors &GaussianMixtureFactor::factors() {
return factors_;
}

/* *******************************************************************************/
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved
GaussianMixtureFactor::Sum GaussianMixtureFactor::add(
const GaussianMixtureFactor::Sum &sum) const {
using Y = GaussianFactorGraph;
auto add = [](const Y &graph1, const Y &graph2) {
auto result = graph1;
result.push_back(graph2);
return result;
};
const Sum wrapped = wrappedFactors();
return sum.empty() ? wrapped : sum.apply(wrapped, add);
}

/* *******************************************************************************/
GaussianMixtureFactor::Sum GaussianMixtureFactor::wrappedFactors() const {
auto wrap = [](const GaussianFactor::shared_ptr &factor) {
GaussianFactorGraph result;
result.push_back(factor);
return result;
};
return {factors_, wrap};
}
} // namespace gtsam
69 changes: 69 additions & 0 deletions gtsam/hybrid/GaussianMixtureFactor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* ----------------------------------------------------------------------------

* 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 GaussianMixtureFactor.h
* @brief A set of Gaussian factors indexed by a set of discrete keys.
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved
* @author Fan Jiang
* @author Varun Agrawal
* @author Frank Dellaert
* @date Mar 12, 2022
*/

#pragma once

#include <gtsam/discrete/DecisionTree.h>
#include <gtsam/discrete/DiscreteKey.h>
#include <gtsam/hybrid/HybridFactor.h>
#include <gtsam/linear/GaussianFactor.h>

namespace gtsam {

class GaussianFactorGraph;

typedef std::vector<gtsam::GaussianFactor::shared_ptr> GaussianFactorVector;

class GaussianMixtureFactor : public HybridFactor {
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved
public:
using Base = HybridFactor;
using This = GaussianMixtureFactor;
using shared_ptr = boost::shared_ptr<This>;

using Factors = DecisionTree<Key, GaussianFactor::shared_ptr>;

Factors factors_;
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved

GaussianMixtureFactor() = default;

GaussianMixtureFactor(const KeyVector &continuousKeys,
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved
const DiscreteKeys &discreteKeys,
const Factors &factors);

using Sum = DecisionTree<Key, GaussianFactorGraph>;

const Factors &factors();

static This FromFactorList(
const KeyVector &continuousKeys, const DiscreteKeys &discreteKeys,
const std::vector<GaussianFactor::shared_ptr> &factors);

Sum add(const Sum &sum) const;

Sum wrappedFactors() const;

bool equals(const HybridFactor &lf, double tol = 1e-9) const override;
varunagrawal marked this conversation as resolved.
Show resolved Hide resolved

void print(
const std::string &s = "HybridFactor\n",
const KeyFormatter &formatter = DefaultKeyFormatter) const override;
};

} // namespace gtsam
16 changes: 16 additions & 0 deletions gtsam/hybrid/HybridBayesNet.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* ----------------------------------------------------------------------------
* 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 HybridBayesNet.cpp
* @brief A bayes net of Gaussian Conditionals indexed by discrete keys.
* @author Fan Jiang
* @date January 2022
*/

#include <gtsam/hybrid/HybridBayesNet.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this file?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't but could use it in the future? Seems fine to have it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kill until we need it.

Loading