212 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
/* ----------------------------------------------------------------------------
 | 
						|
 | 
						|
 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
 | 
						|
 * Atlanta, Georgia 30332-0415
 | 
						|
 * All Rights Reserved
 | 
						|
 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
 | 
						|
 | 
						|
 * See LICENSE for the license information
 | 
						|
 | 
						|
 * -------------------------------------------------------------------------- */
 | 
						|
 | 
						|
/**
 | 
						|
 * @file    Factor.h
 | 
						|
 * @brief   The base class for all factors
 | 
						|
 * @author  Kai Ni
 | 
						|
 * @author  Frank Dellaert
 | 
						|
 * @author  Richard Roberts
 | 
						|
 */
 | 
						|
 | 
						|
// \callgraph
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
#if GTSAM_ENABLE_BOOST_SERIALIZATION
 | 
						|
#include <boost/serialization/nvp.hpp>
 | 
						|
#endif
 | 
						|
#include <gtsam/base/FastVector.h>
 | 
						|
#include <gtsam/base/types.h>
 | 
						|
#include <gtsam/inference/Key.h>
 | 
						|
 | 
						|
#include <algorithm>
 | 
						|
#include <memory>
 | 
						|
 | 
						|
namespace gtsam {
 | 
						|
 | 
						|
  /// Define collection types:
 | 
						|
  typedef FastVector<FactorIndex> FactorIndices;
 | 
						|
  typedef FastSet<FactorIndex> FactorIndexSet;
 | 
						|
 | 
						|
  class HybridValues; // forward declaration of a Value type for error.
 | 
						|
 | 
						|
  /**
 | 
						|
   * This is the base class for all factor types, as well as conditionals, 
 | 
						|
   * which are implemented as specialized factors.  This class does not store any
 | 
						|
   * data other than its keys.  Derived classes store data such as matrices and
 | 
						|
   * probability tables.
 | 
						|
   *
 | 
						|
   * The `error` method is used to evaluate the factor, and is the only method
 | 
						|
   * that is required to be implemented in derived classes, although it has a 
 | 
						|
   * default implementation that throws an exception.
 | 
						|
   * 
 | 
						|
   * There are five broad classes of factors that derive from Factor:
 | 
						|
   *
 | 
						|
   * - \b Nonlinear factors, such as \class NonlinearFactor and \class NoiseModelFactor, which
 | 
						|
   *   represent a nonlinear likelihood function over a set of variables.
 | 
						|
   * - \b Gaussian factors, such as \class JacobianFactor and \class HessianFactor, which
 | 
						|
   *   represent a Gaussian likelihood over a set of variables.
 | 
						|
   * - \b Discrete factors, such as \class DiscreteFactor and \class DecisionTreeFactor, which
 | 
						|
   *   represent a discrete distribution over a set of variables.
 | 
						|
   * - \b Hybrid factors, such as \class HybridFactor, which represent a mixture of
 | 
						|
   *   Gaussian and discrete distributions over a set of variables.
 | 
						|
   * - \b Symbolic factors, used to represent a graph structure, such as
 | 
						|
   *   \class SymbolicFactor, only used for symbolic elimination etc.
 | 
						|
   *
 | 
						|
   * Note that derived classes must also redefine the `This` and `shared_ptr`
 | 
						|
   * typedefs. See JacobianFactor, etc. for examples.
 | 
						|
   * 
 | 
						|
   * \nosubgrouping
 | 
						|
   */
 | 
						|
  class GTSAM_EXPORT Factor
 | 
						|
  {
 | 
						|
 | 
						|
  private:
 | 
						|
    // These typedefs are private because they must be overridden in derived classes.
 | 
						|
    typedef Factor This; ///< This class
 | 
						|
    typedef std::shared_ptr<Factor> shared_ptr; ///< A shared_ptr to this class.
 | 
						|
 | 
						|
  public:
 | 
						|
    /// Iterator over keys
 | 
						|
    typedef KeyVector::iterator iterator;
 | 
						|
 | 
						|
    /// Const iterator over keys
 | 
						|
    typedef KeyVector::const_iterator const_iterator;
 | 
						|
 | 
						|
  protected:
 | 
						|
 | 
						|
    /// The keys involved in this factor
 | 
						|
    KeyVector keys_;
 | 
						|
 | 
						|
    /// @name Standard Constructors
 | 
						|
    /// @{
 | 
						|
 | 
						|
    /** Default constructor for I/O */
 | 
						|
    Factor() {}
 | 
						|
 | 
						|
    /** Construct factor from container of keys.  This constructor is used internally from derived factor
 | 
						|
    *  constructors, either from a container of keys or from a boost::assign::list_of. */
 | 
						|
    template<typename CONTAINER>
 | 
						|
    explicit Factor(const CONTAINER& keys) : keys_(keys.begin(), keys.end()) {}
 | 
						|
 | 
						|
    /** Construct factor from iterator keys.  This constructor may be used internally from derived
 | 
						|
    *  factor constructors, although our code currently does not use this. */
 | 
						|
    template<typename ITERATOR>
 | 
						|
    Factor(ITERATOR first, ITERATOR last) : keys_(first, last) {}
 | 
						|
 | 
						|
    /** Construct factor from container of keys.  This is called internally from derived factor static
 | 
						|
    *  factor methods, as a workaround for not being able to call the protected constructors above. */
 | 
						|
    template<typename CONTAINER>
 | 
						|
    static Factor FromKeys(const CONTAINER& keys) {
 | 
						|
      return Factor(keys.begin(), keys.end()); }
 | 
						|
 | 
						|
    /** Construct factor from iterator keys.  This is called internally from derived factor static
 | 
						|
    *  factor methods, as a workaround for not being able to call the protected constructors above. */
 | 
						|
    template<typename ITERATOR>
 | 
						|
    static Factor FromIterators(ITERATOR first, ITERATOR last) {
 | 
						|
      return Factor(first, last); }
 | 
						|
 | 
						|
    /// @}
 | 
						|
 | 
						|
  public:
 | 
						|
   /// Default destructor
 | 
						|
   // public since it is required for boost serialization and static methods.
 | 
						|
   // virtual since it is public.
 | 
						|
   // http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-dtor-virtual
 | 
						|
   virtual ~Factor() = default;
 | 
						|
 | 
						|
   /// @name Standard Interface
 | 
						|
   /// @{
 | 
						|
 | 
						|
   /// Whether the factor is empty (involves zero variables).
 | 
						|
   bool empty() const { return keys_.empty(); }
 | 
						|
 | 
						|
   /// First key
 | 
						|
   Key front() const { return keys_.front(); }
 | 
						|
 | 
						|
   /// Last key
 | 
						|
   Key back() const { return keys_.back(); }
 | 
						|
 | 
						|
   /// find
 | 
						|
   const_iterator find(Key key) const { return std::find(begin(), end(), key); }
 | 
						|
 | 
						|
   /// Access the factor's involved variable keys
 | 
						|
   const KeyVector& keys() const { return keys_; }
 | 
						|
 | 
						|
   /** Iterator at beginning of involved variable keys */
 | 
						|
   const_iterator begin() const { return keys_.begin(); }
 | 
						|
 | 
						|
   /** Iterator at end of involved variable keys */
 | 
						|
   const_iterator end() const { return keys_.end(); }
 | 
						|
 | 
						|
  /**
 | 
						|
   * All factor types need to implement an error function.
 | 
						|
   * In factor graphs, this is the negative log-likelihood.
 | 
						|
   */
 | 
						|
  virtual double error(const HybridValues& c) const;
 | 
						|
 | 
						|
   /**
 | 
						|
    * @return the number of variables involved in this factor
 | 
						|
    */
 | 
						|
   size_t size() const { return keys_.size(); }
 | 
						|
 | 
						|
   /// @}
 | 
						|
 | 
						|
   /// @name Testable
 | 
						|
   /// @{
 | 
						|
 | 
						|
   /// print
 | 
						|
   virtual void print(
 | 
						|
       const std::string& s = "Factor",
 | 
						|
       const KeyFormatter& formatter = DefaultKeyFormatter) const;
 | 
						|
 | 
						|
   /// print only keys
 | 
						|
   virtual void printKeys(
 | 
						|
       const std::string& s = "Factor",
 | 
						|
       const KeyFormatter& formatter = DefaultKeyFormatter) const;
 | 
						|
 | 
						|
    /// check equality
 | 
						|
    bool equals(const This& other, double tol = 1e-9) const;
 | 
						|
 | 
						|
    /// @}
 | 
						|
    /// @name Advanced Interface
 | 
						|
    /// @{
 | 
						|
 | 
						|
    /** @return keys involved in this factor */
 | 
						|
    KeyVector& keys() { return keys_; }
 | 
						|
 | 
						|
    /** Iterator at beginning of involved variable keys */
 | 
						|
    iterator begin() { return keys_.begin(); }
 | 
						|
 | 
						|
    /** Iterator at end of involved variable keys */
 | 
						|
    iterator end() { return keys_.end(); }
 | 
						|
 | 
						|
    /// @}
 | 
						|
 | 
						|
  private:
 | 
						|
#if GTSAM_ENABLE_BOOST_SERIALIZATION
 | 
						|
    /// @name Serialization
 | 
						|
    /// @{
 | 
						|
    /** Serialization function */
 | 
						|
    friend class boost::serialization::access;
 | 
						|
    template<class Archive>
 | 
						|
    void serialize(Archive & ar, const unsigned int /*version*/) {
 | 
						|
      ar & BOOST_SERIALIZATION_NVP(keys_);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    /// @}
 | 
						|
 | 
						|
  };
 | 
						|
 | 
						|
} // \namespace gtsam
 |