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

260 lines
5.4 KiB
C
Raw Normal View History

#ifndef HORUS_INDEXER_H
#define HORUS_INDEXER_H
2012-05-23 14:56:01 +01:00
#include <algorithm>
#include <functional>
#include <sstream>
#include <iomanip>
#include "Util.h"
class Indexer
2012-05-23 14:56:01 +01:00
{
public:
Indexer (const Ranges& ranges, bool calcOffsets = true)
: index_(0), indices_(ranges.size(), 0), ranges_(ranges)
2012-05-23 14:56:01 +01:00
{
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
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;
}
}
index_ ++;
2012-05-23 14:56:01 +01:00
}
void incrementDimension (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] ++;
index_ += offsets_[dim];
2012-05-23 14:56:01 +01:00
}
void incrementExceptDimension (size_t dim)
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; ) {
if (i != dim) {
2012-05-23 14:56:01 +01:00
indices_[i] ++;
index_ += offsets_[i];
2012-05-23 14:56:01 +01:00
if (indices_[i] != ranges_[i]) {
return;
} else {
indices_[i] = 0;
index_ -= offsets_[i] * ranges_[i];
2012-05-23 14:56:01 +01:00
}
}
}
index_ = size_;
2012-05-23 14:56:01 +01:00
}
Indexer& operator++ (void)
2012-05-23 14:56:01 +01:00
{
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 index_;
2012-05-23 14:56:01 +01:00
}
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 index_ < size_;
2012-05-23 14:56:01 +01:00
}
void reset (void)
{
std::fill (indices_.begin(), indices_.end(), 0);
index_ = 0;
2012-05-23 14:56:01 +01:00
}
void resetDimension (size_t dim)
2012-05-23 14:56:01 +01:00
{
indices_[dim] = 0;
index_ -= offsets_[dim] * ranges_[dim];
2012-05-23 14:56:01 +01:00
}
2012-05-24 22:55:20 +01:00
size_t size (void) const
2012-05-23 14:56:01 +01:00
{
return size_ ;
}
friend std::ostream& operator<< (std::ostream&, const Indexer&);
2012-05-23 14:56:01 +01:00
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];
}
}
size_t index_;
Ranges indices_;
const Ranges& ranges_;
size_t size_;
vector<size_t> offsets_;
2012-05-23 14:56:01 +01:00
};
inline std::ostream&
operator<< (std::ostream& os, const Indexer& indexer)
{
os << "(" ;
os << std::setw (2) << std::setfill('0') << indexer.index_;
os << ") " ;
os << indexer.indices_;
return os;
}
2012-05-28 12:32:15 +01:00
class MapIndexer
2012-05-23 14:56:01 +01:00
{
public:
2012-05-28 12:32:15 +01:00
MapIndexer (const Ranges& ranges, const vector<bool>& mask)
2012-05-25 20:15:05 +01:00
: 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;
offsets_.resize (ranges.size(), 0);
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-28 12:32:15 +01:00
MapIndexer (const Ranges& ranges, size_t dim)
2012-05-25 20:15:05 +01:00
: 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;
offsets_.resize (ranges.size(), 0);
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];
}
}
}
template <typename T>
2012-05-28 12:32:15 +01:00
MapIndexer (
const vector<T>& allArgs,
const Ranges& allRanges,
const vector<T>& wantedArgs,
const Ranges& wantedRanges)
: index_(0), indices_(allArgs.size(), 0), ranges_(allRanges),
valid_(true)
{
size_t prod = 1;
vector<size_t> offsets (wantedRanges.size());
for (size_t i = wantedRanges.size(); i-- > 0; ) {
offsets[i] = prod;
prod *= wantedRanges[i];
}
offsets_.reserve (allArgs.size());
for (size_t i = 0; i < allArgs.size(); i++) {
size_t idx = Util::indexOf (wantedArgs, allArgs[i]);
offsets_.push_back (idx != wantedArgs.size() ? offsets[idx] : 0);
}
}
2012-05-28 12:32:15 +01:00
MapIndexer& 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
{
assert (valid());
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-28 12:32:15 +01:00
friend std::ostream& operator<< (std::ostream&, const MapIndexer&);
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&
2012-05-28 12:32:15 +01:00
operator<< (std::ostream &os, const MapIndexer& indexer)
2012-05-25 20:15:05 +01:00
{
os << "(" ;
os << std::setw (2) << std::setfill('0') << indexer.index_;
2012-05-25 20:15:05 +01:00
os << ") " ;
os << indexer.indices_;
2012-05-25 20:15:05 +01:00
return os;
}
#endif // HORUS_INDEXER_H
2012-05-23 14:56:01 +01:00