247 lines
5.7 KiB
C++
247 lines
5.7 KiB
C++
#ifndef HORUS_STATESINDEXER_H
|
|
#define HORUS_STATESINDEXER_H
|
|
|
|
#include <iomanip>
|
|
|
|
class StatesIndexer {
|
|
public:
|
|
|
|
StatesIndexer (const Ranges& ranges)
|
|
{
|
|
maxIndex_ = 1;
|
|
states_.resize (ranges.size(), 0);
|
|
ranges_ = ranges;
|
|
for (unsigned i = 0; i < ranges.size(); i++) {
|
|
maxIndex_ *= ranges[i];
|
|
}
|
|
linearIndex_ = 0;
|
|
}
|
|
|
|
|
|
StatesIndexer (const VarNodes& vars)
|
|
{
|
|
maxIndex_ = 1;
|
|
states_.resize (vars.size(), 0);
|
|
ranges_.reserve (vars.size());
|
|
for (unsigned i = 0; i < vars.size(); i++) {
|
|
ranges_.push_back (vars[i]->nrStates());
|
|
maxIndex_ *= vars[i]->nrStates();
|
|
}
|
|
linearIndex_ = 0;
|
|
}
|
|
|
|
StatesIndexer& operator++ (void) {
|
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
|
states_[i] ++;
|
|
if (states_[i] == (int)ranges_[i]) {
|
|
states_[i] = 0;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
linearIndex_ ++;
|
|
return *this;
|
|
}
|
|
|
|
StatesIndexer& operator-- (void) {
|
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
|
states_[i] --;
|
|
if (states_[i] == -1) {
|
|
states_[i] = ranges_[i] - 1;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
linearIndex_ --;
|
|
return *this;
|
|
}
|
|
|
|
void incrementState (unsigned whichVar)
|
|
{
|
|
for (int i = whichVar; i >= 0; i--) {
|
|
states_[i] ++;
|
|
if (states_[i] == (int)ranges_[i] && i != 0) {
|
|
if (i == 0) {
|
|
linearIndex_ = maxIndex_;
|
|
} else {
|
|
states_[i] = 0;
|
|
}
|
|
} else {
|
|
linearIndex_ = getLinearIndexFromStates();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void decrementState (unsigned whichVar)
|
|
{
|
|
for (int i = whichVar; i >= 0; i--) {
|
|
states_[i] --;
|
|
if (states_[i] == -1) {
|
|
if (i == 0) {
|
|
linearIndex_ = -1;
|
|
} else {
|
|
states_[i] = ranges_[i] - 1;
|
|
}
|
|
} else {
|
|
linearIndex_ = getLinearIndexFromStates();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void nextSameState (unsigned whichVar)
|
|
{
|
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
|
if (i != (int)whichVar) {
|
|
states_[i] ++;
|
|
if (states_[i] == (int)ranges_[i]) {
|
|
if (i == 0 || (i-1 == (int)whichVar && whichVar == 0)) {
|
|
linearIndex_ = maxIndex_;
|
|
} else {
|
|
states_[i] = 0;
|
|
}
|
|
} else {
|
|
linearIndex_ = getLinearIndexFromStates();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void previousSameState (unsigned whichVar)
|
|
{
|
|
for (int i = ranges_.size() - 1; i >= 0; i--) {
|
|
if (i != (int)whichVar) {
|
|
states_[i] --;
|
|
if (states_[i] == - 1) {
|
|
if (i == 0 || (i-1 == (int)whichVar && whichVar == 0)) {
|
|
linearIndex_ = -1;
|
|
} else {
|
|
states_[i] = ranges_[i] - 1;
|
|
}
|
|
} else {
|
|
linearIndex_ = getLinearIndexFromStates();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void moveToBegin (void)
|
|
{
|
|
std::fill (states_.begin(), states_.end(), 0);
|
|
linearIndex_ = 0;
|
|
}
|
|
|
|
void moveToEnd (void)
|
|
{
|
|
for (unsigned i = 0; i < states_.size(); i++) {
|
|
states_[i] = ranges_[i] - 1;
|
|
}
|
|
linearIndex_ = maxIndex_ - 1;
|
|
}
|
|
|
|
bool valid (void) const
|
|
{
|
|
return linearIndex_ >= 0 && linearIndex_ < (int)maxIndex_;
|
|
}
|
|
|
|
unsigned getLinearIndex (void) const
|
|
{
|
|
return linearIndex_;
|
|
}
|
|
|
|
const vector<int>& getStates (void) const
|
|
{
|
|
return states_;
|
|
}
|
|
|
|
unsigned operator[] (unsigned whichVar) const
|
|
{
|
|
assert (valid());
|
|
assert (whichVar < states_.size());
|
|
return states_[whichVar];
|
|
}
|
|
|
|
string toString (void) const
|
|
{
|
|
stringstream ss;
|
|
ss << "linear index=" << setw (3) << linearIndex_ << " " ;
|
|
ss << "states= [" << states_[0] ;
|
|
for (unsigned i = 1; i < states_.size(); i++) {
|
|
ss << ", " << states_[i];
|
|
}
|
|
ss << "]" ;
|
|
return ss.str();
|
|
}
|
|
|
|
private:
|
|
unsigned getLinearIndexFromStates (void)
|
|
{
|
|
unsigned prod = 1;
|
|
unsigned linearIndex = 0;
|
|
for (int i = states_.size() - 1; i >= 0; i--) {
|
|
linearIndex += states_[i] * prod;
|
|
prod *= ranges_[i];
|
|
}
|
|
return linearIndex;
|
|
}
|
|
|
|
int linearIndex_;
|
|
int maxIndex_;
|
|
vector<int> states_;
|
|
vector<unsigned> ranges_;
|
|
};
|
|
|
|
|
|
/*
|
|
FgVarNode* v1 = new FgVarNode (0, 4);
|
|
FgVarNode* v2 = new FgVarNode (1, 3);
|
|
FgVarNode* v3 = new FgVarNode (2, 2);
|
|
FgVarSet vars = {v1,v2,v3};
|
|
ParamSet params = {
|
|
0.2, 0.44, 0.1, 0.88, 0.22,0.62,0.32, 0.42, 0.11, 0.88, 0.8,0.5,
|
|
0.22, 0.4, 0.11, 0.8, 0.224,0.6,0.21, 0.44, 0.14, 0.68, 0.41,0.6
|
|
};
|
|
Factor f (vars,params);
|
|
StatesIndexer idx (vars);
|
|
while (idx.valid())
|
|
{
|
|
cout << idx.toString() << " p=" << params[idx.getLinearIndex()] << endl;
|
|
idx.incrementVariableState (0);
|
|
idx.nextSameState (1);
|
|
++idx;
|
|
}
|
|
cout << endl;
|
|
idx.moveToEnd();
|
|
while (idx.valid())
|
|
{
|
|
cout << idx.toString() << " p=" << params[idx.getLinearIndex()] << endl;
|
|
idx.decrementVariableState (0);
|
|
idx.previousSameState (1);
|
|
--idx;
|
|
}
|
|
*/
|
|
|
|
|
|
/*
|
|
FgVarNode* x0 = new FgVarNode (0, 2);
|
|
FgVarNode* x1 = new FgVarNode (1, 2);
|
|
FgVarNode* x2 = new FgVarNode (2, 2);
|
|
FgVarNode* x3 = new FgVarNode (2, 2);
|
|
FgVarNode* x4 = new FgVarNode (2, 2);
|
|
FgVarSet vars_ = {x0,x1,x2,x3,x4};
|
|
ParamSet params_ = {
|
|
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
|
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
|
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5,
|
|
0.2, 0.44, 0.1, 0.88, 0.11, 0.88, 0.8, 0.5
|
|
};
|
|
Factor ff (vars_,params_);
|
|
ff.printFactor();
|
|
*/
|
|
|
|
#endif // HORUS_STATESINDEXER_H
|
|
|