+* Renamed Permute::convert_linear_index into Permute::convertLinearIndex
+ (and provided an alias for backwards compatibility)
+* Added examples/example_permute.cpp
* Added TProb<T>::divided_by(const TProb<T>&) const
* Fixed bug in BipartiteGraph::eraseEdge()
* Added python and octave ports for examples/example_sprinkler.cpp
all : $(TARGETS)
-examples : examples/example$(EE) examples/example_bipgraph$(EE) examples/example_varset$(EE) examples/example_sprinkler$(EE)
+examples : examples/example$(EE) examples/example_bipgraph$(EE) examples/example_varset$(EE) examples/example_permute$(EE) examples/example_sprinkler$(EE)
matlabs : matlab/dai$(ME) matlab/dai_readfg$(ME) matlab/dai_writefg$(ME) matlab/dai_potstrength$(ME)
examples/example_varset$(EE) : examples/example_varset.cpp $(HEADERS) $(LIB)/libdai$(LE)
$(CC) $(CCO)examples/example_varset$(EE) examples/example_varset.cpp $(LIBS)
+examples/example_permute$(EE) : examples/example_permute.cpp $(HEADERS) $(LIB)/libdai$(LE)
+ $(CC) $(CCO)examples/example_permute$(EE) examples/example_permute.cpp $(LIBS)
+
examples/example_sprinkler$(EE) : examples/example_sprinkler.cpp $(HEADERS) $(LIB)/libdai$(LE)
$(CC) $(CCO)examples/example_sprinkler$(EE) examples/example_sprinkler.cpp $(LIBS)
clean :
-rm *$(OE)
-rm matlab/*$(ME)
- -rm examples/example$(EE) examples/example_bipgraph$(EE) examples/example_varset$(EE) examples/example_sprinkler$(EE)
+ -rm examples/example$(EE) examples/example_bipgraph$(EE) examples/example_varset$(EE) examples/example_permute$(EE) examples/example_sprinkler$(EE)
-rm tests/testdai$(EE) tests/testem/testem$(EE) tests/testbbp$(EE)
-rm utils/fg2dot$(EE) utils/createfg$(EE) utils/fginfo$(EE)
-rm -R doc
const std::vector<Edge>& BipartiteGraph::edges() const;
size_t BipartiteGraph::VV2E(size_t n1, size_t n2) const;
size_t BipartiteGraph::nr_edges() const;
+size_t Permute::convert_linear_index( size_t li ) const;
--- /dev/null
+/* This file is part of libDAI - http://www.libdai.org/
+ *
+ * libDAI is licensed under the terms of the GNU General Public License version
+ * 2, or (at your option) any later version. libDAI is distributed without any
+ * warranty. See the file COPYING for more details.
+ *
+ * Copyright (C) 2008-2009 Joris Mooij [joris dot mooij at libdai dot org]
+ */
+
+
+#include <dai/varset.h>
+#include <dai/index.h>
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+using namespace dai;
+
+int main() {
+ Var x0(0, 2); // Define binary variable x0 (with label 0)
+ Var x1(1, 3); // Define ternary variable x1 (with label 1)
+ Var x2(2, 2); // Define binary variable x2 (with label 2)
+
+ // Define vector V = (x1, x2, x0)
+ vector<Var> V; // Define a vector of variables
+ V.push_back( x1 ); // V[0] = x1;
+ V.push_back( x2 ); // V[1] = x2;
+ V.push_back( x0 ); // V[2] = x0;
+ cout << "V = " << V << endl; // Note that the elements of X are not necessarily ordered according to their labels
+
+ // Define set X = {x0, x1, x2}
+ VarSet X; // empty
+ X |= x2; // X = {x2}
+ X |= x0; // X = {x0, x2}
+ X |= x1; // X = {x0, x1, x2}
+ cout << "X = " << X << endl; // Note that the elements of X are ordered according to their labels
+
+ cout << "Note that the ordering of the variables in X is the canonical ordering" << endl;
+ cout << "(ascendingly according to their labels) but the ordering in V is different." << endl << endl;
+
+ // N = number of variables in V (and X)
+ size_t N = V.size();
+
+ // Define a Permute object based on the variables in V
+ Permute sigma(V);
+ // Each Var in V corresponds with a dimension in a multi-dimensional array.
+ // The permutation sigma permutes these dimensions from the canonical ordering
+ // (sorted ascendingly on the label of the variable, i.e., the same ordering as
+ // in X) into the ordering these variables have in V.
+ cout << "The permutation between both variable orderings is sigma = " << sigma.sigma() << ", or more verbosely:" << endl;
+ for( size_t n = 0; n < N; n++ )
+ cout << " sigma[" << n << "] = " << sigma[n] << endl;
+ cout << "This means that variable V[sigma[n]] should correspond with the n'th variable in X (for n=0,...," << (N-1) << ")...";
+ // Check whether the permutation works as advertised
+ VarSet::const_iterator X_n = X.begin();
+ for( size_t n = 0; n < N; n++, X_n++ )
+ DAI_ASSERT( V[sigma[n]] == *X_n );
+ cout << "OK. " << endl << endl;
+
+ // Iterate over the joint states of the variables, according to the ordering in V
+ cout << "The states of the variables x0,x1,x2 are, according to the ordering in V:" << endl;
+ cout << "SV: x0: x1: x2:" << endl;
+ std::vector<size_t> ranges;
+ for( size_t i = 0; i < V.size(); i++ )
+ ranges.push_back( V[i].states() );
+ for( multifor SV(ranges); SV.valid(); ++SV )
+ cout << setw(2) << (size_t)SV << " " << SV[sigma[0]] << " " << SV[sigma[1]] << " " << SV[sigma[2]] << endl;
+ cout << endl;
+
+ // Iterate over the joint states of the variables, according to the canonical ordering in X
+ cout << "The states of the variables x0,x1,x2 are, according to the canonical ordering in X:" << endl;
+ cout << "SX: x0: x1: x2:" << endl;
+ for( State SX(X); SX.valid(); SX++ )
+ cout << setw(2) << SX << " " << SX(x0) << " " << SX(x1) << " " << SX(x2) << endl;
+ cout << endl;
+
+ // The main functionality of the Permute object is to calculate the induced permutation of linear indices of joint states
+ cout << "The permutation sigma induces the following permutation of linear indices of joint states:" << endl;
+ cout << "SV: SX:" << endl;
+ for( size_t li = 0; li < X.nrStates(); li++ )
+ cout << setw(2) << li << " " << setw(2) << sigma.convertLinearIndex( li ) << endl;
+
+ return 0;
+}
--- /dev/null
+V = (x1, x2, x0)
+X = {x0, x1, x2}
+Note that the ordering of the variables in X is the canonical ordering
+(ascendingly according to their labels) but the ordering in V is different.
+
+The permutation between both variable orderings is sigma = (2, 0, 1), or more verbosely:
+ sigma[0] = 2
+ sigma[1] = 0
+ sigma[2] = 1
+This means that variable V[sigma[n]] should correspond with the n'th variable in X (for n=0,...,2)...OK.
+
+The states of the variables x0,x1,x2 are, according to the ordering in V:
+SV: x0: x1: x2:
+ 0 0 0 0
+ 1 0 1 0
+ 2 0 2 0
+ 3 0 0 1
+ 4 0 1 1
+ 5 0 2 1
+ 6 1 0 0
+ 7 1 1 0
+ 8 1 2 0
+ 9 1 0 1
+10 1 1 1
+11 1 2 1
+
+The states of the variables x0,x1,x2 are, according to the canonical ordering in X:
+SX: x0: x1: x2:
+ 0 0 0 0
+ 1 1 0 0
+ 2 0 1 0
+ 3 1 1 0
+ 4 0 2 0
+ 5 1 2 0
+ 6 0 0 1
+ 7 1 0 1
+ 8 0 1 1
+ 9 1 1 1
+10 0 2 1
+11 1 2 1
+
+The permutation sigma induces the following permutation of linear indices of joint states:
+SV: SX:
+ 0 0
+ 1 2
+ 2 4
+ 3 6
+ 4 8
+ 5 10
+ 6 1
+ 7 3
+ 8 5
+ 9 7
+10 9
+11 11
#include <dai/varset.h>
+#include <dai/index.h>
#include <iostream>
using namespace std;
cout << "VarSet " << X << " has " << X.nrStates() << " states (joint assignments of its variables)." << endl << endl;
cout << "States of VarSets correspond to states of their constituent Vars:" << endl;
- cout << " state of x0: state of x1: state of X:" << endl;
+ cout << " state of x0: state of x1: (linear) state of X:" << endl;
for( size_t s1 = 0; s1 < x1.states(); s1++ ) // for all states s1 of x1
for( size_t s0 = 0; s0 < x0.states(); s0++ ) { // for all states s0 of x0
// store s0 and s1 in a map "states"
}
cout << endl << "And vice versa:" << endl;
- cout << " state of x0: state of x1: state of X:" << endl;
+ cout << " state of x0: state of x1: (linear) state of X:" << endl;
for( size_t S = 0; S < X.nrStates(); S++ ) { // for all (joint) states of X
// calculate states of x0 and x1 corresponding to state S of X
map<Var,size_t> states = X.calcStates(S);
DAI_ASSERT( X.calcState(X.calcStates(S)) == S );
}
+ cout << endl << "Iterating over all joint states using the State class:" << endl;
+ cout << " state of x0: state of x1: (linear) state of X: state of X (as a map):" << endl;
+ for( State S(X); S.valid(); S++ ) {
+ // output state of X and corresponding states of x0, x1
+ cout << " " << S(x0) << " " << S(x1) << " " << S << " " << S.get() << endl;
+ }
+
return 0;
}
TFactor( const std::vector<Var> &vars, const std::vector<T> &p ) : _vs(vars.begin(), vars.end(), vars.size()), _p(p.size()) {
Permute permindex(vars);
for( size_t li = 0; li < p.size(); ++li )
- _p[permindex.convert_linear_index(li)] = p[li];
+ _p[permindex.convertLinearIndex(li)] = p[li];
}
/// Constructs TFactor depending on the variable v, with uniform distribution
/// \file
-/// \brief Defines the IndexFor, MultiFor, Permute and State classes
-/// \todo Improve documentation
+/// \brief Defines the IndexFor, multifor, Permute and State classes
+/// \todo Improve documentation of IndexFor
#ifndef __defined_libdai_index_h
std::vector<size_t> _count;
/// For each variable in forVars, its number of possible values
- std::vector<size_t> _dims;
+ std::vector<size_t> _ranges;
public:
/// Default constructor
IndexFor( const VarSet& indexVars, const VarSet& forVars ) : _count( forVars.size(), 0 ) {
long sum = 1;
- _dims.reserve( forVars.size() );
+ _ranges.reserve( forVars.size() );
_sum.reserve( forVars.size() );
VarSet::const_iterator j = forVars.begin();
for( VarSet::const_iterator i = indexVars.begin(); i != indexVars.end(); ++i ) {
for( ; j != forVars.end() && *j <= *i; ++j ) {
- _dims.push_back( j->states() );
+ _ranges.push_back( j->states() );
_sum.push_back( (*i == *j) ? sum : 0 );
}
sum *= i->states();
}
for( ; j != forVars.end(); ++j ) {
- _dims.push_back( j->states() );
+ _ranges.push_back( j->states() );
_sum.push_back( 0 );
}
_index = 0;
while( i < _count.size() ) {
_index += _sum[i];
- if( ++_count[i] < _dims[i] )
+ if( ++_count[i] < _ranges[i] )
break;
- _index -= _sum[i] * _dims[i];
+ _index -= _sum[i] * _ranges[i];
_count[i] = 0;
i++;
}
};
-/// MultiFor makes it easy to perform a dynamic number of nested for loops.
+/// Tool for calculating permutations of linear indices of multi-dimensional arrays.
+class Permute {
+ private:
+ /// Stores the number of possible values of all indices
+ std::vector<size_t> _ranges;
+ /// Stores the permutation
+ std::vector<size_t> _sigma;
+
+ public:
+ /// Default constructor
+ Permute() : _ranges(), _sigma() {}
+
+ /// Construct from vector of index ranges and permutation
+ Permute( const std::vector<size_t> &rs, const std::vector<size_t> &sigma ) : _ranges(rs), _sigma(sigma) {
+ DAI_ASSERT( _ranges.size() == _sigma.size() );
+ }
+
+ /// Construct from vector of variables.
+ /** The implied permutation maps the index of each variable in \a vars according to the canonical ordering
+ * (i.e., sorted ascendingly according to their label) to the index it has in \a vars.
+ */
+ Permute( const std::vector<Var> &vars ) : _ranges(vars.size()), _sigma(vars.size()) {
+ for( size_t i = 0; i < vars.size(); ++i )
+ _ranges[i] = vars[i].states();
+ VarSet vs( vars.begin(), vars.end(), vars.size() );
+ VarSet::const_iterator vs_i = vs.begin();
+ for( size_t i = 0; i < vs.size(); ++i, ++vs_i )
+ _sigma[i] = find( vars.begin(), vars.end(), *vs_i ) - vars.begin();
+ }
+
+ /// Calculates a permuted linear index.
+ /** Converts the linear index \a li to a vector index, permutes its
+ * components, and converts it back to a linear index.
+ */
+ size_t convertLinearIndex( size_t li ) const {
+ size_t N = _ranges.size();
+
+ // calculate vector index corresponding to linear index
+ std::vector<size_t> vi;
+ vi.reserve( N );
+ size_t prod = 1;
+ for( size_t k = 0; k < N; k++ ) {
+ vi.push_back( li % _ranges[k] );
+ li /= _ranges[k];
+ prod *= _ranges[k];
+ }
+
+ // convert permuted vector index to corresponding linear index
+ prod = 1;
+ size_t sigma_li = 0;
+ for( size_t k = 0; k < N; k++ ) {
+ sigma_li += vi[_sigma[k]] * prod;
+ prod *= _ranges[_sigma[k]];
+ }
+
+ return sigma_li;
+ }
+
+ // OBSOLETE
+ /// For backwards compatibility (to be removed soon)
+ size_t convert_linear_index( size_t li ) const { return convertLinearIndex(li); }
+
+ /// Returns const reference to the permutation
+ const std::vector<size_t>& sigma() const { return _sigma; }
+
+ /// Returns reference to the permutation
+ std::vector<size_t>& sigma() { return _sigma; }
+
+ /// Returns the result of applying the permutation on \a i
+ size_t operator[]( size_t i ) const {
+#ifdef DAI_DEBUG
+ return _sigma.at(i);
+#else
+ return _sigma[i];
+#endif
+ }
+};
+
+
+/// multifor makes it easy to perform a dynamic number of nested \c for loops.
/** An example of the usage is as follows:
* \code
- * std::vector<size_t> dims;
- * dims.push_back( 3 );
- * dims.push_back( 4 );
- * dims.push_back( 5 );
- * for( MultiFor s(dims); s.valid(); ++s )
- * cout << "linear index: " << (size_t)s << " corresponds to indices " << s[0] << ", " << s[1] << ", " << s[2] << endl;
+ * std::vector<size_t> ranges;
+ * ranges.push_back( 3 );
+ * ranges.push_back( 4 );
+ * ranges.push_back( 5 );
+ * for( multifor s(ranges); s.valid(); ++s )
+ * cout << "linear index: " << (size_t)s << " corresponds to indices " << s[2] << ", " << s[1] << ", " << s[0] << endl;
* \endcode
* which would be equivalent to:
* \code
* size_t s = 0;
- * for( size_t s0 = 0; s0 < 3; s0++ )
+ * for( size_t s2 = 0; s2 < 5; s2++ )
* for( size_t s1 = 0; s1 < 4; s1++ )
- * for( size_t s2 = 0; s2 < 5; s++, s2++ )
- * cout << "linear index: " << (size_t)s << " corresponds to indices " << s0 << ", " << s1 << ", " << s2 << endl;
+ * for( size_t s0 = 0; s0 < 3; s++, s0++ )
+ * cout << "linear index: " << (size_t)s << " corresponds to indices " << s2 << ", " << s1 << ", " << s0 << endl;
* \endcode
*/
-class MultiFor {
+class multifor {
private:
- std::vector<size_t> _dims;
- std::vector<size_t> _states;
- long _state;
+ /// Stores the number of possible values of all indices
+ std::vector<size_t> _ranges;
+ /// Stores the current values of all indices
+ std::vector<size_t> _indices;
+ /// Stores the current linear index
+ long _linear_index;
public:
/// Default constructor
- MultiFor() : _dims(), _states(), _state(0) {}
+ multifor() : _ranges(), _indices(), _linear_index(0) {}
- /// Initialize from vector of index dimensions
- MultiFor( const std::vector<size_t> &d ) : _dims(d), _states(d.size(),0), _state(0) {}
+ /// Initialize from vector of index ranges
+ multifor( const std::vector<size_t> &d ) : _ranges(d), _indices(d.size(),0), _linear_index(0) {}
- /// Return linear state
+ /// Returns linear index (i.e., the index in the Cartesian product space)
operator size_t() const {
- DAI_ASSERT( valid() );
- return( _state );
+ DAI_DEBASSERT( valid() );
+ return( _linear_index );
}
- /// Return k'th index
+ /// Returns \a k 'th index
size_t operator[]( size_t k ) const {
- DAI_ASSERT( valid() );
- DAI_ASSERT( k < _states.size() );
- return _states[k];
+ DAI_DEBASSERT( valid() );
+ DAI_DEBASSERT( k < _indices.size() );
+ return _indices[k];
}
- /// Prefix increment operator
- MultiFor & operator++() {
+ /// Increments the current indices (prefix)
+ multifor & operator++() {
if( valid() ) {
- _state++;
+ _linear_index++;
size_t i;
- for( i = 0; i != _states.size(); i++ ) {
- if( ++(_states[i]) < _dims[i] )
+ for( i = 0; i != _indices.size(); i++ ) {
+ if( ++(_indices[i]) < _ranges[i] )
break;
- _states[i] = 0;
+ _indices[i] = 0;
}
- if( i == _states.size() )
- _state = -1;
+ if( i == _indices.size() )
+ _linear_index = -1;
}
return *this;
}
- /// Postfix increment operator
+ /// Increments the current indices (postfix)
void operator++( int ) {
operator++();
}
- /// Returns true if the current state is valid
+ /// Returns \c true if the current indices are valid
bool valid() const {
- return( _state >= 0 );
- }
-};
-
-
-/// Tool for calculating permutations of multiple indices.
-class Permute {
- private:
- std::vector<size_t> _dims;
- std::vector<size_t> _sigma;
-
- public:
- /// Default constructor
- Permute() : _dims(), _sigma() {}
-
- /// Construct from vector of index dimensions and permutation sigma
- Permute( const std::vector<size_t> &d, const std::vector<size_t> &sigma ) : _dims(d), _sigma(sigma) {
- DAI_ASSERT( _dims.size() == _sigma.size() );
- }
-
- /// Construct from vector of variables
- Permute( const std::vector<Var> &vars ) : _dims(vars.size()), _sigma(vars.size()) {
- VarSet vs( vars.begin(), vars.end(), vars.size() );
- for( size_t i = 0; i < vars.size(); ++i )
- _dims[i] = vars[i].states();
- VarSet::const_iterator set_iter = vs.begin();
- for( size_t i = 0; i < vs.size(); ++i, ++set_iter )
- _sigma[i] = find( vars.begin(), vars.end(), *set_iter ) - vars.begin();
- }
-
- /// Calculates a permuted linear index.
- /** Converts the linear index li to a vector index
- * corresponding with the dimensions in _dims, permutes it according to sigma,
- * and converts it back to a linear index according to the permuted dimensions.
- */
- size_t convert_linear_index( size_t li ) const {
- size_t N = _dims.size();
-
- // calculate vector index corresponding to linear index
- std::vector<size_t> vi;
- vi.reserve( N );
- size_t prod = 1;
- for( size_t k = 0; k < N; k++ ) {
- vi.push_back( li % _dims[k] );
- li /= _dims[k];
- prod *= _dims[k];
- }
-
- // convert permuted vector index to corresponding linear index
- prod = 1;
- size_t sigma_li = 0;
- for( size_t k = 0; k < N; k++ ) {
- sigma_li += vi[_sigma[k]] * prod;
- prod *= _dims[_sigma[k]];
- }
-
- return sigma_li;
+ return( _linear_index >= 0 );
}
};
-/// Contains the joint state of variables within a VarSet and useful things to do with this information.
-/** This is very similar to a MultiFor, but tailored for Vars and Varsets.
+/// Makes it easy to iterate over all possible joint states of variables within a VarSet.
+/** A joint state of several variables can be represented in two different ways, by a map that maps each variable
+ * to its own state, or by an integer that gives the index of the joint state in the canonical enumeration.
+ *
+ * Both representations are useful, and the main functionality provided by the State class is to simplify iterating
+ * over the various joint states of a VarSet and to provide access to the current state in both representations.
+ *
+ * \note The same functionality could be achieved by simply iterating over the linear state and using VarSet::calcStates,
+ * but the State class offers a more efficient implementation.
+ *
+ * \note A State is very similar to a \link multifor \endlink, but tailored for Var 's and VarSet 's.
+ *
+ * \see VarSet::calcState, VarSet::calcStates
*/
class State {
private:
+ /// Type for representing a joint state of some variables as a map, which maps each variable to its state
typedef std::map<Var, size_t> states_type;
+ /// Current state (represented linearly)
long state;
+
+ /// Current state (represented as a map)
states_type states;
public:
/// Default constructor
State() : state(0), states() {}
- /// Initialize from VarSet
+ /// Initialize from VarSet, resetting the current state
State( const VarSet &vs ) : state(0) {
for( VarSet::const_iterator v = vs.begin(); v != vs.end(); v++ )
states[*v] = 0;
}
- /// Return linear state
+ /// Return current linear state
operator size_t() const {
DAI_ASSERT( valid() );
return( state );
}
- /// Return state of variable n, or zero if n is not in this State
- size_t operator() ( const Var &n ) const {
+ /// Return current state represented as a map
+ const states_type& get() const { return states; }
+
+ /// Return current state of variable \a v, or 0 if \a v is not in \c *this
+ size_t operator() ( const Var &v ) const {
DAI_ASSERT( valid() );
- states_type::const_iterator entry = states.find( n );
+ states_type::const_iterator entry = states.find( v );
if( entry == states.end() )
return 0;
else
return entry->second;
}
- /// Return linear state of variables in varset, setting them to zero if they are not in this State
+ /// Return linear state of variables in \a vs, assuming that variables that are not in \c *this are in state 0
size_t operator() ( const VarSet &vs ) const {
DAI_ASSERT( valid() );
size_t vs_state = 0;
return vs_state;
}
- /// Prefix increment operator
+ /// Increments the current state (prefix)
void operator++( ) {
if( valid() ) {
state++;
}
}
- /// Postfix increment operator
+ /// Increments the current state (postfix)
void operator++( int ) {
operator++();
}
- /// Returns true if the current state is valid
+ /// Returns \c true if the current state is valid
bool valid() const {
return( state >= 0 );
}
+
+ /// Resets the current state (to the joint state represented by linear state 0)
+ void reset() {
+ state = 0;
+ for( states_type::iterator s = states.begin(); s != states.end(); s++ )
+ s->second = 0;
+ }
};
} // end of namespace dai
+/** \example example_permute.cpp
+ * This example shows how to use the Permute, multifor and State classes.
+ *
+ * \section Output
+ * \verbinclude examples/example_permute.out
+ *
+ * \section Source
+ */
+
+
#endif
return Z;
}
- /// Returns true if one or more entries are NaN
+ /// Returns \c true if one or more entries are NaN
bool hasNaNs() const {
bool foundnan = false;
for( typename std::vector<T>::const_iterator x = _p.begin(); x != _p.end(); x++ )
return foundnan;
}
- /// Returns true if one or more entries are negative
+ /// Returns \c true if one or more entries are negative
bool hasNegatives() const {
return (std::find_if( _p.begin(), _p.end(), std::bind2nd( std::less<T>(), (T)0 ) ) != _p.end());
}
}
/// Lexicographical comparison
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
*/
bool operator<= (const TProb<T> & q) const {
DAI_DEBASSERT( size() == q.size() );
}
/// Returns pointwise logarithm
- /** If zero==true, uses log(0)==0; otherwise, log(0)==-Inf.
+ /** If \a zero == \c true, uses <tt>log(0)==0</tt>; otherwise, <tt>log(0)==-Inf</tt>.
*/
TProb<T> log(bool zero=false) const {
TProb<T> l(*this);
}
/// Returns pointwise inverse
- /** If zero==true; uses 1/0==0, otherwise 1/0==Inf.
+ /** If \a zero == \c true, uses <tt>1/0==0</tt>; otherwise, <tt>1/0==Inf</tt>.
*/
TProb<T> inverse(bool zero=true) const {
TProb<T> inv;
}
/// Applies logarithm pointwise
- /** If zero==true, uses log(0)==0; otherwise, log(0)==-Inf.
+ /** If \a zero == \c true, uses <tt>log(0)==0</tt>; otherwise, <tt>log(0)==-Inf</tt>.
*/
const TProb<T>& takeLog(bool zero=false) {
if( zero ) {
/// \name Operations with other equally-sized vectors
//@{
/// Pointwise addition with \a q
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
*/
TProb<T>& operator+= (const TProb<T> & q) {
DAI_DEBASSERT( size() == q.size() );
}
/// Pointwise subtraction of \a q
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
*/
TProb<T>& operator-= (const TProb<T> & q) {
DAI_DEBASSERT( size() == q.size() );
}
/// Pointwise multiplication with \a q
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
*/
TProb<T>& operator*= (const TProb<T> & q) {
DAI_DEBASSERT( size() == q.size() );
}
/// Pointwise division by \a q, where division by 0 yields 0
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
* \see divide(const TProb<T> &)
*/
TProb<T>& operator/= (const TProb<T> & q) {
}
/// Pointwise division by \a q, where division by 0 yields +Inf
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
* \see operator/=(const TProb<T> &)
*/
TProb<T>& divide (const TProb<T> & q) {
/// \name Transformations with other equally-sized vectors
//@{
/// Returns sum of \c *this and \a q
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
*/
TProb<T> operator+ (const TProb<T> & q) const {
DAI_DEBASSERT( size() == q.size() );
}
/// Return \c *this minus \a q
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
*/
TProb<T> operator- (const TProb<T> & q) const {
DAI_DEBASSERT( size() == q.size() );
}
/// Return product of \c *this with \a q
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
*/
TProb<T> operator* (const TProb<T> & q) const {
DAI_DEBASSERT( size() == q.size() );
}
/// Returns quotient of \c *this with \a q, where division by 0 yields +Inf
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
* \see divided_by(const TProb<T> &)
*/
TProb<T> operator/ (const TProb<T> & q) const {
}
/// Pointwise division by \a q, where division by 0 yields 0
- /** \pre this->size() == q.size()
+ /** \pre <tt>this->size() == q.size()</tt>
* \see operator/(const TProb<T> &)
*/
TProb<T> divided_by (const TProb<T> & q) const {
/// Returns distance between \a p and \a q, measured using distance measure \a dt
/** \relates TProb
- * \pre this->size() == q.size()
+ * \pre <tt>this->size() == q.size()</tt>
*/
template<typename T> T dist( const TProb<T> &p, const TProb<T> &q, typename TProb<T>::DistType dt ) {
DAI_DEBASSERT( p.size() == q.size() );
/// Writes a TProb<T> to an output stream
/** \relates TProb
*/
-template<typename T> std::ostream& operator<< (std::ostream& os, const TProb<T>& P) {
+template<typename T> std::ostream& operator<< (std::ostream& os, const TProb<T>& p) {
os << "[";
- std::copy( P.p().begin(), P.p().end(), std::ostream_iterator<T>(os, " ") );
+ std::copy( p.p().begin(), p.p().end(), std::ostream_iterator<T>(os, " ") );
os << "]";
return os;
}
-/// Returns the TProb<T> containing the pointwise minimum of a and b (which should have equal size)
+/// Returns the pointwise minimum of \a a and \a b
/** \relates TProb
+ * \pre <tt>this->size() == q.size()</tt>
*/
template<typename T> TProb<T> min( const TProb<T> &a, const TProb<T> &b ) {
DAI_ASSERT( a.size() == b.size() );
}
-/// Returns the TProb<T> containing the pointwise maximum of a and b (which should have equal size)
+/// Returns the pointwise maximum of \a a and \a b
/** \relates TProb
+ * \pre <tt>this->size() == q.size()</tt>
*/
template<typename T> TProb<T> max( const TProb<T> &a, const TProb<T> &b ) {
DAI_ASSERT( a.size() == b.size() );
template<class T>
std::ostream& operator << (std::ostream& os, const std::set<T> & x) {
os << "{";
- for( typename std::set<T>::const_iterator it = x.begin(); it != x.end(); it++ )
+ for( typename std::set<T>::const_iterator it = x.begin(); it != x.end(); it++ )
os << (it != x.begin() ? ", " : "") << *it;
os << "}";
return os;
friend std::ostream& operator<<( std::ostream &os, const VarSet &vs ) {
os << "{";
for( VarSet::const_iterator v = vs.begin(); v != vs.end(); v++ )
- os << (v != vs.begin() ? "," : "") << *v;
+ os << (v != vs.begin() ? ", " : "") << *v;
os << "}";
return( os );
}
/** \example example_varset.cpp
- * This example shows how to use the Var and VarSet classes. It also explains the concept of "states" for VarSets.
+ * This example shows how to use the Var, VarSet and State classes. It also explains the concept of "states" for VarSets.
*
* \section Output
* \verbinclude examples/example_varset.out
Factor b = alg.belief(vs);
Prob p( b.states(), 0.0 );
for( size_t entry = 0; entry < b.states(); ++entry )
- p[entry] = b[perm.convert_linear_index(entry)];
+ p[entry] = b[perm.convertLinearIndex(entry)];
_estimation->addSufficientStatistics( p );
}
}
Factor f( vs, 0.0 );
for( size_t entry = 0; entry < f.states(); ++entry )
- f[perm.convert_linear_index(entry)] = p[entry];
+ f[perm.convertLinearIndex(entry)] = p[entry];
fg.setFactor( i->first, f );
}
DAI_ASSERT( f.vars() == _varsets[I] );
const Permute &perm = _perms[I];
for( size_t val_index = 0; val_index < f.states(); ++val_index )
- outVals.push_back( f[perm.convert_linear_index(val_index)] );
+ outVals.push_back( f[perm.convertLinearIndex(val_index)] );
}
// store value, but permute indices first according
// to internal representation
- facs.back()[permindex.convert_linear_index( li )] = val;
+ facs.back()[permindex.convertLinearIndex( li )] = val;
}
}
}
Permute permindex( di, perm );
for( size_t li = 0; li < prod; li++ )
- factors.back()[permindex.convert_linear_index(li)] = factordata[li];
+ factors.back()[permindex.convertLinearIndex(li)] = factordata[li];
}
if( verbose >= 3 ) {
}
Permute permindex( di, perm );
for( size_t li = 0; li < prod; li++ )
- factor[permindex.convert_linear_index(li)] = factordata[li];
+ factor[permindex.convertLinearIndex(li)] = factordata[li];
return( factor );
}