Skip to content

Commit

Permalink
Refactor neighborhood to use vector-or-pairs rather than pair-of-vectors
Browse files Browse the repository at this point in the history
Closes #1025
  • Loading branch information
arcondello committed Mar 15, 2022
1 parent dc9607d commit d21b897
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 398 deletions.
308 changes: 0 additions & 308 deletions dimod/include/dimod/iterators.h
Expand Up @@ -18,317 +18,9 @@

namespace dimod {

template <class Bias, class Index>
class Neighborhood;

template <class Bias, class Index>
class QuadraticModelBase;

template <class Bias, class Index>
class NeighborhoodIterator {
public:
using bias_type = Bias;
using index_type = Index;
using neighborhood_type = Neighborhood<Bias, Index>;

using value_type = std::pair<const index_type&, bias_type&>;
using pointer = value_type*;
using reference = value_type&;
using difference_type = std::ptrdiff_t;
using iterator_category = std::random_access_iterator_tag;

// empty constructor needed for Cython
NeighborhoodIterator()
: neighborhood_ptr_(nullptr), i_(0), pair_ptr_(nullptr) {}

// for the copy constructor, we want to copy the pointer to the
// neighborhood, but not to the pair_ptr_, since that's managed by each
// iterator separately
NeighborhoodIterator(const NeighborhoodIterator<Bias, Index>& other)
: neighborhood_ptr_(other.neighborhood_ptr_),
i_(other.i_),
pair_ptr_(nullptr) {
update_pair();
}

// for the move constructor, we want to move everything
NeighborhoodIterator(NeighborhoodIterator<Bias, Index>&& other) noexcept
: neighborhood_ptr_(nullptr), i_(0), pair_ptr_(nullptr) {
swap(other);
}

NeighborhoodIterator(neighborhood_type* neighborhood, index_type i)
: neighborhood_ptr_(neighborhood), i_(i), pair_ptr_(nullptr) {
update_pair();
}

~NeighborhoodIterator() { delete pair_ptr_; }

NeighborhoodIterator<Bias, Index>& operator=(
NeighborhoodIterator<Bias, Index> const& other) {
if (this != &other) {
neighborhood_ptr_ = other.neighborhood_ptr_;
i_ = other.i_;
update_pair(); // handles pair_ptr_
}
return *this;
}

NeighborhoodIterator<Bias, Index>& operator=(
NeighborhoodIterator<Bias, Index>&& other) noexcept {
swap(other);
return *this;
}

reference operator*() { return *pair_ptr_; }

pointer operator->() { return pair_ptr_; }

NeighborhoodIterator<Bias, Index>& operator++() {
++i_;
update_pair();
return *this;
}
NeighborhoodIterator<Bias, Index>& operator--() {
--i_;
update_pair();
return *this;
}
NeighborhoodIterator<Bias, Index> operator++(int) {
NeighborhoodIterator<Bias, Index> r(*this);
++i_;
update_pair();
return r;
}
NeighborhoodIterator<Bias, Index> operator--(int) {
NeighborhoodIterator<Bias, Index> r(*this);
--i_;
update_pair();
return r;
}

NeighborhoodIterator<Bias, Index>& operator+=(int n) {
i_ += n;
update_pair();
return *this;
}
NeighborhoodIterator<Bias, Index>& operator-=(int n) {
i_ -= n;
update_pair();
return *this;
}

NeighborhoodIterator<Bias, Index> operator+(int n) const {
NeighborhoodIterator<Bias, Index> r(*this);
return r += n;
}
NeighborhoodIterator<Bias, Index> operator-(int n) const {
NeighborhoodIterator<Bias, Index> r(*this);
return r -= n;
}

difference_type operator-(
NeighborhoodIterator<Bias, Index> const& r) const {
return i_ - r.i_;
}

bool operator<(NeighborhoodIterator<Bias, Index> const& r) const {
return i_ < r.i_;
}
bool operator<=(NeighborhoodIterator<Bias, Index> const& r) const {
return i_ <= r.i_;
}
bool operator>(NeighborhoodIterator<Bias, Index> const& r) const {
return i_ > r.i_;
}
bool operator>=(NeighborhoodIterator<Bias, Index> const& r) const {
return i_ >= r.i_;
}
bool operator!=(const NeighborhoodIterator<Bias, Index>& r) const {
return i_ != r.i_;
}
bool operator==(const NeighborhoodIterator<Bias, Index>& r) const {
return i_ == r.i_;
}

private:
neighborhood_type* neighborhood_ptr_;
index_type i_;

value_type* pair_ptr_;

void update_pair() {
if (pair_ptr_) {
delete pair_ptr_;
pair_ptr_ = nullptr;
}
if (i_ >= 0 && i_ < (index_type)neighborhood_ptr_->size()) {
pair_ptr_ = new value_type(neighborhood_ptr_->neighbors[i_],
neighborhood_ptr_->quadratic_biases[i_]);
}
}

void swap(NeighborhoodIterator<Bias, Index>& other) noexcept {
std::swap(neighborhood_ptr_, other.neighborhood_ptr_);
std::swap(i_, other.i_);
std::swap(pair_ptr_, other.pair_ptr_);
}
};

template <class Bias, class Index>
class ConstNeighborhoodIterator {
public:
using bias_type = Bias;
using index_type = Index;
using neighborhood_type = Neighborhood<Bias, Index>;

using value_type = std::pair<const index_type&, const bias_type&>;
using pointer = value_type*;
using reference = value_type&;
using difference_type = std::ptrdiff_t;
using iterator_category = std::random_access_iterator_tag;

// empty constructor needed for Cython
ConstNeighborhoodIterator()
: neighborhood_ptr_(nullptr), i_(0), pair_ptr_(nullptr) {}

// for the copy constructor, we want to copy the pointer to the
// neighborhood, but not to the pair_ptr_, since that's managed by each
// iterator separately
ConstNeighborhoodIterator(
const ConstNeighborhoodIterator<Bias, Index>& other)
: neighborhood_ptr_(other.neighborhood_ptr_),
i_(other.i_),
pair_ptr_(nullptr) {
update_pair();
}

// for the move constructor, we want to move everything
ConstNeighborhoodIterator(
ConstNeighborhoodIterator<Bias, Index>&& other) noexcept
: neighborhood_ptr_(nullptr), i_(0), pair_ptr_(nullptr) {
swap(other);
}

ConstNeighborhoodIterator(const neighborhood_type* neighborhood,
index_type i)
: neighborhood_ptr_(neighborhood), i_(i), pair_ptr_(nullptr) {
update_pair();
}

~ConstNeighborhoodIterator() { delete pair_ptr_; }

ConstNeighborhoodIterator<Bias, Index>& operator=(
ConstNeighborhoodIterator<Bias, Index> const& other) {
if (this != &other) {
neighborhood_ptr_ = other.neighborhood_ptr_;
i_ = other.i_;
update_pair(); // handles pair_ptr_
}
return *this;
}

ConstNeighborhoodIterator<Bias, Index>& operator=(
ConstNeighborhoodIterator<Bias, Index>&& other) noexcept {
swap(other);
return *this;
}

const reference operator*() const { return *pair_ptr_; }

const pointer operator->() const { return pair_ptr_; }

ConstNeighborhoodIterator<Bias, Index>& operator++() {
++i_;
update_pair();
return *this;
}
ConstNeighborhoodIterator<Bias, Index>& operator--() {
--i_;
update_pair();
return *this;
}
ConstNeighborhoodIterator<Bias, Index> operator++(int) {
ConstNeighborhoodIterator<Bias, Index> r(*this);
++i_;
update_pair();
return r;
}
ConstNeighborhoodIterator<Bias, Index> operator--(int) {
ConstNeighborhoodIterator<Bias, Index> r(*this);
--i_;
update_pair();
return r;
}

ConstNeighborhoodIterator<Bias, Index>& operator+=(int n) {
i_ += n;
update_pair();
return *this;
}
ConstNeighborhoodIterator<Bias, Index>& operator-=(int n) {
i_ -= n;
update_pair();
return *this;
}

ConstNeighborhoodIterator<Bias, Index> operator+(int n) const {
ConstNeighborhoodIterator<Bias, Index> r(*this);
return r += n;
}
ConstNeighborhoodIterator<Bias, Index> operator-(int n) const {
ConstNeighborhoodIterator<Bias, Index> r(*this);
return r -= n;
}

difference_type operator-(
ConstNeighborhoodIterator<Bias, Index> const& r) const {
return i_ - r.i_;
}

bool operator<(ConstNeighborhoodIterator<Bias, Index> const& r) const {
return i_ < r.i_;
}
bool operator<=(ConstNeighborhoodIterator<Bias, Index> const& r) const {
return i_ <= r.i_;
}
bool operator>(ConstNeighborhoodIterator<Bias, Index> const& r) const {
return i_ > r.i_;
}
bool operator>=(ConstNeighborhoodIterator<Bias, Index> const& r) const {
return i_ >= r.i_;
}
bool operator!=(const ConstNeighborhoodIterator<Bias, Index>& r) const {
return i_ != r.i_;
}
bool operator==(const ConstNeighborhoodIterator<Bias, Index>& r) const {
return i_ == r.i_;
}

private:
const neighborhood_type* neighborhood_ptr_;
index_type i_;

value_type* pair_ptr_;

void update_pair() {
if (pair_ptr_) {
delete pair_ptr_;
pair_ptr_ = nullptr;
}
if (i_ >= 0 && i_ < (index_type)neighborhood_ptr_->size()) {
pair_ptr_ = new value_type(neighborhood_ptr_->neighbors[i_],
neighborhood_ptr_->quadratic_biases[i_]);
}
}

void swap(ConstNeighborhoodIterator<Bias, Index>& other) noexcept {
std::swap(neighborhood_ptr_, other.neighborhood_ptr_);
std::swap(i_, other.i_);
std::swap(pair_ptr_, other.pair_ptr_);
}
};

template <class Bias, class Index>
class ConstQuadraticIterator {
public:
Expand Down

0 comments on commit d21b897

Please sign in to comment.