gtsam/GTSAM-Concepts.md

4.8 KiB

GTSAM Concepts

As discussed in Generic Programming Techniques, concepts define

  • associated types
  • valid expressions, like functions and values
  • invariants
  • complexity guarantees

Below we discuss the most important concepts use in GTSAM, and after that we discuss how they are implemented/used/enforced.

Manifold

To optimize over continuous types, we assume they are manifolds. This is central to GTSAM and hence discussed in some more detail below.

Manifolds and charts are intimately linked concepts. We are only interested here in differentiable manifolds, continuous spaces that can be locally approximated at any point using a local vector space, called the tangent space. A chart is an invertible map from the manifold to the vector space.

In GTSAM we assume that a manifold type can yield such a chart at any point, and we require that a functor defaultChart is available that, when called for any point on the manifold, returns a Chart type.

  • values: dimension
  • types: Vector, type that lives in tangent space *
    • DefaultChart is the type of the chart returned by the functor defaultChart
  • functor defaultChart, returns a DefaultChart
  • invariants: defaultChart::result_type == DefaultChart::type

Anything else?

Chart

  • types: Manifold, a pointer back to the type
  • values: retract, local

Are these values? They are just methods. Anything else?

Group

  • values: identity
  • values: compose, inverse, (between)

Lie Group

Implements both MANIFOLD and GROUP

Vector Space

Lie Group where compose == +

Testable

Unit tests heavily depend on the following two functions being defined for all types that need to be tested:

  • functions: print, equals

Implementation

GTSAM Types start with Uppercase, e.g., gtsam::Point2, and are models of the TESTABLE, MANIFOLD, GROUP, LIE_GROUP, and VECTOR_SPACE concepts. gtsam::traits is our way to associate these concepts with types, and we also define a limited number of gtsam::tags to select the correct implementation of certain functions at compile time (tag dispatching).

traits

We will not use Eigen-style or STL-style traits, that define many properties at once. Rather, we use boost::mpl style meta-programming functions to facilitate meta-programming.

Traits allow us to play with types that are outside GTSAM control, e.g., Eigen::VectorXd.

The naming conventions are as follows:

  • Types: gtsam::traits::SomeAssociatedType<T>::type, i.e., they are MixedCase and define a type, for example:

    template<>
    gtsam::traits::TangentVector<Point2> {
      typedef Vector2 type;
    }
    
  • Values: gtsam::traits::someValue<T>::value, i.e., they are mixedCase starting with a lowercase letter and define a value, but also a value_type. For example:

    template<>
    gtsam::traits::dimension<Point2> {
      static const int value = 2;
      typedef const int value_type; // const ?
    }
    
  • Functors: gtsam::traits::someFunctor<T>::type, i.e., they are mixedCase starting with a lowercase letter and define a functor type. The funcor itself should define a result_type. Example

    struct Point2::retract {
      typedef Point2 result_type;
      Point2 p_;
      retract(const Point2& p) : p_(p) {}
      Point2 operator()(const Vector2& v) {
        return Point2(p.x()+v[0], p.y()+v[1]);
      }
    }
    
    template<>
    gtsam::traits::retract<Point2> {
      typedef Point2::retract type;
    }
    

    The above is still up in the air. Do we need the type indirection? Could we just inherit the trait like so

    template<>
    gtsam::traits::retract<Point2> : Point2::retract {
    }
    

    In which case we could just say gtsam::traits::retract<Point2>(p)(v).

tags

Concepts are associated with a tag.

  • gtsam::tags::manifold_tag
  • gtsam::tags::group_tag
  • gtsam::tags::lie_group_tag
  • gtsam::tags::vector_space_tag

Can be queried gtsam::traits::structure_tag<T>

Examples

An example of implementing a Manifold is here:

// GTSAM type
class Rot2 {
  ...
  class Chart {
    ...
  }
}

namespace gtsam {
  namespace traits {
  
  template<>
  struct DefaultChart<Rot2> {
    typedef Rot2::Chart type;      
  }

  template<>
  struct Manifold<Rot2::Chart> {
    typedef Rot2 type;      
  }

  template<>
  struct Vector<Rot2::Chart> {
    typedef Vector2 type;      
  }
}