2012-05-23 14:56:01 +01:00
|
|
|
#ifndef HORUS_STATESINDEXER_H
|
|
|
|
#define HORUS_STATESINDEXER_H
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <numeric>
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
|
|
#include "Var.h"
|
|
|
|
#include "Util.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StatesIndexer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
StatesIndexer (const Ranges& ranges, bool calcOffsets = true)
|
|
|
|
{
|
2012-05-24 22:55:20 +01:00
|
|
|
li_ = 0;
|
2012-05-25 14:36:52 +01:00
|
|
|
size_ = std::accumulate (ranges.begin(), ranges.end(), 1,
|
|
|
|
std::multiplies<unsigned>());
|
2012-05-23 14:56:01 +01:00
|
|
|
indices_.resize (ranges.size(), 0);
|
|
|
|
ranges_ = ranges;
|
|
|
|
if (calcOffsets) {
|
|
|
|
calculateOffsets();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void increment (void)
|
|
|
|
{
|
2012-05-24 22:55:20 +01:00
|
|
|
for (size_t i = ranges_.size(); i-- > 0; ) {
|
2012-05-23 14:56:01 +01:00
|
|
|
indices_[i] ++;
|
|
|
|
if (indices_[i] != ranges_[i]) {
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
indices_[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
li_ ++;
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
void increment (size_t dim)
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
assert (dim < ranges_.size());
|
|
|
|
assert (ranges_.size() == offsets_.size());
|
|
|
|
assert (indices_[dim] < ranges_[dim]);
|
|
|
|
indices_[dim] ++;
|
|
|
|
li_ += offsets_[dim];
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
void incrementExcluding (size_t skipDim)
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
assert (ranges_.size() == offsets_.size());
|
2012-05-24 22:55:20 +01:00
|
|
|
for (size_t i = ranges_.size(); i-- > 0; ) {
|
2012-05-23 14:56:01 +01:00
|
|
|
if (i != (int)skipDim) {
|
|
|
|
indices_[i] ++;
|
|
|
|
li_ += offsets_[i];
|
|
|
|
if (indices_[i] != ranges_[i]) {
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
indices_[i] = 0;
|
|
|
|
li_ -= offsets_[i] * ranges_[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
li_ = size_;
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
size_t linearIndex (void) const
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
return li_;
|
|
|
|
}
|
|
|
|
|
|
|
|
const vector<unsigned>& indices (void) const
|
|
|
|
{
|
|
|
|
return indices_;
|
|
|
|
}
|
|
|
|
|
|
|
|
StatesIndexer& operator ++ (void)
|
|
|
|
{
|
|
|
|
increment();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
operator size_t (void) const
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
return li_;
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
unsigned operator[] (size_t dim) const
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
assert (valid());
|
|
|
|
assert (dim < ranges_.size());
|
|
|
|
return indices_[dim];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool valid (void) const
|
|
|
|
{
|
|
|
|
return li_ < size_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset (void)
|
|
|
|
{
|
|
|
|
std::fill (indices_.begin(), indices_.end(), 0);
|
|
|
|
li_ = 0;
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
void reset (size_t dim)
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
indices_[dim] = 0;
|
|
|
|
li_ -= offsets_[dim] * ranges_[dim];
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
size_t size (void) const
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
return size_ ;
|
|
|
|
}
|
|
|
|
|
|
|
|
friend ostream& operator<< (ostream &os, const StatesIndexer& idx)
|
|
|
|
{
|
|
|
|
os << "(" << std::setw (2) << std::setfill('0') << idx.li_ << ") " ;
|
|
|
|
os << idx.indices_;
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void calculateOffsets (void)
|
|
|
|
{
|
2012-05-24 22:55:20 +01:00
|
|
|
size_t prod = 1;
|
2012-05-23 14:56:01 +01:00
|
|
|
offsets_.resize (ranges_.size());
|
2012-05-24 22:55:20 +01:00
|
|
|
for (size_t i = ranges_.size(); i-- > 0; ) {
|
2012-05-23 14:56:01 +01:00
|
|
|
offsets_[i] = prod;
|
|
|
|
prod *= ranges_[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
size_t li_;
|
|
|
|
size_t size_;
|
2012-05-23 14:56:01 +01:00
|
|
|
vector<unsigned> indices_;
|
|
|
|
vector<unsigned> ranges_;
|
2012-05-24 22:55:20 +01:00
|
|
|
vector<size_t> offsets_;
|
2012-05-23 14:56:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-05-25 20:15:05 +01:00
|
|
|
class MappingIndexer
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
public:
|
2012-05-25 20:15:05 +01:00
|
|
|
MappingIndexer (const Ranges& ranges, const vector<bool>& mask)
|
|
|
|
: index_(0), indices_(ranges.size(), 0), ranges_(ranges),
|
|
|
|
valid_(true)
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
2012-05-24 22:55:20 +01:00
|
|
|
size_t prod = 1;
|
2012-05-23 14:56:01 +01:00
|
|
|
offsets_.resize (ranges.size());
|
2012-05-24 22:55:20 +01:00
|
|
|
for (size_t i = ranges.size(); i-- > 0; ) {
|
2012-05-25 20:15:05 +01:00
|
|
|
if (mask[i]) {
|
2012-05-23 14:56:01 +01:00
|
|
|
offsets_[i] = prod;
|
|
|
|
prod *= ranges[i];
|
|
|
|
}
|
|
|
|
}
|
2012-05-25 20:15:05 +01:00
|
|
|
assert (ranges.size() == mask.size());
|
2012-05-23 14:56:01 +01:00
|
|
|
}
|
|
|
|
|
2012-05-25 20:15:05 +01:00
|
|
|
MappingIndexer (const Ranges& ranges, size_t dim)
|
|
|
|
: index_(0), indices_(ranges.size(), 0), ranges_(ranges),
|
|
|
|
valid_(true)
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
2012-05-24 22:55:20 +01:00
|
|
|
size_t prod = 1;
|
2012-05-23 14:56:01 +01:00
|
|
|
offsets_.resize (ranges.size());
|
2012-05-24 22:55:20 +01:00
|
|
|
for (size_t i = ranges.size(); i-- > 0; ) {
|
2012-05-25 20:15:05 +01:00
|
|
|
if (i != dim) {
|
2012-05-23 14:56:01 +01:00
|
|
|
offsets_[i] = prod;
|
|
|
|
prod *= ranges[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-25 20:15:05 +01:00
|
|
|
MappingIndexer& operator++ (void)
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
assert (valid_);
|
2012-05-24 22:55:20 +01:00
|
|
|
for (size_t i = ranges_.size(); i-- > 0; ) {
|
2012-05-23 14:56:01 +01:00
|
|
|
indices_[i] ++;
|
|
|
|
index_ += offsets_[i];
|
|
|
|
if (indices_[i] != ranges_[i]) {
|
|
|
|
return *this;
|
|
|
|
} else {
|
|
|
|
indices_[i] = 0;
|
|
|
|
index_ -= offsets_[i] * ranges_[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
valid_ = false;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
operator size_t (void) const
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
return index_;
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:55:20 +01:00
|
|
|
unsigned operator[] (size_t dim) const
|
2012-05-23 14:56:01 +01:00
|
|
|
{
|
|
|
|
assert (valid());
|
|
|
|
assert (dim < ranges_.size());
|
|
|
|
return indices_[dim];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool valid (void) const
|
|
|
|
{
|
|
|
|
return valid_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset (void)
|
|
|
|
{
|
|
|
|
std::fill (indices_.begin(), indices_.end(), 0);
|
|
|
|
index_ = 0;
|
|
|
|
}
|
|
|
|
|
2012-05-25 20:15:05 +01:00
|
|
|
friend std::ostream& operator<< (std::ostream&, const MappingIndexer&);
|
2012-05-23 14:56:01 +01:00
|
|
|
|
|
|
|
private:
|
2012-05-25 20:15:05 +01:00
|
|
|
size_t index_;
|
|
|
|
Ranges indices_;
|
|
|
|
const Ranges& ranges_;
|
|
|
|
bool valid_;
|
|
|
|
vector<size_t> offsets_;
|
2012-05-23 14:56:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-05-25 20:15:05 +01:00
|
|
|
|
|
|
|
inline std::ostream& operator<< (ostream &os, const MappingIndexer& mi)
|
|
|
|
{
|
|
|
|
os << "(" ;
|
|
|
|
os << std::setw (2) << std::setfill('0') << mi.index_;
|
|
|
|
os << ") " ;
|
|
|
|
os << mi.indices_;
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-05-23 14:56:01 +01:00
|
|
|
#endif // HORUS_STATESINDEXER_H
|
|
|
|
|