gtsam  4.0.0
gtsam
SubgraphPreconditioner.h
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 
18 #pragma once
19 
20 #include <gtsam/linear/Errors.h>
24 #include <gtsam/linear/Preconditioner.h>
26 #include <gtsam/base/FastMap.h>
27 #include <gtsam/base/FastVector.h>
28 #include <gtsam/base/types.h>
29 #include <gtsam/base/Vector.h>
30 #include <gtsam/dllexport.h>
31 
32 #include <boost/serialization/nvp.hpp>
33 #include <boost/shared_ptr.hpp>
34 
35 #include <map>
36 #include <utility>
37 #include <vector>
38 
39 namespace boost {
40 namespace serialization {
41 class access;
42 } /* namespace serialization */
43 } /* namespace boost */
44 
45 namespace gtsam {
46 
47  // Forward declarations
48  class GaussianBayesNet;
49  class GaussianFactorGraph;
50  class VectorValues;
51 
52  struct GTSAM_EXPORT SubgraphEdge {
53  size_t index_; /* edge id */
54  double weight_; /* edge weight */
55  SubgraphEdge() : index_(0), weight_(1.0) {}
56  SubgraphEdge(const SubgraphEdge &e) : index_(e.index()), weight_(e.weight()) {}
57  SubgraphEdge(const size_t index, const double weight = 1.0): index_(index), weight_(weight) {}
58  inline size_t index() const { return index_; }
59  inline double weight() const { return weight_; }
60  inline bool isUnitWeight() const { return (weight_ == 1.0); }
61  friend std::ostream &operator<<(std::ostream &os, const SubgraphEdge &edge);
62  private:
63  friend class boost::serialization::access;
64  template<class Archive>
65  void serialize(Archive & ar, const unsigned int /*version*/) {
66  ar & BOOST_SERIALIZATION_NVP(index_);
67  ar & BOOST_SERIALIZATION_NVP(weight_);
68  }
69  };
70 
71  /**************************************************************************/
72  class GTSAM_EXPORT Subgraph {
73  public:
74  typedef boost::shared_ptr<Subgraph> shared_ptr;
75  typedef std::vector<shared_ptr> vector_shared_ptr;
76  typedef std::vector<SubgraphEdge> Edges;
77  typedef std::vector<size_t> EdgeIndices;
78  typedef Edges::iterator iterator;
79  typedef Edges::const_iterator const_iterator;
80 
81  protected:
82  Edges edges_; /* index to the factors */
83 
84  public:
85  Subgraph() {}
86  Subgraph(const Subgraph &subgraph) : edges_(subgraph.edges()) {}
87  Subgraph(const Edges &edges) : edges_(edges) {}
88  Subgraph(const std::vector<size_t> &indices) ;
89 
90  inline const Edges& edges() const { return edges_; }
91  inline size_t size() const { return edges_.size(); }
92  EdgeIndices edgeIndices() const;
93 
94  iterator begin() { return edges_.begin(); }
95  const_iterator begin() const { return edges_.begin(); }
96  iterator end() { return edges_.end(); }
97  const_iterator end() const { return edges_.end(); }
98 
99  void save(const std::string &fn) const;
100  static shared_ptr load(const std::string &fn);
101  friend std::ostream &operator<<(std::ostream &os, const Subgraph &subgraph);
102 
103  private:
104  friend class boost::serialization::access;
105  template<class Archive>
106  void serialize(Archive & ar, const unsigned int /*version*/) {
107  ar & BOOST_SERIALIZATION_NVP(edges_);
108  }
109  };
110 
111  /****************************************************************************/
112  struct GTSAM_EXPORT SubgraphBuilderParameters {
113  public:
114  typedef boost::shared_ptr<SubgraphBuilderParameters> shared_ptr;
115 
116  enum Skeleton {
117  /* augmented tree */
118  NATURALCHAIN = 0, /* natural ordering of the graph */
119  BFS, /* breadth-first search tree */
120  KRUSKAL, /* maximum weighted spanning tree */
121  } skeleton_ ;
122 
123  enum SkeletonWeight { /* how to weigh the graph edges */
124  EQUAL = 0, /* every block edge has equal weight */
125  RHS_2NORM, /* use the 2-norm of the rhs */
126  LHS_FNORM, /* use the frobenius norm of the lhs */
127  RANDOM, /* bounded random edge weight */
128  } skeletonWeight_ ;
129 
130  enum AugmentationWeight { /* how to weigh the graph edges */
131  SKELETON = 0, /* use the same weights in building the skeleton */
132 // STRETCH, /* stretch in the laplacian sense */
133 // GENERALIZED_STRETCH /* the generalized stretch defined in jian2013iros */
134  } augmentationWeight_ ;
135 
136  double complexity_;
137 
139  : skeleton_(KRUSKAL), skeletonWeight_(RANDOM), augmentationWeight_(SKELETON), complexity_(1.0) {}
140  virtual ~SubgraphBuilderParameters() {}
141 
142  /* for serialization */
143  void print() const ;
144  virtual void print(std::ostream &os) const ;
145  friend std::ostream& operator<<(std::ostream &os, const PreconditionerParameters &p);
146 
147  static Skeleton skeletonTranslator(const std::string &s);
148  static std::string skeletonTranslator(Skeleton w);
149  static SkeletonWeight skeletonWeightTranslator(const std::string &s);
150  static std::string skeletonWeightTranslator(SkeletonWeight w);
151  static AugmentationWeight augmentationWeightTranslator(const std::string &s);
152  static std::string augmentationWeightTranslator(AugmentationWeight w);
153  };
154 
155  /*****************************************************************************/
156  class GTSAM_EXPORT SubgraphBuilder {
157 
158  public:
159  typedef SubgraphBuilder Base;
160  typedef boost::shared_ptr<SubgraphBuilder> shared_ptr;
161  typedef std::vector<double> Weights;
162 
164  : parameters_(p) {}
165  virtual ~SubgraphBuilder() {}
166  virtual boost::shared_ptr<Subgraph> operator() (const GaussianFactorGraph &jfg) const ;
167 
168  private:
169  std::vector<size_t> buildTree(const GaussianFactorGraph &gfg, const FastMap<Key, size_t> &ordering, const std::vector<double> &weights) const ;
170  std::vector<size_t> unary(const GaussianFactorGraph &gfg) const ;
171  std::vector<size_t> natural_chain(const GaussianFactorGraph &gfg) const ;
172  std::vector<size_t> bfs(const GaussianFactorGraph &gfg) const ;
173  std::vector<size_t> kruskal(const GaussianFactorGraph &gfg, const FastMap<Key, size_t> &ordering, const std::vector<double> &w) const ;
174  std::vector<size_t> sample(const std::vector<double> &weights, const size_t t) const ;
175  Weights weights(const GaussianFactorGraph &gfg) const;
176  SubgraphBuilderParameters parameters_;
177 
178  };
179 
180  /*******************************************************************************************/
183  typedef boost::shared_ptr<SubgraphPreconditionerParameters> shared_ptr;
185  : Base(), builderParams_(p) {}
187  SubgraphBuilderParameters builderParams_;
188  };
189 
197  class GTSAM_EXPORT SubgraphPreconditioner : public Preconditioner {
198 
199  public:
200  typedef boost::shared_ptr<SubgraphPreconditioner> shared_ptr;
201  typedef boost::shared_ptr<const GaussianBayesNet> sharedBayesNet;
202  typedef boost::shared_ptr<const GaussianFactorGraph> sharedFG;
203  typedef boost::shared_ptr<const VectorValues> sharedValues;
204  typedef boost::shared_ptr<const Errors> sharedErrors;
205 
206  private:
207  sharedFG Ab2_;
208  sharedBayesNet Rc1_;
209  sharedValues xbar_;
210  sharedErrors b2bar_;
211 
212  KeyInfo keyInfo_;
214 
215  public:
216 
218 
225  SubgraphPreconditioner(const sharedFG& Ab2, const sharedBayesNet& Rc1, const sharedValues& xbar,
227 
228  virtual ~SubgraphPreconditioner() {}
229 
231  void print(const std::string& s = "SubgraphPreconditioner") const;
232 
234  const sharedFG& Ab2() const { return Ab2_; }
235 
237  const sharedBayesNet& Rc1() const { return Rc1_; }
238 
240  const sharedErrors b2bar() const { return b2bar_; }
241 
247  /* x = xbar + inv(R1)*y */
248  VectorValues x(const VectorValues& y) const;
249 
250  /* A zero VectorValues with the structure of xbar */
251  VectorValues zero() const {
252  VectorValues V(VectorValues::Zero(*xbar_));
253  return V ;
254  }
255 
261  void transposeMultiplyAdd2(double alpha, Errors::const_iterator begin,
262  Errors::const_iterator end, VectorValues& y) const;
263 
264  /* error, given y */
265  double error(const VectorValues& y) const;
266 
268  VectorValues gradient(const VectorValues& y) const;
269 
271  Errors operator*(const VectorValues& y) const;
272 
274  void multiplyInPlace(const VectorValues& y, Errors& e) const;
275 
277  VectorValues operator^(const Errors& e) const;
278 
283  void transposeMultiplyAdd(double alpha, const Errors& e, VectorValues& y) const;
284 
285  /*****************************************************************************/
286  /* implement virtual functions of Preconditioner */
287 
288  /* Computation Interfaces for Vector */
289  virtual void solve(const Vector& y, Vector &x) const;
290  virtual void transposeSolve(const Vector& y, Vector& x) const ;
291 
292  virtual void build(
293  const GaussianFactorGraph &gfg,
294  const KeyInfo &info,
295  const std::map<Key,Vector> &lambda
296  ) ;
297  /*****************************************************************************/
298  };
299 
300  /* get subvectors */
301  Vector getSubvector(const Vector &src, const KeyInfo &keyInfo, const FastVector<Key> &keys);
302 
303  /* set subvectors */
304  void setSubvector(const Vector &src, const KeyInfo &keyInfo, const FastVector<Key> &keys, Vector &dst);
305 
306 
307  /* build a factor subgraph, which is defined as a set of weighted edges (factors) */
308  boost::shared_ptr<GaussianFactorGraph>
309  buildFactorSubgraph(const GaussianFactorGraph &gfg, const Subgraph &subgraph, const bool clone);
310 
311 
312  /* sort the container and return permutation index with default comparator */
313  template <typename Container>
314  std::vector<size_t> sort_idx(const Container &src)
315  {
316  typedef typename Container::value_type T;
317  const size_t n = src.size() ;
318  std::vector<std::pair<size_t,T> > tmp;
319  tmp.reserve(n);
320  for ( size_t i = 0 ; i < n ; i++ )
321  tmp.push_back(std::make_pair(i, src[i]));
322 
323  /* sort */
324  std::stable_sort(tmp.begin(), tmp.end()) ;
325 
326  /* copy back */
327  std::vector<size_t> idx; idx.reserve(n);
328  for ( size_t i = 0 ; i < n ; i++ ) {
329  idx.push_back(tmp[i].first) ;
330  }
331  return idx;
332  }
333 
334 } // namespace gtsam
const sharedFG & Ab2() const
Access Ab2.
Definition: SubgraphPreconditioner.h:234
Definition: Preconditioner.h:24
Definition: SubgraphPreconditioner.h:181
Chordal Bayes Net, the result of eliminating a factor graph.
void save(const Matrix &A, const string &s, const string &filename)
save a matrix to file, which can be loaded by matlab
Definition: Matrix.cpp:161
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition: Matrix.cpp:140
Typedefs for easier changing of types.
Subgraph conditioner class, as explained in the RSS 2010 submission.
Definition: SubgraphPreconditioner.h:197
typedef and functions to augment Eigen&#39;s VectorXd
Handy data structure for iterative solvers.
Definition: IterativeSolver.h:139
Definition: Preconditioner.h:64
This class represents a collection of vector-valued variables associated each with a unique integer i...
Definition: VectorValues.h:90
Factor Graph Values.
Definition: SubgraphPreconditioner.h:52
const sharedErrors b2bar() const
Access b2bar.
Definition: SubgraphPreconditioner.h:240
Definition: SubgraphPreconditioner.h:156
vector of errors
Some support classes for iterative solvers.
Point2 operator*(double s, const Point2 &p)
multiply with scalar
Definition: Point2.h:170
Vector operator^(const Matrix &A, const Vector &v)
overload ^ for trans(A)*v We transpose the vectors for speed.
Definition: Matrix.cpp:129
Definition: SubgraphPreconditioner.h:112
A thin wrapper around std::vector that uses boost&#39;s pool_allocator.
Linear Factor Graph where all factors are Gaussians.
Definition: SubgraphPreconditioner.h:72
A Linear Factor Graph is a factor graph where all factors are Gaussian, i.e.
Definition: GaussianFactorGraph.h:65
vector of errors
Definition: Errors.h:34
A thin wrapper around std::map that uses boost&#39;s fast_pool_allocator.
const sharedBayesNet & Rc1() const
Access Rc1.
Definition: SubgraphPreconditioner.h:237
Definition: FastSet.h:29
Global functions in a separate testing namespace.
Definition: chartTesting.h:28