Skip to content

Commit

Permalink
Improve the performance of removing variables from expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
arcondello committed Mar 27, 2023
1 parent 5ef7897 commit dfa7f36
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 8 deletions.
2 changes: 1 addition & 1 deletion dimod/include/dimod/abc.h
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ void QuadraticModelBase<bias_type, index_type>::fix_variable(index_type v, T ass
add_offset(assignment * linear(v));

// finally remove v
remove_variable(v);
QuadraticModelBase<bias_type, index_type>::remove_variable(v);
}

template <class bias_type, class index_type>
Expand Down
27 changes: 20 additions & 7 deletions dimod/include/dimod/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,20 @@ void Expression<bias_type, index_type>::clear() {
template <class bias_type, class index_type>
template <class T>
void Expression<bias_type, index_type>::fix_variable(index_type v, T assignment) {
throw std::logic_error("not implemented - fix_variable");
assert(v >= 0 && static_cast<size_type>(v) < parent_->num_variables());

auto vit = indices_.find(v);
if (vit == indices_.end()) return; // nothing to remove

// remove the biases
base_type::fix_variable(vit->second, assignment);

// update the indices
auto it = variables_.erase(variables_.begin() + vit->second);
indices_.erase(vit);
for (; it != variables_.end(); ++it) {
indices_[*it] -= 1;
}
}

template <class bias_type, class index_type>
Expand Down Expand Up @@ -592,19 +605,19 @@ bool Expression<bias_type, index_type>::remove_interaction(index_type u, index_t

template <class bias_type, class index_type>
void Expression<bias_type, index_type>::remove_variable(index_type v) {
assert(v >= 0 && static_cast<size_type>(v) < parent_->num_variables());

auto vit = indices_.find(v);
if (vit == indices_.end()) return; // nothing to remove

// remove the biases
base_type::remove_variable(vit->second);

// update the indices
variables_.erase(variables_.begin() + vit->second);

// indices is no longer valid, so remake
indices_.clear();
for (size_type ui = 0; ui < variables_.size(); ++ui) {
indices_[variables_[ui]] = ui;
auto it = variables_.erase(variables_.begin() + vit->second);
indices_.erase(vit);
for (; it != variables_.end(); ++it) {
indices_[*it] -= 1;
}
}

Expand Down
16 changes: 16 additions & 0 deletions dimod/include/dimod/quadratic_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ class QuadraticModel : public abc::QuadraticModelBase<Bias, Index> {
/// Change the vartype of `v`, updating the biases appropriately.
void change_vartype(Vartype vartype, index_type v);

/**
* Remove variable `v` from the model by fixing its value.
*
* Note that this causes a reindexing, where all variables above `v` have
* their index reduced by one.
*/
template <class T>
void fix_variable(index_type v, T assignment);

/// Return the lower bound on variable ``v``.
bias_type lower_bound(index_type v) const;

Expand Down Expand Up @@ -229,6 +238,13 @@ void QuadraticModel<bias_type, index_type>::change_vartype(Vartype vartype, inde
}
}

template <class bias_type, class index_type>
template <class T>
void QuadraticModel<bias_type, index_type>::fix_variable(index_type v, T assignment) {
base_type::fix_variable(v, assignment);
varinfo_.erase(varinfo_.begin() + v);
}

template <class bias_type, class index_type>
bias_type QuadraticModel<bias_type, index_type>::lower_bound(index_type v) const {
// even though v is unused, we need this to conform the the QuadraticModelBase API
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
features:
- |
Improve the performance of fixing and removing variables from constrained
quadratic model expressions.
- |
Implement the ``Expression::fix_variable()`` C++ method. Previously it would
throw ``std::logic_error("not implemented - fix_variable")``.
upgrade:
- |
Add an overload to the C++ ``QuadraticModel::remove_variable()`` method.
This is binary compatible, but it makes ``&remove_variable`` ambiguous.

0 comments on commit dfa7f36

Please sign in to comment.