This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/CLPBN/horus/Indexer.h

280 lines
5.7 KiB
C
Raw Normal View History

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
};
class MapIndexer
{
public:
MapIndexer (const Ranges& ranges, const vector<bool>& mapDims)
{
assert (ranges.size() == mapDims.size());
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
if (mapDims[i]) {
offsets_[i] = prod;
prod *= ranges[i];
}
}
indices_.resize (ranges.size(), 0);
ranges_ = ranges;
index_ = 0;
valid_ = true;
}
2012-05-24 22:55:20 +01:00
MapIndexer (const Ranges& ranges, size_t ignoreDim)
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; ) {
if (i != ignoreDim) {
2012-05-23 14:56:01 +01:00
offsets_[i] = prod;
prod *= ranges[i];
}
}
indices_.resize (ranges.size(), 0);
ranges_ = ranges;
index_ = 0;
valid_ = true;
}
/*
MapIndexer (
const VarIds& loopVids,
const Ranges& loopRanges,
const VarIds& mapVids,
const Ranges& mapRanges)
{
unsigned prod = 1;
vector<unsigned> offsets (mapRanges.size());
2012-05-24 22:55:20 +01:00
for (size_t i = mapRanges.size(); i-- > 0; ) {
2012-05-23 14:56:01 +01:00
offsets[i] = prod;
prod *= mapRanges[i];
}
offsets_.reserve (loopVids.size());
2012-05-24 22:55:20 +01:00
for (size_t i = 0; i < loopVids.size(); i++) {
2012-05-23 14:56:01 +01:00
VarIds::const_iterator it =
std::find (mapVids.begin(), mapVids.end(), loopVids[i]);
if (it != mapVids.end()) {
offsets_.push_back (offsets[it - mapVids.begin()]);
} else {
offsets_.push_back (0);
}
}
indices_.resize (loopVids.size(), 0);
ranges_ = loopRanges;
index_ = 0;
size_ = prod;
}
*/
MapIndexer& operator ++ (void)
{
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
size_t mappedIndex (void) const
2012-05-23 14:56:01 +01:00
{
return index_;
}
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;
}
friend ostream& operator<< (ostream &os, const MapIndexer& idx)
{
os << "(" << std::setw (2) << std::setfill('0') << idx.index_ << ") " ;
os << idx.indices_;
return os;
}
private:
2012-05-24 22:55:20 +01:00
size_t index_;
2012-05-23 14:56:01 +01:00
bool valid_;
vector<unsigned> ranges_;
vector<unsigned> indices_;
2012-05-24 22:55:20 +01:00
vector<size_t> offsets_;
2012-05-23 14:56:01 +01:00
};
#endif // HORUS_STATESINDEXER_H