HybridNonlinearFactorGraph.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 
26 namespace gtsam {
27 
28 /* ************************************************************************* */
29 void HybridNonlinearFactorGraph::print(const std::string& s,
30  const KeyFormatter& keyFormatter) const {
31  // Base::print(str, keyFormatter);
32  std::cout << (s.empty() ? "" : s + " ") << std::endl;
33  std::cout << "size: " << size() << std::endl;
34  for (size_t i = 0; i < factors_.size(); i++) {
35  std::stringstream ss;
36  ss << "factor " << i << ": ";
37  if (factors_[i]) {
38  factors_[i]->print(ss.str(), keyFormatter);
39  std::cout << std::endl;
40  }
41  }
42 }
43 
44 /* ************************************************************************* */
46  const HybridValues& values, const std::string& str,
47  const KeyFormatter& keyFormatter,
48  const std::function<bool(const Factor* /*factor*/, double /*whitenedError*/,
49  size_t /*index*/)>& printCondition) const {
50  std::cout << str << "size: " << size() << std::endl << std::endl;
51 
52  std::stringstream ss;
53 
54  for (size_t i = 0; i < factors_.size(); i++) {
55  auto&& factor = factors_[i];
56  std::cout << "Factor " << i << ": ";
57 
58  // Clear the stringstream
59  ss.str(std::string());
60 
61  if (auto mf = std::dynamic_pointer_cast<HybridNonlinearFactor>(factor)) {
62  if (factor == nullptr) {
63  std::cout << "nullptr"
64  << "\n";
65  } else {
66  factor->print(ss.str(), keyFormatter);
67  std::cout << "error = ";
68  mf->errorTree(values.nonlinear()).print("", keyFormatter);
69  std::cout << std::endl;
70  }
71  } else if (auto gmf =
72  std::dynamic_pointer_cast<HybridGaussianFactor>(factor)) {
73  if (factor == nullptr) {
74  std::cout << "nullptr"
75  << "\n";
76  } else {
77  factor->print(ss.str(), keyFormatter);
78  std::cout << "error = ";
79  gmf->errorTree(values.continuous()).print("", keyFormatter);
80  std::cout << std::endl;
81  }
82  } else if (auto gm = std::dynamic_pointer_cast<HybridGaussianConditional>(
83  factor)) {
84  if (factor == nullptr) {
85  std::cout << "nullptr"
86  << "\n";
87  } else {
88  factor->print(ss.str(), keyFormatter);
89  std::cout << "error = ";
90  gm->errorTree(values.continuous()).print("", keyFormatter);
91  std::cout << std::endl;
92  }
93  } else if (auto nf = std::dynamic_pointer_cast<NonlinearFactor>(factor)) {
94  const double errorValue = (factor != nullptr ? nf->error(values) : .0);
95  if (!printCondition(factor.get(), errorValue, i))
96  continue; // User-provided filter did not pass
97 
98  if (factor == nullptr) {
99  std::cout << "nullptr"
100  << "\n";
101  } else {
102  factor->print(ss.str(), keyFormatter);
103  std::cout << "error = " << errorValue << "\n";
104  }
105  } else if (auto gf = std::dynamic_pointer_cast<GaussianFactor>(factor)) {
106  const double errorValue = (factor != nullptr ? gf->error(values) : .0);
107  if (!printCondition(factor.get(), errorValue, i))
108  continue; // User-provided filter did not pass
109 
110  if (factor == nullptr) {
111  std::cout << "nullptr"
112  << "\n";
113  } else {
114  factor->print(ss.str(), keyFormatter);
115  std::cout << "error = " << errorValue << "\n";
116  }
117  } else if (auto df = std::dynamic_pointer_cast<DiscreteFactor>(factor)) {
118  if (factor == nullptr) {
119  std::cout << "nullptr"
120  << "\n";
121  } else {
122  factor->print(ss.str(), keyFormatter);
123  std::cout << "error = ";
124  df->errorTree().print("", keyFormatter);
125  std::cout << std::endl;
126  }
127 
128  } else {
129  continue;
130  }
131 
132  std::cout << "\n";
133  }
134  std::cout.flush();
135 }
136 
137 /* ************************************************************************* */
139  const Values& continuousValues) const {
140  using std::dynamic_pointer_cast;
141 
142  // create an empty linear FG
143  auto linearFG = std::make_shared<HybridGaussianFactorGraph>();
144 
145  linearFG->reserve(size());
146 
147  // linearize all hybrid factors
148  for (auto& f : factors_) {
149  // First check if it is a valid factor
150  if (!f) {
151  continue;
152  }
153  // Check if it is a hybrid nonlinear factor
154  if (auto mf = dynamic_pointer_cast<HybridNonlinearFactor>(f)) {
156  mf->linearize(continuousValues);
157  linearFG->push_back(gmf);
158  } else if (auto nlf = dynamic_pointer_cast<NonlinearFactor>(f)) {
159  const GaussianFactor::shared_ptr& gf = nlf->linearize(continuousValues);
160  linearFG->push_back(gf);
161  } else if (dynamic_pointer_cast<DiscreteFactor>(f)) {
162  // If discrete-only: doesn't need linearization.
163  linearFG->push_back(f);
164  } else if (auto gmf = dynamic_pointer_cast<HybridGaussianFactor>(f)) {
165  linearFG->push_back(gmf);
166  } else if (auto gm = dynamic_pointer_cast<HybridGaussianConditional>(f)) {
167  linearFG->push_back(gm);
168  } else if (dynamic_pointer_cast<GaussianFactor>(f)) {
169  linearFG->push_back(f);
170  } else {
171  auto& fr = *f;
172  throw std::invalid_argument(
173  std::string("HybridNonlinearFactorGraph::linearize: factor type "
174  "not handled: ") +
175  demangle(typeid(fr).name()));
176  }
177  }
178  return linearFG;
179 }
180 
181 /* ************************************************************************* */
183  const Values& values) const {
185 
186  // Iterate over each factor.
187  for (auto& factor : factors_) {
188  if (auto hnf = std::dynamic_pointer_cast<HybridNonlinearFactor>(factor)) {
189  // Compute factor error and add it.
190  result = result + hnf->errorTree(values);
191 
192  } else if (auto nf = std::dynamic_pointer_cast<NonlinearFactor>(factor)) {
193  // If continuous only, get the (double) error
194  // and add it to every leaf of the result
195  result = result + nf->error(values);
196 
197  } else if (auto df = std::dynamic_pointer_cast<DiscreteFactor>(factor)) {
198  // If discrete, just add its errorTree as well
199  result = result + df->errorTree();
200 
201  } else {
202  throw std::runtime_error(
203  "HybridNonlinearFactorGraph::errorTree(Values) not implemented for "
204  "factor type " +
205  demangle(typeid(factor).name()) + ".");
206  }
207  }
208 
209  return result;
210 }
211 
212 /* ************************************************************************ */
214  const Values& continuousValues) const {
215  AlgebraicDecisionTree<Key> errors = this->errorTree(continuousValues);
216  AlgebraicDecisionTree<Key> p = errors.apply([](double error) {
217  // NOTE: The 0.5 term is handled by each factor
218  return exp(-error);
219  });
220  return p / p.sum();
221 }
222 
223 /* ************************************************************************ */
225  const DiscreteValues& discreteValues) const {
226  using std::dynamic_pointer_cast;
227 
229  result.reserve(size());
230  for (auto& f : factors_) {
231  // First check if it is a valid factor
232  if (!f) {
233  continue;
234  }
235  // Check if it is a hybrid factor
236  if (auto hf = dynamic_pointer_cast<HybridFactor>(f)) {
237  result.push_back(hf->restrict(discreteValues));
238  } else if (auto df = dynamic_pointer_cast<DiscreteFactor>(f)) {
239  auto restricted_df = df->restrict(discreteValues);
240  // In the case where all the discrete values in the factor
241  // have been selected, we get a factor without any keys,
242  // and default values of 0.5.
243  // Since this factor no longer adds any information, we ignore it to make
244  // inference faster.
245  if (restricted_df->discreteKeys().size() > 0) {
246  result.push_back(restricted_df);
247  }
248  } else {
249  result.push_back(f); // Everything else is just added as is
250  }
251  }
252 
253  return result;
254 }
255 
256 /* ************************************************************************ */
257 } // namespace gtsam
gtsam::HybridGaussianFactorGraph::shared_ptr
std::shared_ptr< This > shared_ptr
shared_ptr to This
Definition: HybridGaussianFactorGraph.h:120
gtsam::HybridValues
Definition: HybridValues.h:37
gtsam::FactorGraph< Factor >::factors_
FastVector< sharedFactor > factors_
Definition: FactorGraph.h:92
gtsam::HybridNonlinearFactorGraph::print
void print(const std::string &s="HybridNonlinearFactorGraph", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
Print the factor graph.
Definition: HybridNonlinearFactorGraph.cpp:29
HybridGaussianConditional.h
A hybrid conditional in the Conditional Linear Gaussian scheme.
s
RealScalar s
Definition: level1_cplx_impl.h:126
gtsam::FactorGraph< Factor >::error
double error(const HybridValues &values) const
Definition: FactorGraph-inst.h:66
gtsam::HybridGaussianFactor::shared_ptr
std::shared_ptr< This > shared_ptr
Definition: HybridGaussianFactor.h:64
HybridNonlinearFactorGraph.h
Nonlinear hybrid factor graph that uses type erasure.
gtsam::HybridNonlinearFactorGraph
Definition: HybridNonlinearFactorGraph.h:33
gtsam::HybridNonlinearFactorGraph::printErrors
void printErrors(const HybridValues &values, const std::string &str="HybridNonlinearFactorGraph: ", const KeyFormatter &keyFormatter=DefaultKeyFormatter, const std::function< bool(const Factor *, double, size_t)> &printCondition=[](const Factor *, double, size_t) { return true;}) const
Definition: HybridNonlinearFactorGraph.cpp:45
gtsam::HybridNonlinearFactorGraph::discretePosterior
AlgebraicDecisionTree< Key > discretePosterior(const Values &continuousValues) const
Computer posterior P(M|X=x) when all continuous values X are given. This is efficient as this simply ...
Definition: HybridNonlinearFactorGraph.cpp:213
different_sigmas::values
HybridValues values
Definition: testHybridBayesNet.cpp:247
gtsam::Factor
Definition: Factor.h:70
exp
const EIGEN_DEVICE_FUNC ExpReturnType exp() const
Definition: ArrayCwiseUnaryOps.h:97
result
Values result
Definition: OdometryOptimize.cpp:8
gtsam::HybridNonlinearFactorGraph::errorTree
AlgebraicDecisionTree< Key > errorTree(const Values &values) const
Compute error of (hybrid) nonlinear factors and discrete factors over each discrete assignment,...
Definition: HybridNonlinearFactorGraph.cpp:182
name
static char name[]
Definition: rgamma.c:72
gtsam::AlgebraicDecisionTree< Key >
pruning_fixture::factor
DecisionTreeFactor factor(D &C &B &A, "0.0 0.0 0.0 0.60658897 0.61241912 0.61241969 0.61247685 0.61247742 0.0 " "0.0 0.0 0.99995287 1.0 1.0 1.0 1.0")
ss
static std::stringstream ss
Definition: testBTree.cpp:31
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
mf
Matrix2f mf
Definition: MatrixBase_cast.cpp:2
gtsam::DecisionTree::apply
DecisionTree apply(const Unary &op) const
Definition: DecisionTree-inl.h:1003
TableFactor.h
str
Definition: pytypes.h:1560
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
NonlinearFactor.h
Non-linear factor base classes.
gtsam::FactorGraph< Factor >::size
size_t size() const
Definition: FactorGraph.h:297
HybridNonlinearFactor.h
A set of nonlinear factors indexed by a set of discrete keys.
gtsam::HybridNonlinearFactorGraph::restrict
HybridNonlinearFactorGraph restrict(const DiscreteValues &assignment) const
Restrict all factors in the graph to the given discrete values.
Definition: HybridNonlinearFactorGraph.cpp:224
HybridGaussianFactorGraph.h
Linearized Hybrid factor graph that uses type erasure.
gtsam
traits
Definition: ABC.h:17
gtsam::DiscreteValues
Definition: DiscreteValues.h:34
gtsam::Values
Definition: Values.h:65
gtsam::demangle
std::string demangle(const char *name)
Pretty print Value type name.
Definition: types.cpp:37
p
float * p
Definition: Tutorial_Map_using.cpp:9
gtsam::HybridNonlinearFactorGraph::linearize
std::shared_ptr< HybridGaussianFactorGraph > linearize(const Values &continuousValues) const
Linearize all the continuous factors in the HybridNonlinearFactorGraph.
Definition: HybridNonlinearFactorGraph.cpp:138
DecisionTreeFactor.h
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9


gtsam
Author(s):
autogenerated on Mon Apr 28 2025 03:01:38