Skip to content

Commit 8f4622a

Browse files
authored
Merge pull request #1371 from arcondello/faster-remove-interactions
Add QuadraticModelBase::remove_interactions() method
2 parents 63d4629 + 011cbb6 commit 8f4622a

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

dimod/include/dimod/abc.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,12 @@ class QuadraticModelBase {
331331
/// Remove the interaction between variables `u` and `v`.
332332
bool remove_interaction(index_type u, index_type v);
333333

334+
/// Remove all interactions for which `filter` returns `true`.
335+
/// Returns the number of interactions removed.
336+
/// `filter` must be symmetric. That is `filter(u, v, bias)` must equal `filter(v, u, bias)`.
337+
template<class Filter>
338+
size_type remove_interactions(Filter filter);
339+
334340
/**
335341
* Remove variable `v` from the model.
336342
*
@@ -889,6 +895,35 @@ bool QuadraticModelBase<bias_type, index_type>::remove_interaction(index_type u,
889895
return false;
890896
}
891897

898+
template <class bias_type, class index_type>
899+
template <class Filter>
900+
std::size_t QuadraticModelBase<bias_type, index_type>::remove_interactions(Filter filter) {
901+
if (!has_adj()) return 0; // nothing to filter
902+
903+
std::size_t num_removed = 0;
904+
905+
index_type u = 0;
906+
for (auto& n : *adj_ptr_) {
907+
auto it = std::remove_if(n.begin(), n.end(),
908+
[&u, &filter](const OneVarTerm<bias_type, index_type>& term) {
909+
const index_type& v = term.v;
910+
const bias_type& bias = term.bias;
911+
assert(filter(u, v, bias) == filter(v, u, bias));
912+
return filter(u, v, bias);
913+
});
914+
915+
num_removed += n.end() - it;
916+
917+
n.erase(it, n.end());
918+
919+
u += 1;
920+
}
921+
922+
assert(num_removed % 2 == 0);
923+
924+
return num_removed / 2;
925+
}
926+
892927
template <class bias_type, class index_type>
893928
void QuadraticModelBase<bias_type, index_type>::remove_variable(index_type v) {
894929
assert(0 <= v && static_cast<size_type>(v) < num_variables());
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
features:
3+
- |
4+
Add C++ ``QuadraticModelBase::remove_interactions()`` method.

testscpp/tests/test_quadratic_model.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,4 +546,26 @@ SCENARIO("quadratic models can be swapped", "[qm]") {
546546
}
547547
}
548548
}
549+
550+
SCENARIO("quadratic models can have their interactions filtered") {
551+
GIVEN("a binary quadratic model") {
552+
auto bqm = dimod::BinaryQuadraticModel<double>(5, dimod::Vartype::BINARY);
553+
bqm.add_quadratic(0, 1, 1.5);
554+
bqm.add_quadratic(1, 2, 2.5);
555+
bqm.add_quadratic(2, 3, 3.5);
556+
557+
WHEN("We filter all interactions with variable 1") {
558+
CHECK(bqm.remove_interactions([](int u, int v, double) { return u == 1 || v == 1; }) ==
559+
2);
560+
561+
CHECK(bqm.quadratic(0, 1) == 0);
562+
CHECK(bqm.quadratic(1, 2) == 0);
563+
CHECK(bqm.quadratic(2, 3) == 3.5);
564+
565+
CHECK(bqm.quadratic(1, 0) == 0);
566+
CHECK(bqm.quadratic(2, 1) == 0);
567+
CHECK(bqm.quadratic(3, 2) == 3.5);
568+
}
569+
}
570+
}
549571
} // namespace dimod

0 commit comments

Comments
 (0)