Skip to content

Commit

Permalink
Merge pull request #1288 from arcondello/fix/removed-cqm-methods
Browse files Browse the repository at this point in the history
Restore some removed methods for CQM manipulation
  • Loading branch information
arcondello authored Nov 10, 2022
2 parents f87d455 + 87cbe24 commit 3d0c26f
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 25 deletions.
25 changes: 0 additions & 25 deletions dimod/binary/binary_quadratic_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,28 +801,6 @@ def add_linear_inequality_constraint(
lagrange_multiplier, -ub_c)
return slack_terms

def add_linear_from(self, linear: Union[Iterable, Mapping]):
"""Add variables and linear biases to a binary quadratic model.
Args:
linear:
Variables and their associated linear biases, as either a dict of
form ``{v: bias, ...}`` or an iterable of ``(v, bias)`` pairs,
where ``v`` is a variable and ``bias`` is its associated linear
bias.
"""
if isinstance(linear, abc.Mapping):
iterator = linear.items()
elif isinstance(linear, abc.Iterable):
iterator = linear
else:
raise TypeError(
"expected 'linear' to be a dict or an iterable of 2-tuples.")

for v, bias in iterator:
self.add_linear(v, bias)

def add_linear_from_array(self, linear: Sequence):
"""Add linear biases from an array-like to a binary quadratic model.
Expand All @@ -848,9 +826,6 @@ def add_linear_from_array(self, linear: Sequence):

self.data.add_linear_from_array(np.asarray(ldata))

add_variables_from = add_linear_from
"""Alias for :meth:`add_linear_from`."""

def add_offset(self, bias):
"""Add offset to to the model.
Expand Down
8 changes: 8 additions & 0 deletions dimod/constrained/cyexpression.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ cdef class _cyExpression:
def offset(self):
return as_numpy_float(self.expression().offset())

@offset.setter
def offset(self, bias_type offset):
self.expression().set_offset(offset)

@property
def variables(self):
# we could do yet another view, but that way lies madness
Expand Down Expand Up @@ -102,6 +106,10 @@ cdef class _cyExpression:

self.expression().add_quadratic(ui, vi, bias)

def add_variable(self, *args, **kwargs):
"""Add a variable to the model. See :meth:`ConstrainedQuadraticModel.add_variable()`."""
return self.parent.add_variable(*args, **kwargs)

def degree(self, v):
return self.expression().degree(self.parent.variables.index(v))

Expand Down
26 changes: 26 additions & 0 deletions dimod/views/quadratic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

import abc
import collections.abc
import io
import operator

Expand Down Expand Up @@ -400,6 +401,31 @@ def set_linear(self, v: Variable, bias: Bias):
def set_quadratic(self, u: Variable, v: Variable, bias: Bias):
raise NotImplementedError

def add_linear_from(self, linear: Union[Iterable, Mapping]):
"""Add variables and linear biases to a binary quadratic model.
Args:
linear:
Variables and their associated linear biases, as either a dict of
form ``{v: bias, ...}`` or an iterable of ``(v, bias)`` pairs,
where ``v`` is a variable and ``bias`` is its associated linear
bias.
"""
if isinstance(linear, collections.abc.Mapping):
iterator = linear.items()
elif isinstance(linear, collections.abc.Iterable):
iterator = linear
else:
raise TypeError(
"expected 'linear' to be a dict or an iterable of 2-tuples.")

for v, bias in iterator:
self.add_linear(v, bias)

add_variables_from = add_linear_from
"""Alias for :meth:`add_linear_from`."""

def fix_variable(self, v: Variable, value: float):
"""Remove a variable by fixing its value.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
fixes:
- |
Add the ability to set offsets on ``ObjectiveView`` and ``ConstraintView``.
This was previously removed in dimod 0.12.0.
See `#1287 <https://github.com/dwavesystems/dimod/issues/1287>`_
- |
Add ``ObjectiveView.add_linear_from()`` and ``ConstraintView.add_linear_from()`` methods.
These were previously removed in dimod 0.12.0.
- |
Add ``ObjectiveView.add_variable()`` and ``ConstraintView.add_variable()`` methods.
These were previously removed in dimod 0.12.0.
40 changes: 40 additions & 0 deletions tests/test_constrained.py
Original file line number Diff line number Diff line change
Expand Up @@ -1653,6 +1653,36 @@ def test_list_length_limiting(self):


class TestViews(unittest.TestCase):
def test_add_linear(self):
x, y = dimod.Binaries('xy')
cqm = dimod.CQM()
lbl1 = cqm.add_constraint(x + y <= 1)
lbl2 = cqm.add_constraint(x == 1)

cqm.constraints[lbl2].lhs.set_linear('y', 3)
self.assertEqual(cqm.constraints[lbl2].lhs.linear, {'x': 1, 'y': 3})

def test_add_linear_from(self):
x, y = dimod.Binaries('xy')
cqm = dimod.CQM()
lbl = cqm.add_constraint(x + y <= 1)

cqm.objective.add_linear_from([('x', 3)])

self.assertEqual(cqm.objective.linear, {'x': 3})

def test_add_variable(self):
x, y = dimod.Binaries('xy')
cqm = dimod.CQM()
lbl = cqm.add_constraint(x == 1)
cqm.constraints[lbl].lhs.add_variable(dimod.BINARY, 'y')
self.assertIn('y', cqm.variables)
cqm.constraints[lbl].lhs.add_variable(dimod.INTEGER, 'i', lower_bound=-5, upper_bound=10)
self.assertIn('i', cqm.variables)
self.assertEqual(cqm.vartype('i'), dimod.INTEGER)
self.assertEqual(cqm.lower_bound('i'), -5)
self.assertEqual(cqm.upper_bound('i'), 10)

def test_objective(self):
cqm = dimod.CQM()

Expand Down Expand Up @@ -1686,6 +1716,16 @@ def test_constraint_energies(self):
self.assertEqual(cqm.constraints[c1].lhs.energy({'a': 1, 'b': 1}), 1)
self.assertEqual(cqm.constraints[c1].lhs.energy({'a': 0, 'b': 0}), 0)

def test_offset(self):
x, y = dimod.Binaries('xy')
cqm = dimod.CQM()
lbl = cqm.add_constraint(x + y <= 1)

cqm.objective.offset = 5
self.assertEqual(cqm.objective.offset, 5)
cqm.constraints[lbl].lhs.offset = 3
self.assertEqual(cqm.constraints[lbl].lhs.offset, 3)

def test_serialization_helpers(self):
a, c = dimod.Binaries('ac')
b = dimod.Integer('b', upper_bound=5)
Expand Down

0 comments on commit 3d0c26f

Please sign in to comment.