Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ConstrainedQuadraticModel.add_linear_constraints() method #1307

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

arcondello
Copy link
Member

Speeds up adding linear constraints to the CQM. We get about a 10x speedup.

import time

import dimod
import numpy as np

num_variables = 1_000
num_constraints = 5_000
pnz = .25  # probability that a bias is non-zero

rng = np.random.default_rng(42)

A = rng.uniform(size=(num_constraints, num_variables))
A[A > pnz] = 0
b = rng.uniform(size=num_constraints)

####################

t = time.perf_counter()

cqm = dimod.ConstrainedQuadraticModel()
cqm.add_variables("BINARY", num_variables)

ci = 0
for rhs, lhs in zip(A, b):
    cqm.add_constraint(((v, bias) for v, bias in enumerate(rhs) if bias), '==', lhs, label=ci)
    ci += 1

print(f"old: {time.perf_counter() - t}")

old = cqm

###################

t = time.perf_counter()

cqm = dimod.ConstrainedQuadraticModel()
cqm.add_variables("BINARY", num_variables)
cqm.add_linear_constraints(A, '==', b, constraint_labels=range(num_constraints))

print(f"new: {time.perf_counter() - t}")

Gives

old: 0.6515062270009366
new: 0.07133342499946593

@arcondello arcondello added the enhancement New feature or request label Jan 27, 2023
@codecov-commenter
Copy link

Codecov Report

Merging #1307 (cc6e1e7) into main (8952fe8) will decrease coverage by 0.01%.
The diff coverage is 84.61%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

@@            Coverage Diff             @@
##             main    #1307      +/-   ##
==========================================
- Coverage   91.70%   91.69%   -0.01%     
==========================================
  Files          94       94              
  Lines       10135    10147      +12     
==========================================
+ Hits         9294     9304      +10     
- Misses        841      843       +2     
Impacted Files Coverage Δ
dimod/constrained/constrained.py 92.88% <84.61%> (-0.20%) ⬇️

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Contributor

@JoelPasvolsky JoelPasvolsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just looked at the docstring so far, I can get back to the code later if needed

):
r"""Add multiple linear constraints to the model.

Add linear constraints defined by
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Add linear constraints defined by
Add linear constraints defined by the following upper-boundary and equality conditions

to clarify ub and eq

A_{ub}x \le b_{ub}, \\
A_{eq}x = b_{eq}

where `x` is a vector of decision variables,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
where `x` is a vector of decision variables,
where :math:`x` is a vector of decision variables,

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same formatting, you only need to use :math: when you want to use latex etc.

dimod/constrained/constrained.py Outdated Show resolved Hide resolved
variable_labels: The variable labels corresponding to the columns of `A`.
If ``None``, defaults to ``range(A.shape[1])``.
constraint_labels: The labels of the constraints. Labels of additional
constraints are generated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean here something like, "Labels are generated for any unlabeled constraints"?

dimod/constrained/constrained.py Outdated Show resolved Hide resolved
Bounds
<BLANKLINE>

We can also use :class:`str`-labelled variables
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We can also use :class:`str`-labelled variables
You can also label the variables:

Is it helpful to point out that labels are strings? Would they be something else?

Copy link
Member Author

@arcondello arcondello Jan 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am distinguishing them from the int-labelled ones from before, but I can clarify the intent

Co-authored-by: Joel Pasvolsky <34041130+JoelPasvolsky@users.noreply.github.com>
Copy link
Contributor

@mhramani mhramani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, maybe useful to add something like:
`cqm.add_linear_objective(c, variable_labels=...)'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants