Fixed a bug (introduced in commit 64db6bc3...) and another one in Factors2mx
[libdai.git] / include / dai / factor.h
index 9925835..05f3e82 100644 (file)
@@ -55,12 +55,13 @@ namespace dai {
  *  \todo Define a better fileformat for .fg files (maybe using XML)?
  *  \todo Add support for sparse factors.
  */
-template <typename T> class TFactor {
+template <typename T>
+class TFactor {
     private:
         /// Stores the variables on which the factor depends
-        VarSet      _vs;
+        VarSet _vs;
         /// Stores the factor values
-        TProb<T>    _p;
+        TProb<T> _p;
 
     public:
     /// \name Constructors and destructors
@@ -72,10 +73,14 @@ template <typename T> class TFactor {
         TFactor( const Var &v ) : _vs(v), _p(v.states()) {}
 
         /// Constructs factor depending on variables in \a vars with uniform distribution
-        TFactor( const VarSet& vars ) : _vs(vars), _p(_vs.nrStates()) {}
+        TFactor( const VarSet& vars ) : _vs(vars), _p((size_t)_vs.nrStates()) {
+            DAI_ASSERT( _vs.nrStates() <= std::numeric_limits<std::size_t>::max() );
+        }
 
         /// Constructs factor depending on variables in \a vars with all values set to \a p
-        TFactor( const VarSet& vars, T p ) : _vs(vars), _p(_vs.nrStates(),p) {}
+        TFactor( const VarSet& vars, T p ) : _vs(vars), _p((size_t)_vs.nrStates(),p) {
+            DAI_ASSERT( _vs.nrStates() <= std::numeric_limits<std::size_t>::max() );
+        }
 
         /// Constructs factor depending on variables in \a vars, copying the values from a std::vector<>
         /** \tparam S Type of values of \a x
@@ -83,15 +88,18 @@ template <typename T> class TFactor {
          *  \param x Vector with values to be copied.
          */
         template<typename S>
-        TFactor( const VarSet& vars, const std::vector<S> &x ) : _vs(vars), _p(x.begin(), x.begin() + _vs.nrStates(), _vs.nrStates()) {
+        TFactor( const VarSet& vars, const std::vector<S> &x ) : _vs(vars), _p() {
             DAI_ASSERT( x.size() == vars.nrStates() );
+            _p = TProb<T>( x.begin(), x.end(), x.size() );
         }
 
         /// Constructs factor depending on variables in \a vars, copying the values from an array
         /** \param vars contains the variables that the new factor should depend on.
          *  \param p Points to array of values to be added.
          */
-        TFactor( const VarSet& vars, const T* p ) : _vs(vars), _p(p, p + _vs.nrStates(), _vs.nrStates()) {}
+        TFactor( const VarSet& vars, const T* p ) : _vs(vars), _p(p, p + (size_t)_vs.nrStates(), (size_t)_vs.nrStates()) {
+            DAI_ASSERT( _vs.nrStates() <= std::numeric_limits<std::size_t>::max() );
+        }
 
         /// Constructs factor depending on variables in \a vars, copying the values from \a p
         TFactor( const VarSet& vars, const TProb<T> &p ) : _vs(vars), _p(p) {
@@ -110,6 +118,15 @@ template <typename T> class TFactor {
         }
     //@}
 
+    /// \name Get/set individual entries
+    //@{
+        /// Sets \a i 'th entry to \a val
+        void set( size_t i, T val ) { _p.set( i, val ); }
+
+        /// Gets \a i 'th entry
+        T get( size_t i ) const { return _p[i]; }
+    //@}
+
     /// \name Queries
     //@{
         /// Returns constant reference to value vector
@@ -121,16 +138,6 @@ template <typename T> class TFactor {
         /// Returns a copy of the \a i 'th entry of the value vector
         T operator[] (size_t i) const { return _p[i]; }
 
-        /// Returns a reference to the \a i 'th entry of the value vector
-        /// \deprecated Please use dai::TFactor::set() instead
-        T& operator[] (size_t i) { return _p[i]; }
-
-        /// Gets \a i 'th entry of the value vector
-        T get( size_t i ) const { return _p[i]; }
-
-        /// Sets \a i 'th entry of the value vector to \a val
-        void set( size_t i, T val ) { _p.set( i, val ); }
-
         /// Returns constant reference to variable set (i.e., the variables on which the factor depends)
         const VarSet& vars() const { return _vs; }
 
@@ -142,12 +149,6 @@ template <typename T> class TFactor {
          */
         size_t nrStates() const { return _p.size(); }
 
-        /// Returns the number of possible joint states of the variables on which the factor depends, \f$\prod_{l\in L} S_l\f$
-        /** \note This is equal to the length of the value vector.
-         *  \deprecated Please use dai::TFactor::nrStates() instead.
-         */
-        size_t states() const { return _p.size(); }
-
         /// Returns the Shannon entropy of \c *this, \f$-\sum_i p_i \log p_i\f$
         T entropy() const { return _p.entropy(); }
 
@@ -219,7 +220,7 @@ template <typename T> class TFactor {
             x._p = _p.log(zero);
             return x;
         }
-        
+
         /// Returns pointwise inverse
         /** If \a zero == \c true, uses <tt>1/0==0</tt>; otherwise, <tt>1/0==Inf</tt>.
          */
@@ -233,7 +234,7 @@ template <typename T> class TFactor {
         /// Returns normalized copy of \c *this, using the specified norm
         /** \throw NOT_NORMALIZABLE if the norm is zero
          */
-        TFactor<T> normalized( typename TProb<T>::NormType norm=TProb<T>::NORMPROB ) const {
+        TFactor<T> normalized( ProbNormType norm=NORMPROB ) const {
             TFactor<T> x;
             x._vs = _vs;
             x._p = _p.normalized( norm );
@@ -263,7 +264,7 @@ template <typename T> class TFactor {
         /// Normalizes factor using the specified norm
         /** \throw NOT_NORMALIZABLE if the norm is zero
          */
-        T normalize( typename TProb<T>::NormType norm=TProb<T>::NORMPROB ) { return _p.normalize( norm ); }
+        T normalize( ProbNormType norm=NORMPROB ) { return _p.normalize( norm ); }
     //@}
 
     /// \name Operations with scalars
@@ -347,7 +348,8 @@ template <typename T> class TFactor {
             else {
                 TFactor<T> f(*this); // make a copy
                 _vs |= g._vs;
-                size_t N = _vs.nrStates();
+                DAI_ASSERT( _vs.nrStates() < std::numeric_limits<std::size_t>::max() );
+                size_t N = (size_t)_vs.nrStates();
 
                 IndexFor i_f( f._vs, _vs );
                 IndexFor i_g( g._vs, _vs );
@@ -405,7 +407,8 @@ template <typename T> class TFactor {
                 result._p = _p.pwBinaryTr( g._p, op );
             } else {
                 result._vs = _vs | g._vs;
-                size_t N = result._vs.nrStates();
+                DAI_ASSERT( result._vs.nrStates() < std::numeric_limits<std::size_t>::max() );
+                size_t N = (size_t)result._vs.nrStates();
 
                 IndexFor i_f( _vs, result.vars() );
                 IndexFor i_g( g._vs, result.vars() );
@@ -413,7 +416,7 @@ template <typename T> class TFactor {
                 result._p.p().clear();
                 result._p.p().reserve( N );
                 for( size_t i = 0; i < N; i++, ++i_f, ++i_g )
-                    result._p.p().push_back( op( _p[i_f], g._p[i_g] ) );
+                    result._p.p().push_back( op( _p[i_f], g[i_g] ) );
             }
             return result;
         }
@@ -520,7 +523,7 @@ template<typename T> TFactor<T> TFactor<T>::marginal(const VarSet &vars, bool no
         res.set( i_res, res[i_res] + _p[i] );
 
     if( normed )
-        res.normalize( TProb<T>::NORMPROB );
+        res.normalize( NORMPROB );
 
     return res;
 }
@@ -537,7 +540,7 @@ template<typename T> TFactor<T> TFactor<T>::maxMarginal(const VarSet &vars, bool
             res.set( i_res, _p[i] );
 
     if( normed )
-        res.normalize( TProb<T>::NORMPROB );
+        res.normalize( NORMPROB );
 
     return res;
 }
@@ -588,7 +591,7 @@ template<typename T> std::ostream& operator<< (std::ostream& os, const TFactor<T
 /** \relates TFactor
  *  \pre f.vars() == g.vars()
  */
-template<typename T> T dist( const TFactor<T> &f, const TFactor<T> &g, typename TProb<T>::DistType dt ) {
+template<typename T> T dist( const TFactor<T> &f, const TFactor<T> &g, ProbDistType dt ) {
     if( f.vars().empty() || g.vars().empty() )
         return -1;
     else {
@@ -627,7 +630,7 @@ template<typename T> T MutualInfo(const TFactor<T> &f) {
     VarSet::const_iterator it = f.vars().begin();
     Var i = *it; it++; Var j = *it;
     TFactor<T> projection = f.marginal(i) * f.marginal(j);
-    return dist( f.normalized(), projection, TProb<T>::DISTKL );
+    return dist( f.normalized(), projection, DISTKL );
 }
 
 
@@ -674,6 +677,13 @@ Factor createFactorPotts( const Var &x1, const Var &x2, Real J );
 Factor createFactorDelta( const Var &v, size_t state );
 
 
+/// Returns a Kronecker delta point mass
+/** \param vs Set of variables
+ *  \param state The state of \a vs that should get value 1
+ */
+Factor createFactorDelta( const VarSet& vs, size_t state );
+
+
 } // end of namespace dai