HybridNonlinearFactor.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 
20 
21 namespace gtsam {
22 
23 /* *******************************************************************************/
24 static void checkKeys(const KeyVector& continuousKeys,
25  const std::vector<NonlinearFactorValuePair>& pairs) {
26  KeySet factor_keys_set;
27  for (const auto& pair : pairs) {
28  auto f = pair.first;
29  // Insert all factor continuous keys in the continuous keys set.
30  std::copy(f->keys().begin(), f->keys().end(),
31  std::inserter(factor_keys_set, factor_keys_set.end()));
32  }
33 
34  KeySet continuous_keys_set(continuousKeys.begin(), continuousKeys.end());
35  if (continuous_keys_set != factor_keys_set) {
36  throw std::runtime_error(
37  "HybridNonlinearFactor: The specified continuous keys and the keys in "
38  "the factors do not match!");
39  }
40 }
41 
42 /* *******************************************************************************/
44  const KeyVector& continuousKeys, const DiscreteKey& discreteKey,
45  const std::vector<NonlinearFactor::shared_ptr>& factors)
46  : Base(continuousKeys, {discreteKey}) {
47  std::vector<NonlinearFactorValuePair> pairs;
48  for (auto&& f : factors) {
49  pairs.emplace_back(f, 0.0);
50  }
51  checkKeys(continuousKeys, pairs);
52  factors_ = FactorValuePairs({discreteKey}, pairs);
53 }
54 
55 /* *******************************************************************************/
57  const KeyVector& continuousKeys, const DiscreteKey& discreteKey,
58  const std::vector<NonlinearFactorValuePair>& pairs)
59  : Base(continuousKeys, {discreteKey}) {
60  KeySet continuous_keys_set(continuousKeys.begin(), continuousKeys.end());
61  checkKeys(continuousKeys, pairs);
62  factors_ = FactorValuePairs({discreteKey}, pairs);
63 }
64 
65 /* *******************************************************************************/
67  const DiscreteKeys& discreteKeys,
69  : Base(continuousKeys, discreteKeys), factors_(factors) {}
70 
71 /* *******************************************************************************/
73  const Values& continuousValues) const {
74  // functor to convert from sharedFactor to double error value.
75  auto errorFunc =
76  [continuousValues](const std::pair<sharedFactor, double>& f) {
77  auto [factor, val] = f;
78  return factor->error(continuousValues) + val;
79  };
81  return result;
82 }
83 
84 /* *******************************************************************************/
86  const Values& continuousValues,
87  const DiscreteValues& discreteValues) const {
88  // Retrieve the factor corresponding to the assignment in discreteValues.
89  auto [factor, val] = factors_(discreteValues);
90  // Compute the error for the selected factor
91  const double factorError = factor->error(continuousValues);
92  return factorError + val;
93 }
94 
95 /* *******************************************************************************/
97  return error(values.nonlinear(), values.discrete());
98 }
99 
100 /* *******************************************************************************/
102  const auto assignments = DiscreteValues::CartesianProduct(discreteKeys_);
103  auto [factor, val] = factors_(assignments.at(0));
104  return factor->dim();
105 }
106 
107 /* *******************************************************************************/
108 void HybridNonlinearFactor::print(const std::string& s,
109  const KeyFormatter& keyFormatter) const {
110  std::cout << (s.empty() ? "" : s + " ");
111  Base::print("", keyFormatter);
112  std::cout << "\nHybridNonlinearFactor\n";
113  auto valueFormatter = [](const std::pair<sharedFactor, double>& v) {
114  auto [factor, val] = v;
115  if (factor) {
116  return "Nonlinear factor on " + std::to_string(factor->size()) + " keys";
117  } else {
118  return std::string("nullptr");
119  }
120  };
121  factors_.print("", keyFormatter, valueFormatter);
122 }
123 
124 /* *******************************************************************************/
126  double tol) const {
127  // We attempt a dynamic cast from HybridFactor to HybridNonlinearFactor. If
128  // it fails, return false.
129  if (!dynamic_cast<const HybridNonlinearFactor*>(&other)) return false;
130 
131  // If the cast is successful, we'll properly construct a
132  // HybridNonlinearFactor object from `other`
133  const HybridNonlinearFactor& f(
134  static_cast<const HybridNonlinearFactor&>(other));
135 
136  // Ensure that this HybridNonlinearFactor and `f` have the same `factors_`.
137  auto compare = [tol](const std::pair<sharedFactor, double>& a,
138  const std::pair<sharedFactor, double>& b) {
139  return traits<NonlinearFactor>::Equals(*a.first, *b.first, tol) &&
140  (a.second == b.second);
141  };
142  if (!factors_.equals(f.factors_, compare)) return false;
143 
144  // If everything above passes, and the keys_ and discreteKeys_
145  // member variables are identical, return true.
146  return (std::equal(keys_.begin(), keys_.end(), f.keys().begin()) &&
147  (discreteKeys_ == f.discreteKeys_));
148 }
149 
150 /* *******************************************************************************/
152  const Values& continuousValues,
153  const DiscreteValues& discreteValues) const {
154  auto factor = factors_(discreteValues).first;
155  return factor->linearize(continuousValues);
156 }
157 
158 /* *******************************************************************************/
159 std::shared_ptr<HybridGaussianFactor> HybridNonlinearFactor::linearize(
160  const Values& continuousValues) const {
161  // functional to linearize each factor in the decision tree
162  auto linearizeDT =
163  [continuousValues](
164  const std::pair<sharedFactor, double>& f) -> GaussianFactorValuePair {
165  auto [factor, val] = f;
166  return {factor->linearize(continuousValues), val};
167  };
168 
170  linearized_factors(factors_, linearizeDT);
171 
172  return std::make_shared<HybridGaussianFactor>(continuousKeys_, discreteKeys_,
173  linearized_factors);
174 }
175 
176 } // namespace gtsam
gtsam::HybridNonlinearFactor::HybridNonlinearFactor
HybridNonlinearFactor()=default
Default constructor, mainly for serialization.
compare
bool compare
Definition: SolverComparer.cpp:98
gtsam::HybridValues
Definition: HybridValues.h:37
gtsam::HybridNonlinearFactor::print
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
print to stdout
Definition: HybridNonlinearFactor.cpp:108
s
RealScalar s
Definition: level1_cplx_impl.h:126
gtsam::HybridNonlinearFactor::linearize
GaussianFactor::shared_ptr linearize(const Values &continuousValues, const DiscreteValues &discreteValues) const
Definition: HybridNonlinearFactor.cpp:151
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::HybridFactor
Definition: HybridFactor.h:54
gtsam::HybridNonlinearFactor::error
double error(const Values &continuousValues, const DiscreteValues &discreteValues) const
Compute error of factor given both continuous and discrete values.
Definition: HybridNonlinearFactor.cpp:85
gtsam::HybridFactor::continuousKeys_
KeyVector continuousKeys_
Record continuous keys for book-keeping.
Definition: HybridFactor.h:67
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::FastSet
Definition: FastSet.h:51
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
gtsam::AlgebraicDecisionTree< Key >
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::DiscreteValues::CartesianProduct
static std::vector< DiscreteValues > CartesianProduct(const DiscreteKeys &keys)
Return a vector of DiscreteValues, one for each possible combination of values.
Definition: DiscreteValues.h:85
gtsam::HybridNonlinearFactor::equals
bool equals(const HybridFactor &other, double tol=1e-9) const override
Check equality.
Definition: HybridNonlinearFactor.cpp:125
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
gtsam::GaussianFactor::shared_ptr
std::shared_ptr< This > shared_ptr
shared_ptr to this class
Definition: GaussianFactor.h:42
gtsam::HybridFactor::discreteKeys_
DiscreteKeys discreteKeys_
Definition: HybridFactor.h:65
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
gtsam::DecisionTree< Key, NonlinearFactorValuePair >
gtsam::b
const G & b
Definition: Group.h:79
gtsam::HybridFactor::print
void print(const std::string &s="HybridFactor\n", const KeyFormatter &formatter=DefaultKeyFormatter) const override
print
Definition: HybridFactor.cpp:94
HybridNonlinearFactor.h
A set of nonlinear factors indexed by a set of discrete keys.
a
ArrayXXi a
Definition: Array_initializer_list_23_cxx11.cpp:1
gtsam
traits
Definition: chartTesting.h:28
gtsam::Factor::keys_
KeyVector keys_
The keys involved in this factor.
Definition: Factor.h:88
gtsam::traits
Definition: Group.h:36
gtsam::DiscreteValues
Definition: DiscreteValues.h:34
leaf::values
leaf::MyValues values
gtsam::Values
Definition: Values.h:65
gtsam::DiscreteKey
std::pair< Key, size_t > DiscreteKey
Definition: DiscreteKey.h:38
v
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
gtsam::HybridNonlinearFactor::dim
size_t dim() const
Get the dimension of the factor (number of rows on linearization). Returns the dimension of the first...
Definition: HybridNonlinearFactor.cpp:101
gtsam::tol
const G double tol
Definition: Group.h:79
gtsam::HybridNonlinearFactor::factors_
FactorValuePairs factors_
Decision tree of nonlinear factors indexed by discrete keys.
Definition: HybridNonlinearFactor.h:75
gtsam::valueFormatter
static std::string valueFormatter(const double &v)
Definition: DecisionTreeFactor.cpp:264
gtsam::HybridNonlinearFactor::errorTree
AlgebraicDecisionTree< Key > errorTree(const VectorValues &continuousValues) const override
HybridFactor method implementation. Should not be used.
Definition: HybridNonlinearFactor.h:78
gtsam::checkKeys
static void checkKeys(const KeyVector &continuousKeys, const std::vector< NonlinearFactorValuePair > &pairs)
Definition: HybridNonlinearFactor.cpp:24
gtsam::equal
bool equal(const T &obj1, const T &obj2, double tol)
Definition: Testable.h:85
gtsam::HybridNonlinearFactor
Implementation of a discrete-conditioned hybrid factor.
Definition: HybridNonlinearFactor.h:60
pybind_wrapper_test_script.other
other
Definition: pybind_wrapper_test_script.py:42
factorError
Vector factorError(const Point3 &T1, const Point3 &T2, const TranslationFactor &factor)
Definition: testTranslationFactor.cpp:74


gtsam
Author(s):
autogenerated on Wed Sep 25 2024 03:02:32