Skip to content

Instantly share code, notes, and snippets.

@dnbaker
Last active October 29, 2017 06:09
Show Gist options
  • Select an option

  • Save dnbaker/dea323b469a4861003ed0c95ea480cdd to your computer and use it in GitHub Desktop.

Select an option

Save dnbaker/dea323b469a4861003ed0c95ea480cdd to your computer and use it in GitHub Desktop.
PRNVector
#ifndef _PRN_VECTOR_H__
#define _PRN_VECTOR_H__
template<typename RNG>
struct UnchangedRNGDistribution {
auto operator()(RNG &rng) const {return rng();}
void reset() {} // For interface compatibility with generators with internal state.
};
template<typename RNG=std::mt19937_64, typename Distribution=UnchangedRNGDistribution<RNG>>
class PRNVector {
// Vector of random values generated
const uint64_t seed_;
[dbaker49@jhu.edu@login-node01 gfrp]$ tail -n +156 include/gfrp/compact.h
template<typename RNG>
struct UnchangedRNGDistribution {
auto operator()(RNG &rng) const {return rng();}
void reset() {} // Because RNGs such as std::normal_distribution have an internal state to reset, this is provided for interface compatibility.
};
template<typename RNG=aes::AesCtr, typename Distribution=UnchangedRNGDistribution<RNG>>
class PRNVector {
// Vector of random values generated
const uint64_t seed_;
uint64_t used_;
uint64_t size_;
RNG rng_;
Distribution dist_;
public:
using ResultType = std::decay_t<decltype(dist_(rng_))>;
private:
ResultType val_;
public:
class PRNIterator {
PRNVector<RNG, Distribution> *const ref_;
public:
auto operator*() const {return ref_->val_;}
auto &operator ++() {
inc();
return *this;
}
void inc() {
ref_->gen();
++ref_->used_;
}
void gen() {ref_->gen();}
bool operator !=(const PRNIterator &other) const {
return ref_->used_ < ref_->size_; // Doesn't even access the other iterator. Only used for `while(it < end)`.
}
PRNIterator(PRNVector<RNG, Distribution> *prn_vec): ref_(prn_vec) {}
};
template<typename... DistArgs>
PRNVector(uint64_t size, uint64_t seed=0, DistArgs &&... args):
seed_{seed}, used_{0}, size_{size}, rng_(seed_), dist_(std::forward<DistArgs>(args)...), val_(gen()) {}
auto begin() {
reset();
return PRNIterator(this);
}
ResultType gen() {return val_ = dist_(rng_);}
void reset() {
rng_.seed(seed_);
dist_.reset();
used_ = 0;
gen();
}
auto end() {
return PRNIterator(static_cast<decltype(this)>(nullptr));
}
auto end() const {
return PRNIterator(static_cast<decltype(this)>(nullptr));
}
auto size() const {return size_;}
void resize(size_t newsize) {size_ = newsize;}
};
#endif // #ifndef _PRN_VECTOR_H__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment