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

Atom for the Von Neumann Entropy #1789

Merged
merged 14 commits into from
Jun 23, 2022
Merged

Conversation

aryamanjeendgar
Copy link
Contributor

@aryamanjeendgar aryamanjeendgar commented May 28, 2022

In this PR I add support for the Von Neumann Entropy as an Atom. The vn_entr class itself lies in cvxpy/atoms, and its respective Canonicalization method lies in cvxpy/reductions/dcp2cone/atom_canonicalizers, finally, the tests reside in cvxpy/tests/test_vn_entr.py. I chose to omit the _grad method for this PR as per @SteveDiamond's advice.

The implementation of the function itself is wrapped in the numeric procedure in vn_entr.py--- $S(\rho)=-\sum_x \lambda_x\log\lambda_x$ --- this form can be found in equation (11.40) of Neilsen & Chuang's QIC text.

The Canonicalization procedure is based off of Proposition-4 of THIS paper.

@keithbriggs
Copy link
Contributor

"it's respective Canonicalization method" should be "its respective Canonicalization method".

@rileyjmurray
Copy link
Collaborator

The failing tests seem to be for versions of Python where SCS 2.1.2 is installed, rather than SCS 3. I ran the tests on my laptop with SCS 3 and they passed, but the return code was "inaccurate" even after I increased max_iters to 500,000. So I think we'll need MOSEK for these tests to pass.

Copy link
Collaborator

@rileyjmurray rileyjmurray left a comment

Choose a reason for hiding this comment

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

@aryamanJgl here are some things to be aware of. I'm investigating other stuff and hopefully will provide more comments soon.

expect_N = np.array([[0.36787973, 0.00099987],
[0.00099987, 0.36787973]])
eps = 1e2
cons1 = N >> 0
Copy link
Collaborator

Choose a reason for hiding this comment

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

The constraint that N >> 0 is redundant, since you already declared PSD = True for N. Same comment goes for other tests.

Comment on lines 100 to 109
N = U.T@N@U
objective = cp.Maximize(vn_entr(N))
obj_pair = (objective, 1.1033501770078251)
con_pairs = [
(cons1, None),
(cons2, None),
(cons3, None)
]
var_pairs = [
(N, expect_N)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here you're reassigning N. That should cause tests to fail since expect_N is supposed to be with respect to the original variable.

eps = 1e3
cons1 = N >> 0
cons2 = N << eps*np.eye(N.shape[0])
cons3 = N[2][0] == 1e-2
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is inconsistent with expect_N.

@rileyjmurray
Copy link
Collaborator

rileyjmurray commented May 28, 2022

@aryamanJgl here is a tiny example of a test that's failing:

N = cp.Variable(shape=(2, 2), PSD=True)
constraints = [cp.trace(N) <= 1,
               N[0, 1] == -0.1,
               ]
objective = cp.Maximize(cp.vn_entr(N))
prob = cp.Problem(objective, constraints)
prob.solve(verbose=True)  # infeasible

The solver (SCS or MOSEK) says the problem is infeasible, but N = [[0.5, -0.1],[-0.1, 0.5]] is feasible (its eigenvalues are 0.4 and 0.6).

Here's another option:

N = cp.Variable(shape=(2, 2), PSD=True)
N_val = np.array([[0.6, -0.1], [-0.1, 0.4]])
constraints = [N == N_val]
objective = cp.Maximize(cp.vn_entr(N))
prob = cp.Problem(objective, constraints)
prob.solve(verbose=True)  # again, infeasible.

In fact, you can make that example even simpler by setting N_val = np.array([[0.6, 0.0], [0.0, 0.4]]).

rileyjmurray and others added 2 commits May 28, 2022 17:56
@CLAassistant
Copy link

CLAassistant commented May 29, 2022

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
2 out of 3 committers have signed the CLA.

✅ rileyjmurray
✅ aryamanJgl
❌ Riley Murray


Riley Murray seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@keithbriggs
Copy link
Contributor

Isn't this a another case where a long name is needed? vn_entr is completely cryptic. I would go for von_neumann_entropy.

@rileyjmurray
Copy link
Collaborator

Isn't this a another case where a long name is needed? vn_entr is completely cryptic. I would go for von_neumann_entropy.

That's a good point. Although I'd vote for von_neumann_entr, since basic (Shannon) entropy is just entr. In the near future we'll have a bunch of other atoms where we'll want to continue to use existing abbreviations, like quantum_rel_entr and operator_rel_entr.

@aryamanJgl if you don't object, how about you change it to von_neumann_entr?

@aryamanjeendgar
Copy link
Contributor Author

@aryamanJgl if you don't object, how about you change it to von_neumann_entr?

Yeah, that makes a lot of sense! I will change it in the next commit.

Copy link
Collaborator

@rileyjmurray rileyjmurray left a comment

Choose a reason for hiding this comment

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

Mostly looks good! The main thing that stands out is the need for documentation. The docstring for von_neumann_entr is missing, and the web docs need to be updated to mention this new atom. I also left minor comments on the tests.

cvxpy/atoms/von_neumann_entr.py Outdated Show resolved Hide resolved
cvxpy/tests/test_von_neumann_entr.py Outdated Show resolved Hide resolved
cvxpy/tests/test_von_neumann_entr.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@rileyjmurray rileyjmurray left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@rileyjmurray
Copy link
Collaborator

@SteveDiamond can you review this PR? We need to project maintainers to approve before merging, since this affects the public API.

Copy link
Collaborator

@SteveDiamond SteveDiamond left a comment

Choose a reason for hiding this comment

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

Approved subject to my comments. Also shouldn't we add it to the table of atoms?

@rileyjmurray
Copy link
Collaborator

@aryamanJgl please address my response to Steven's comment. Also, there are two things to do for the docs.

  1. von_neumann_entr isn't an elementwise atom. It should be documented here, not at doc/source/api_reference/cvxpy.atoms.elementwise.rst.
  2. Add von_neumann_entr to the table of "Scalar Functions" here.

@rileyjmurray rileyjmurray merged commit f788cce into cvxpy:master Jun 23, 2022
SteveDiamond added a commit that referenced this pull request Jun 29, 2022
* origin/master:
  Add autoflake pre-commit; remove unused variable; remove unused pass (#1756)
  [New atom] dotsort (#1803)
  Change exception type when unsupported SCIP 4.x is installed (#1807)
  Atom for the Von Neumann Entropy (#1789)
  Exclude examples from deployment (#1804)
  make upload jobs pass (#1802)
  [CI] Replace manylinux_2_24 image (#1792)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants