/// Constructor
/** \param varorders all the factor orientations for this parameter
* \param estimation a pointer to the parameter estimation method
+ * \param deletePE whether the parameter estimation object should be deleted in the destructor
*/
- SharedParameters( const FactorOrientations &varorders, ParameterEstimation *estimation, bool deleteParameterEstimationInDestructor=0);
+ SharedParameters( const FactorOrientations &varorders, ParameterEstimation *estimation, bool deletePE=false );
/// Constructor for making an object from a stream and a factor graph
SharedParameters( std::istream &is, const FactorGraph &fg_varlookup );
/// Estimate and set the shared parameters
void setParameters( FactorGraph &fg );
- void collectParameters( const FactorGraph& fg, std::vector< Real >& outVals, std::vector< Var >& outVarOrder );
+ /// Returns the parameters
+ void collectParameters( const FactorGraph &fg, std::vector<Real> &outVals, std::vector<Var> &outVarOrder );
};
/// Using all of the currently added expectations, make new factors with maximized parameters and set them in the FactorGraph.
void maximize( FactorGraph &fg );
- /// @name iterator interface
- //@{
- typedef std::vector< SharedParameters >::iterator iterator;
- typedef std::vector< SharedParameters >::const_iterator const_iterator;
- iterator begin() { return _params.begin(); }
- const_iterator begin() const { return _params.begin(); }
- iterator end() { return _params.end(); }
- const_iterator end() const { return _params.end(); }
- //@}
+ /// @name Iterator interface
+ //@{
+ typedef std::vector<SharedParameters>::iterator iterator;
+ typedef std::vector<SharedParameters>::const_iterator const_iterator;
+ iterator begin() { return _params.begin(); }
+ const_iterator begin() const { return _params.begin(); }
+ iterator end() { return _params.end(); }
+ const_iterator end() const { return _params.end(); }
+ //@}
};
*/
bool hasSatisfiedTermConditions() const;
- /// Return the last calculated log likelihood
- Real getLogZ() const { return _lastLogZ.back(); }
+ /// Return the last calculated log likelihood
+ Real getLogZ() const { return _lastLogZ.back(); }
/// Returns number of iterations done so far
size_t getCurrentIters() const { return _iters; }
- /// Get the iteration method used
- const InfAlg& eStep() const { return _estep; }
+ /// Get the iteration method used
+ const InfAlg& eStep() const { return _estep; }
/// Perform an iteration over all maximization steps
Real iterate();
/// Iterate until termination conditions are satisfied
void run();
- /// @name iterator interface
- //@{ !!!
- typedef std::vector< MaximizationStep >::iterator s_iterator;
- typedef std::vector< MaximizationStep >::const_iterator const_s_iterator;
- s_iterator s_begin() { return _msteps.begin(); }
- const_s_iterator s_begin() const { return _msteps.begin(); }
- s_iterator s_end() { return _msteps.end(); }
- const_s_iterator s_end() const { return _msteps.end(); }
- //@}
+ /// @name Iterator interface
+ //@{
+ typedef std::vector<MaximizationStep>::iterator s_iterator;
+ typedef std::vector<MaximizationStep>::const_iterator const_s_iterator;
+ s_iterator s_begin() { return _msteps.begin(); }
+ const_s_iterator s_begin() const { return _msteps.begin(); }
+ s_iterator s_end() { return _msteps.end(); }
+ const_s_iterator s_end() const { return _msteps.end(); }
+ //@}
};
/// Default constructor
Evidence() : _samples() {}
- /// Constructor with existing samples
- Evidence(std::vector<Observation>& samples) : _samples(samples) {}
+ /// Construct from existing samples
+ Evidence( std::vector<Observation> &samples ) : _samples(samples) {}
-/// Read in tabular data from a stream.
+ /// Read in tabular data from a stream.
/** Each line contains one sample, and the first line is a header line with names.
*/
void addEvidenceTabFile( std::istream& is, std::map<std::string, Var> &varMap );
-
/// Read in tabular data from a stream.
/** Each line contains one sample, and the first line is a header line with
// Function object similar to std::divides(), but different in that dividing by zero results in zero
template<typename T> struct divides0 : public std::binary_function<T, T, T> {
// Returns (j == 0 ? 0 : (i/j))
- T operator()(const T& i, const T& j) const {
+ T operator()( const T &i, const T &j ) const {
if( j == (T)0 )
return (T)0;
else
/// Constructs TFactor depending on no variables, with value p
TFactor ( Real p = 1.0 ) : _vs(), _p(1,p) {}
- /// Constructs TFactor depending on variables in ns, with uniform distribution
- TFactor( const VarSet& ns ) : _vs(ns), _p(_vs.nrStates()) {}
+ /// Constructs TFactor depending on variables in vars, with uniform distribution
+ TFactor( const VarSet& vars ) : _vs(vars), _p(_vs.nrStates()) {}
- /// Constructs TFactor depending on variables in ns, with all values set to p
- TFactor( const VarSet& ns, Real p ) : _vs(ns), _p(_vs.nrStates(),p) {}
+ /// Constructs TFactor depending on variables in vars, with all values set to p
+ TFactor( const VarSet& vars, Real p ) : _vs(vars), _p(_vs.nrStates(),p) {}
- /// Constructs TFactor depending on variables in ns, copying the values from the range starting at begin
- /** \param ns contains the variables that the new TFactor should depend on.
+ /// Constructs TFactor depending on variables in vars, copying the values from the range starting at begin
+ /** \param vars contains the variables that the new TFactor should depend on.
* \tparam Iterator Iterates over instances of type T; should support addition of size_t.
* \param begin Points to first element to be added.
*/
template<typename TIterator>
- TFactor( const VarSet& ns, TIterator begin ) : _vs(ns), _p(begin, begin + _vs.nrStates(), _vs.nrStates()) {}
+ TFactor( const VarSet& vars, TIterator begin ) : _vs(vars), _p(begin, begin + _vs.nrStates(), _vs.nrStates()) {}
- /// Constructs TFactor depending on variables in ns, with values set to the TProb p
- TFactor( const VarSet& ns, const TProb<T>& p ) : _vs(ns), _p(p) {
+ /// Constructs TFactor depending on variables in vars, with values set to the TProb p
+ TFactor( const VarSet& vars, const TProb<T> &p ) : _vs(vars), _p(p) {
DAI_DEBASSERT( _vs.nrStates() == _p.size() );
}
- TFactor( const std::vector< Var >& vars, const std::vector< T >& p ) : _vs(vars.begin(), vars.end(), vars.size()), _p(p.size()) {
+
+ /// Constructs TFactor depending on variables in vars, permuting the values given in TProb p
+ 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) {
+ for( size_t li = 0; li < p.size(); ++li )
_p[permindex.convert_linear_index(li)] = p[li];
- }
}
- /// Constructs TFactor depending on the variable n, with uniform distribution
- TFactor( const Var& n ) : _vs(n), _p(n.states()) {}
+ /// Constructs TFactor depending on the variable v, with uniform distribution
+ TFactor( const Var &v ) : _vs(v), _p(v.states()) {}
/// Returns const reference to value vector
- const TProb<T> & p() const { return _p; }
+ const TProb<T>& p() const { return _p; }
/// Returns reference to value vector
- TProb<T> & p() { return _p; }
+ TProb<T>& p() { return _p; }
/// Returns const reference to variable set
- const VarSet & vars() const { return _vs; }
+ const VarSet& vars() const { return _vs; }
/// Returns the number of possible joint states of the variables
/** \note This is equal to the length of the value vector.
private:
/// The current linear index corresponding to the state of indexVars
long _index;
-
+
/// For each variable in forVars, the amount of change in _index
std::vector<long> _sum;
/// For each variable in forVars, its number of possible values
std::vector<size_t> _dims;
-
+
public:
/// Default constructor
IndexFor() {
/// Default constructor
Permute() : _dims(), _sigma() {}
- /// Initialize from vector of index dimensions and permutation 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) {
assert( _dims.size() == _sigma.size() );
}
- 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::iterator set_iter = vs.begin();
- for (size_t i = 0; i < vs.size(); ++i, ++set_iter) {
- std::vector< Var >::const_iterator j;
- j = find(vars.begin(), vars.end(), *set_iter);
- _sigma[i] = j - vars.begin();
- }
- }
-
+ /// 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,
}
/// Shorthand for (temporarily) adding properties, e.g. PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
- PropertySet operator()(const PropertyKey &key, const PropertyValue &val) const { PropertySet copy = *this; return copy.Set(key,val); }
+ PropertySet operator()(const PropertyKey &key, const PropertyValue &val) const { PropertySet copy = *this; return copy.Set(key,val); }
- std::vector< PropertyKey > keys() const {
- std::vector< PropertyKey > result;
- result.reserve(size());
- PropertySet::const_iterator i = begin();
- for ( ; i != end(); ++i) {
- result.push_back(i->first);
- }
- return result;
- }
-
/// Check if a property with the given key exists
bool hasKey(const PropertyKey &key) const { PropertySet::const_iterator x = find(key); return (x != this->end()); }
return res;
}
+ /// Returns a vector containing all keys
+ std::vector<PropertyKey> keys() const {
+ std::vector<PropertyKey> result;
+ result.reserve( size() );
+ for( PropertySet::const_iterator i = begin(); i != end(); ++i )
+ result.push_back( i->first );
+ return result;
+ }
+
/// Writes a PropertySet object to an output stream
friend std::ostream& operator<< (std::ostream & os, const PropertySet & ps);
newEP.residual = 0.0;
_edges[i].push_back( newEP );
if( props.updates == Properties::UpdateType::SEQMAX )
- _edge2lut[i].push_back( _lut.insert( std::make_pair( newEP.residual, std::make_pair( i, _edges[i].size() - 1 ))) );
+ _edge2lut[i].push_back( _lut.insert( make_pair( newEP.residual, make_pair( i, _edges[i].size() - 1 ))) );
}
}
}
// rearrange look-up table (delete and reinsert new key)
_lut.erase( _edge2lut[i][_I] );
- _edge2lut[i][_I] = _lut.insert( std::make_pair( r, std::make_pair(i, _I) ) );
+ _edge2lut[i][_I] = _lut.insert( make_pair( r, make_pair(i, _I) ) );
}
std::vector<size_t> BP::findMaximum() const {
- std::vector<size_t> maximum( nrVars() );
- std::vector<bool> visitedVars( nrVars(), false );
- std::vector<bool> visitedFactors( nrFactors(), false );
- std::stack<size_t> scheduledFactors;
+ vector<size_t> maximum( nrVars() );
+ vector<bool> visitedVars( nrVars(), false );
+ vector<bool> visitedFactors( nrFactors(), false );
+ stack<size_t> scheduledFactors;
for( size_t i = 0; i < nrVars(); ++i ) {
if( visitedVars[i] )
continue;
// Maximise with respect to variable i
Prob prod;
calcBeliefV( i, prod );
- maximum[i] = std::max_element( prod.begin(), prod.end() ) - prod.begin();
+ maximum[i] = max_element( prod.begin(), prod.end() ) - prod.begin();
foreach( const Neighbor &I, nbV(i) )
if( !visitedFactors[I] )
// The allowed configuration is restrained according to the variables assigned so far:
// pick the argmax amongst the allowed states
- Real maxProb = std::numeric_limits<Real>::min();
+ Real maxProb = numeric_limits<Real>::min();
State maxState( factor(I).vars() );
for( State s( factor(I).vars() ); s.valid(); ++s ){
// First, calculate whether this state is consistent with variables that
if( visitedVars[j.node] ) {
// We have already visited j earlier - hopefully our state is consistent
if( maximum[j.node] != maxState(var(j.node)) && props.verbose >= 1 )
- std::cerr << "BP::findMaximum - warning: maximum not consistent due to loops." << std::endl;
+ cerr << "BP::findMaximum - warning: maximum not consistent due to loops." << endl;
} else {
// We found a consistent state for variable j
visitedVars[j.node] = true;
}
-SharedParameters::SharedParameters( const FactorOrientations &varorders, ParameterEstimation *estimation, bool deleteParameterEstimationInDestructor )
- : _varsets(), _perms(), _varorders(varorders), _estimation(estimation), _deleteEstimation(deleteParameterEstimationInDestructor)
+SharedParameters::SharedParameters( const FactorOrientations &varorders, ParameterEstimation *estimation, bool deletePE )
+ : _varsets(), _perms(), _varorders(varorders), _estimation(estimation), _deleteEstimation(deletePE)
{
// Calculate the necessary permutations
setPermsAndVarSetsFromVarOrders();
}
-void SharedParameters::collectParameters( const FactorGraph& fg, std::vector< Real >& outVals, std::vector< Var >& outVarOrder ) {
+void SharedParameters::collectParameters( const FactorGraph &fg, std::vector<Real> &outVals, std::vector<Var> &outVarOrder ) {
FactorOrientations::iterator it = _varorders.begin();
- if (it == _varorders.end()) {
- return;
- }
- FactorIndex i = it->first;
- std::vector< Var >::iterator var_it = _varorders[i].begin();
- std::vector< Var >::iterator var_stop = _varorders[i].end();
- for ( ; var_it != var_stop; ++var_it) {
- outVarOrder.push_back(*var_it);
- }
- const Factor& f = fg.factor(i);
- 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)]);
- }
+ if( it == _varorders.end() )
+ return;
+ FactorIndex I = it->first;
+ for( std::vector<Var>::const_iterator var_it = _varorders[I].begin(); var_it != _varorders[I].end(); ++var_it )
+ outVarOrder.push_back( *var_it );
+
+ const Factor &f = fg.factor(I);
+ 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)] );
}
_msteps.reserve(num_msteps);
for( size_t i = 0; i < num_msteps; ++i )
_msteps.push_back( MaximizationStep( msteps_file, estep.fg() ) );
-}
+}
void EMAlg::setTermConditions( const PropertySet &p ) {
Real EMAlg::iterate( MaximizationStep &mstep ) {
Real logZ = 0;
- Real likelihood = 0;
-
- _estep.run();
- logZ = _estep.logZ();
-
+ Real likelihood = 0;
+
+ _estep.run();
+ logZ = _estep.logZ();
+
// Expectation calculation
for( Evidence::const_iterator e = _evidence.begin(); e != _evidence.end(); ++e ) {
InfAlg* clamped = _estep.clone();
e->applyEvidence( *clamped );
clamped->init();
clamped->run();
-
- likelihood += clamped->logZ() - logZ;
-
+
+ likelihood += clamped->logZ() - logZ;
+
mstep.addExpectations( *clamped );
-
+
delete clamped;
}
-
+
// Maximization of parameters
mstep.maximize( _estep.fg() );
-
- return likelihood;
+
+ return likelihood;
}