HybridGaussianFactor.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
21 #include <gtsam/base/utilities.h>
29 
30 namespace gtsam {
31 
32 /* *******************************************************************************/
34  const FactorValuePairs &factors) {
35  // Find the minimum value so we can "proselytize" to positive values.
36  // Done because we can't have sqrt of negative numbers.
37  Factors gaussianFactors;
39  std::tie(gaussianFactors, valueTree) = unzip(factors);
40 
41  // Compute minimum value for normalization.
42  double min_value = valueTree.min();
43 
44  // Finally, update the [A|b] matrices.
45  auto update = [&min_value](const GaussianFactorValuePair &gfv) {
46  auto [gf, value] = gfv;
47 
48  auto jf = std::dynamic_pointer_cast<JacobianFactor>(gf);
49  if (!jf) return gf;
50 
51  double normalized_value = value - min_value;
52 
53  // If the value is 0, do nothing
54  if (normalized_value == 0.0) return gf;
55 
57  gfg.push_back(jf);
58 
59  Vector c(1);
60  // When hiding c inside the `b` vector, value == 0.5*c^2
61  c << std::sqrt(2.0 * normalized_value);
62  auto constantFactor = std::make_shared<JacobianFactor>(c);
63 
64  gfg.push_back(constantFactor);
65  return std::dynamic_pointer_cast<GaussianFactor>(
66  std::make_shared<JacobianFactor>(gfg));
67  };
68  return Factors(factors, update);
69 }
70 
71 /* *******************************************************************************/
73  KeyVector continuousKeys; // Continuous keys extracted from factors
74  DiscreteKeys discreteKeys; // Discrete keys provided to the constructors
75  FactorValuePairs pairs; // Used only if factorsTree is empty
77 
78  ConstructorHelper(const DiscreteKey &discreteKey,
79  const std::vector<GaussianFactor::shared_ptr> &factors)
80  : discreteKeys({discreteKey}) {
81  // Extract continuous keys from the first non-null factor
82  for (const auto &factor : factors) {
83  if (factor && continuousKeys.empty()) {
84  continuousKeys = factor->keys();
85  break;
86  }
87  }
88 
89  // Build the DecisionTree from the factor vector
91  }
92 
93  ConstructorHelper(const DiscreteKey &discreteKey,
94  const std::vector<GaussianFactorValuePair> &factorPairs)
95  : discreteKeys({discreteKey}) {
96  // Extract continuous keys from the first non-null factor
97  for (const auto &pair : factorPairs) {
98  if (pair.first && continuousKeys.empty()) {
99  continuousKeys = pair.first->keys();
100  break;
101  }
102  }
103 
104  // Build the FactorValuePairs DecisionTree
105  pairs = FactorValuePairs(discreteKeys, factorPairs);
106  }
107 
109  const FactorValuePairs &factorPairs)
111  // Extract continuous keys from the first non-null factor
112  factorPairs.visit([&](const GaussianFactorValuePair &pair) {
113  if (pair.first && continuousKeys.empty()) {
114  continuousKeys = pair.first->keys();
115  }
116  });
117 
118  // Build the FactorValuePairs DecisionTree
119  pairs = factorPairs;
120  }
121 };
122 
123 /* *******************************************************************************/
125  : Base(helper.continuousKeys, helper.discreteKeys),
126  factors_(helper.factorsTree.empty() ? augment(helper.pairs)
127  : helper.factorsTree) {}
128 
129 /* *******************************************************************************/
131  const DiscreteKey &discreteKey,
132  const std::vector<GaussianFactor::shared_ptr> &factors)
134 
135 /* *******************************************************************************/
137  const DiscreteKey &discreteKey,
138  const std::vector<GaussianFactorValuePair> &factorPairs)
139  : HybridGaussianFactor(ConstructorHelper(discreteKey, factorPairs)) {}
140 
141 /* *******************************************************************************/
143  const FactorValuePairs &factors)
144  : HybridGaussianFactor(ConstructorHelper(discreteKeys, factors)) {}
145 
146 /* *******************************************************************************/
147 bool HybridGaussianFactor::equals(const HybridFactor &lf, double tol) const {
148  const This *e = dynamic_cast<const This *>(&lf);
149  if (e == nullptr) return false;
150 
151  // This will return false if either factors_ is empty or e->factors_ is
152  // empty, but not if both are empty or both are not empty:
153  if (factors_.empty() ^ e->factors_.empty()) return false;
154 
155  // Check the base and the factors:
156  return Base::equals(*e, tol) &&
157  factors_.equals(e->factors_, [tol](const auto &f1, const auto &f2) {
158  return (!f1 && !f2) || (f1 && f2 && f1->equals(*f2, tol));
159  });
160 }
161 
162 /* *******************************************************************************/
163 void HybridGaussianFactor::print(const std::string &s,
164  const KeyFormatter &formatter) const {
165  std::cout << (s.empty() ? "" : s + "\n");
166  std::cout << "HybridGaussianFactor" << std::endl;
168  std::cout << "{\n";
169  if (factors_.empty()) {
170  std::cout << " empty" << std::endl;
171  } else {
172  factors_.print(
173  "", [&](Key k) { return formatter(k); },
174  [&](const sharedFactor &gf) -> std::string {
175  RedirectCout rd;
176  std::cout << ":\n";
177  if (gf) {
178  gf->print("", formatter);
179  return rd.str();
180  } else {
181  return "nullptr";
182  }
183  });
184  }
185  std::cout << "}" << std::endl;
186 }
187 
188 /* *******************************************************************************/
190  const DiscreteValues &assignment) const {
191  return factors_(assignment);
192 }
193 
194 /* *******************************************************************************/
196  const GaussianFactorGraphTree &sum) const {
197  using Y = GaussianFactorGraph;
198  auto add = [](const Y &graph1, const Y &graph2) {
199  auto result = graph1;
200  result.push_back(graph2);
201  return result;
202  };
203  const auto tree = asGaussianFactorGraphTree();
204  return sum.empty() ? tree : sum.apply(tree, add);
205 }
206 
207 /* *******************************************************************************/
209  const {
210  auto wrap = [](const sharedFactor &gf) { return GaussianFactorGraph{gf}; };
211  return {factors_, wrap};
212 }
213 
214 /* *******************************************************************************/
217  const GaussianFactor::shared_ptr &gf, const VectorValues &values) {
218  // Check if valid pointer
219  if (gf) {
220  return gf->error(values);
221  } else {
222  // If nullptr this component was pruned, so we return maximum error. This
223  // way the negative exponential will give a probability value close to 0.0.
225  }
226 }
227 
228 /* *******************************************************************************/
230  const VectorValues &continuousValues) const {
231  // functor to convert from sharedFactor to double error value.
232  auto errorFunc = [&continuousValues](const sharedFactor &gf) {
233  return PotentiallyPrunedComponentError(gf, continuousValues);
234  };
235  DecisionTree<Key, double> error_tree(factors_, errorFunc);
236  return error_tree;
237 }
238 
239 /* *******************************************************************************/
241  // Directly index to get the component, no need to build the whole tree.
242  const sharedFactor gf = factors_(values.discrete());
243  return PotentiallyPrunedComponentError(gf, values.continuous());
244 }
245 
246 } // namespace gtsam
gtsam::HybridGaussianFactor::Factors
DecisionTree< Key, sharedFactor > Factors
typedef for Decision Tree of Gaussian factors.
Definition: HybridGaussianFactor.h:70
relicense.update
def update(text)
Definition: relicense.py:46
gtsam::HybridGaussianFactor::operator()
sharedFactor operator()(const DiscreteValues &assignment) const
Get factor at a given discrete assignment.
Definition: HybridGaussianFactor.cpp:189
GaussianFactorGraph.h
Linear Factor Graph where all factors are Gaussians.
gtsam::HybridValues
Definition: HybridValues.h:37
Y
const char Y
Definition: test/EulerAngles.cpp:31
test_constructor::f1
auto f1
Definition: testHybridNonlinearFactor.cpp:56
gtsam::HybridGaussianFactor::ConstructorHelper::continuousKeys
KeyVector continuousKeys
Definition: HybridGaussianFactor.cpp:73
s
RealScalar s
Definition: level1_cplx_impl.h:126
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
gtsam::HybridGaussianFactor::errorTree
AlgebraicDecisionTree< Key > errorTree(const VectorValues &continuousValues) const override
Compute error of the HybridGaussianFactor as a tree.
Definition: HybridGaussianFactor.cpp:229
gtsam::HybridFactor::equals
virtual bool equals(const HybridFactor &lf, double tol=1e-9) const
equals
Definition: HybridFactor.cpp:86
gtsam::HybridGaussianFactor::HybridGaussianFactor
HybridGaussianFactor()=default
Default constructor, mainly for serialization.
gtsam::HybridGaussianFactor::ConstructorHelper::ConstructorHelper
ConstructorHelper(const DiscreteKey &discreteKey, const std::vector< GaussianFactorValuePair > &factorPairs)
Definition: HybridGaussianFactor.cpp:93
gtsam::DecisionTree::empty
bool empty() const
Check if tree is empty.
Definition: DecisionTree.h:269
c
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
tree
Definition: testExpression.cpp:212
gtsam::DecisionTree::equals
bool equals(const DecisionTree &other, const CompareFunc &compare=&DefaultCompare) const
Definition: DecisionTree-inl.h:899
simple_graph::factors
const GaussianFactorGraph factors
Definition: testJacobianFactor.cpp:213
gtsam::HybridGaussianFactor::factors
const Factors & factors() const
Getter for GaussianFactor decision tree.
Definition: HybridGaussianFactor.h:161
gtsam::RedirectCout
Definition: base/utilities.h:16
gtsam::HybridFactor
Definition: HybridFactor.h:54
wrap
mxArray * wrap(const Class &value)
Definition: matlab.h:126
simple::graph2
NonlinearFactorGraph graph2()
Definition: testInitializePose3.cpp:72
gtsam::HybridGaussianFactor::ConstructorHelper::pairs
FactorValuePairs pairs
Definition: HybridGaussianFactor.cpp:75
formatter
const KeyFormatter & formatter
Definition: treeTraversal-inst.h:204
f2
double f2(const Vector2 &x)
Definition: testNumericalDerivative.cpp:56
gtsam::HybridGaussianFactor::add
GaussianFactorGraphTree add(const GaussianFactorGraphTree &sum) const
Combine the Gaussian Factor Graphs in sum and this while maintaining the original tree structure.
Definition: HybridGaussianFactor.cpp:195
different_sigmas::values
HybridValues values
Definition: testHybridBayesNet.cpp:195
gtsam::Factor
Definition: Factor.h:70
gtsam::DiscreteKeys
DiscreteKeys is a set of keys that can be assembled using the & operator.
Definition: DiscreteKey.h:41
gtsam::DecisionTree::print
void print(const std::string &s, const LabelFormatter &labelFormatter, const ValueFormatter &valueFormatter) const
GTSAM-style print.
Definition: DecisionTree-inl.h:905
gtsam::HybridGaussianFactor::print
void print(const std::string &s="", const KeyFormatter &formatter=DefaultKeyFormatter) const override
print
Definition: HybridGaussianFactor.cpp:163
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:38
gtsam::KeyVector
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:92
result
Values result
Definition: OdometryOptimize.cpp:8
HybridGaussianFactor.h
A set of GaussianFactors, indexed by a set of discrete keys.
utilities.h
gtsam::AlgebraicDecisionTree< Key >
gtsam::GaussianFactorGraph
Definition: GaussianFactorGraph.h:73
HybridFactor.h
gtsam::GaussianFactorValuePair
std::pair< GaussianFactor::shared_ptr, double > GaussianFactorValuePair
Alias for pair of GaussianFactor::shared_pointer and a double value.
Definition: HybridGaussianFactor.h:37
gtsam::VectorValues
Definition: VectorValues.h:74
gtsam::KeyFormatter
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: Key.h:35
DecisionTree.h
Decision Tree for use in DiscreteFactors.
gtsam::HybridGaussianFactor::ConstructorHelper::factorsTree
Factors factorsTree
Definition: HybridGaussianFactor.cpp:76
gtsam::GaussianFactor::shared_ptr
std::shared_ptr< This > shared_ptr
shared_ptr to this class
Definition: GaussianFactor.h:42
gtsam::DecisionTree::visit
void visit(Func f) const
Visit all leaves in depth-first fashion.
Definition: DecisionTree-inl.h:769
gtsam::DecisionTree::apply
DecisionTree apply(const Unary &op) const
Definition: DecisionTree-inl.h:922
gtsam::HybridGaussianFactor::equals
bool equals(const HybridFactor &lf, double tol=1e-9) const override
equals
Definition: HybridGaussianFactor.cpp:147
gtsam::HybridGaussianFactor::asGaussianFactorGraphTree
GaussianFactorGraphTree asGaussianFactorGraphTree() const
Helper function to return factors and functional to create a DecisionTree of Gaussian Factor Graphs.
Definition: HybridGaussianFactor.cpp:208
gtsam::DecisionTree< Key, sharedFactor >
gtsam::HybridGaussianFactor::ConstructorHelper::ConstructorHelper
ConstructorHelper(const DiscreteKeys &discreteKeys, const FactorValuePairs &factorPairs)
Definition: HybridGaussianFactor.cpp:108
gtsam::HybridFactor::print
void print(const std::string &s="HybridFactor\n", const KeyFormatter &formatter=DefaultKeyFormatter) const override
print
Definition: HybridFactor.cpp:94
empty
Definition: test_copy_move.cpp:19
gtsam
traits
Definition: chartTesting.h:28
gtsam::HybridGaussianFactor::FactorValuePairs
DecisionTree< Key, GaussianFactorValuePair > FactorValuePairs
typedef for Decision Tree of Gaussian factors and arbitrary value.
Definition: HybridGaussianFactor.h:68
DecisionTree-inl.h
gtsam::HybridGaussianFactor::sharedFactor
std::shared_ptr< GaussianFactor > sharedFactor
Definition: HybridGaussianFactor.h:65
gtsam::DiscreteValues
Definition: DiscreteValues.h:34
gtsam::FactorGraph::push_back
IsDerived< DERIVEDFACTOR > push_back(std::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:147
gtsam::DiscreteKey
std::pair< Key, size_t > DiscreteKey
Definition: DiscreteKey.h:38
gtsam::HybridGaussianFactor
Implementation of a discrete-conditioned hybrid factor. Implements a joint discrete-continuous factor...
Definition: HybridGaussianFactor.h:59
gtsam::AlgebraicDecisionTree::min
double min() const
Find the minimum values amongst all leaves.
Definition: AlgebraicDecisionTree.h:219
gtsam::HybridGaussianFactor::factors_
Factors factors_
Decision tree of Gaussian factors indexed by discrete keys.
Definition: HybridGaussianFactor.h:74
gtsam::tol
const G double tol
Definition: Group.h:79
gtsam::HybridGaussianFactor::error
double error(const HybridValues &values) const override
Compute the log-likelihood, including the log-normalizing constant.
Definition: HybridGaussianFactor.cpp:240
GaussianFactor.h
A factor with a quadratic error function - a Gaussian.
gtsam::HybridGaussianFactor::augment
static Factors augment(const FactorValuePairs &factors)
Helper function to augment the [A|b] matrices in the factor components with the additional scalar val...
Definition: HybridGaussianFactor.cpp:33
gtsam::unzip
std::pair< DecisionTree< L, T1 >, DecisionTree< L, T2 > > unzip(const DecisionTree< L, std::pair< T1, T2 > > &input)
unzip a DecisionTree with std::pair values.
Definition: DecisionTree.h:454
gtsam::HybridGaussianFactor::ConstructorHelper::discreteKeys
DiscreteKeys discreteKeys
Definition: HybridGaussianFactor.cpp:74
gtsam::Key
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:97
max
#define max(a, b)
Definition: datatypes.h:20
HybridValues.h
test_callbacks.value
value
Definition: test_callbacks.py:160
ceres::sqrt
Jet< T, N > sqrt(const Jet< T, N > &f)
Definition: jet.h:418
gtsam::RedirectCout::str
std::string str() const
return the string
Definition: utilities.cpp:5
gtsam::PotentiallyPrunedComponentError
static double PotentiallyPrunedComponentError(const GaussianFactor::shared_ptr &gf, const VectorValues &values)
Helper method to compute the error of a component.
Definition: HybridGaussianFactor.cpp:216
gtsam::HybridGaussianFactor::ConstructorHelper::ConstructorHelper
ConstructorHelper(const DiscreteKey &discreteKey, const std::vector< GaussianFactor::shared_ptr > &factors)
Definition: HybridGaussianFactor.cpp:78
gtsam::HybridGaussianFactor::ConstructorHelper
Definition: HybridGaussianFactor.cpp:72


gtsam
Author(s):
autogenerated on Fri Oct 4 2024 03:02:13