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

Adds tests for decomposed frontend gates #173

Merged
merged 18 commits into from
Sep 18, 2019
Merged

Adds tests for decomposed frontend gates #173

merged 18 commits into from
Sep 18, 2019

Conversation

nquesada
Copy link
Collaborator

Context:
Several useful Gaussian gates can be decomposed in terms of beamsplitters and single mode squeezing gates. This PR creates tests that explicitly check that these decompositions are correct
Description of the Change:
Adds new test class TestDecompositionsGaussianGates
Benefits:
Explicit testing for the decompositions derived in the documentation
Possible Drawbacks:

Related GitHub Issues:
#171

@nquesada nquesada requested review from co9olguy and josh146 and removed request for co9olguy August 23, 2019 21:02
Copy link
Member

@josh146 josh146 left a comment

Choose a reason for hiding this comment

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

Great tests @nquesada! Just some minor comments

@@ -1,3 +1,5 @@
* Adds new integration tests for the Gaussian gates that are not primitive, i.e. P, CX, CZ, and S2. Addresses issue [#171](https://github.com/XanaduAI/strawberryfields/issues/171)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Adds new integration tests for the Gaussian gates that are not primitive, i.e. P, CX, CZ, and S2. Addresses issue [#171](https://github.com/XanaduAI/strawberryfields/issues/171)
* Adds new integration tests for the Gaussian gates that are not primitive, i.e. P, CX, CZ, and S2. Addresses issue
[#171](https://github.com/XanaduAI/strawberryfields/issues/171)

Copy link
Member

Choose a reason for hiding this comment

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

Also, this should be moved down the changelog to within the # Release 0.12.0-dev section. Probably under a new subsection ### Improvements.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, @josh146 . I need to learn some CHANGELOG etiquette :)

strawberryfields/ops.py Outdated Show resolved Hide resolved
Vexpected = 0.5 * hbar * Pmat @ np.diag(np.exp([-2 * r, 2 * r])) @ Pmat.T
assert np.allclose(Vexpected, state.cov())
rexpected = Pmat @ np.array([x1, p1])
assert np.allclose(rexpected, state.means())
Copy link
Member

Choose a reason for hiding this comment

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

Should atol=tol and rtol=0 be added to these np.allclose() calls? Especially since tol is being included in the test signature.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes! Will add it.

r = 3
x1 = 2
p1 = 1.3
s = 0.5 * 0
Copy link
Member

Choose a reason for hiding this comment

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

Should this be s = 0.5? Otherwise it looks like this is just testing that Pgate(0) acts as the identity

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes! Should check again that it works

assert np.allclose(state.cov(), Vexpected, atol=tol)
rexpected = CXmat @ np.array([x1, x2, p1, p2])
# Checks the means are transformed correctly
assert np.allclose(state.means(), rexpected, atol=tol)
Copy link
Member

Choose a reason for hiding this comment

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

Missing rtol=0? By default, I think np.allclose() included a non-zero relative tolerance

np.exp(1j * phi) * np.sqrt((nbar / (1 + nbar)))
) ** (list(range(n)))
diag_elems[-1] = 0
assert np.allclose(np.diag(diag_elems), ket, atol=0.2)
Copy link
Member

Choose a reason for hiding this comment

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

rtol=0?

assert np.allclose(state.cov(), Vexpected, atol=tol)
rexpected = CZmat @ np.array([x1, x2, p1, p2])
# Checks the means are transformed correctly
assert np.allclose(state.means(), rexpected, atol=tol)
Copy link
Member

Choose a reason for hiding this comment

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

rtol=0?

eng, prog = setup_eng(N)
nbar = 1
s = np.arcsinh(np.sqrt(1.0))
phi = 0 * np.pi / 3
Copy link
Member

Choose a reason for hiding this comment

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

Should phi be zero?

n, _ = ket.shape
diag_elems = (1 / np.sqrt(1 + nbar)) * (
np.exp(1j * phi) * np.sqrt((nbar / (1 + nbar)))
) ** (list(range(n)))
Copy link
Member

Choose a reason for hiding this comment

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

I'm a bit confused why this line works; the LHS of the ** should be a Python float, while the RHS is a list - how come it evaluates as a NumPy array?

Copy link
Member

Choose a reason for hiding this comment

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

Oh, it's because the LHS is of type np.float64.

Maybe it's worth being a bit explicit, and having the exponent be np.arange(n) instead of list(range(n))

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Cool! Will do. To be honest I was not sure why it worked.

Copy link
Collaborator Author

@nquesada nquesada left a comment

Choose a reason for hiding this comment

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

Thanks for the thorough review @josh146 !

@codecov
Copy link

codecov bot commented Aug 26, 2019

Codecov Report

❗ No coverage uploaded for pull request base (master@d75a078). Click here to learn what that means.
The diff coverage is n/a.

@@            Coverage Diff            @@
##             master     #173   +/-   ##
=========================================
  Coverage          ?   97.05%           
=========================================
  Files             ?       43           
  Lines             ?     5398           
  Branches          ?        0           
=========================================
  Hits              ?     5239           
  Misses            ?      159           
  Partials          ?        0

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d75a078...26ccb52. Read the comment docs.

@codecov
Copy link

codecov bot commented Aug 26, 2019

Codecov Report

❗ No coverage uploaded for pull request base (master@d75a078). Click here to learn what that means.
The diff coverage is n/a.

@@            Coverage Diff            @@
##             master     #173   +/-   ##
=========================================
  Coverage          ?   97.21%           
=========================================
  Files             ?       40           
  Lines             ?     5273           
  Branches          ?        0           
=========================================
  Hits              ?     5126           
  Misses            ?      147           
  Partials          ?        0
Impacted Files Coverage Δ
strawberryfields/ops.py 98.37% <ø> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d75a078...aebcfe2. Read the comment docs.

nquesada and others added 2 commits August 26, 2019 09:51
Co-Authored-By: Josh Izaac <josh146@gmail.com>
@nquesada nquesada requested a review from smite August 26, 2019 13:54
Copy link
Member

@co9olguy co9olguy left a comment

Choose a reason for hiding this comment

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

I have some questions about these tests to resolve before merging

.github/CHANGELOG.md Outdated Show resolved Hide resolved
tests/integration/test_decompositions_integration.py Outdated Show resolved Hide resolved
@josh146 josh146 added the tests label Aug 31, 2019
@nquesada
Copy link
Collaborator Author

@co9olguy . I agree with Josh. We could add extra tests to check that the gates are applied in the right order by for instance applying the decomposition we have found and then apply the gate backwards and check that effectively we just applied the identity. However, the spirit of these tests was to check that the operations do what they are supposed to do, for example that the P gate takes x-> x and p-> p+ s x.

@josh146 josh146 changed the title New tests Adds tests for decomposed frontend gates Sep 10, 2019
@co9olguy
Copy link
Member

@co9olguy . I agree with Josh. We could add extra tests to check that the gates are applied in the right order by for instance applying the decomposition we have found and then apply the gate backwards and check that effectively we just applied the identity. However, the spirit of these tests was to check that the operations do what they are supposed to do, for example that the P gate takes x-> x and p-> p+ s x.

@nquesada sounds good. I'm happy to leave these tests, which are more concrete (but less amenable to verifying all backends). We should also add the other suggested abstract test strategy (confirm that gates match their decomposing by reversing the arguments and concatenating) before merging.

@nquesada
Copy link
Collaborator Author

I think this PR could be merged now. We could make an issue to be addressed in a future PR to check that the gates are applied in the right order and that the "compiled" gate applied backwards reverses them.

@co9olguy
Copy link
Member

I'm concerned that a magic number tolerance might be masking a possible numerical error. I've set tests to run on default tolerance and observed failures even for cutoff as high as 30 dimensions

@co9olguy
Copy link
Member

Update: cutoff of 35 seems to pass with default tolerance

tests/integration/test_decompositions_integration.py Outdated Show resolved Hide resolved
tests/integration/test_decompositions_integration.py Outdated Show resolved Hide resolved
@co9olguy
Copy link
Member

@josh146 I'm inclined to drop the failing test, since the numerics are too sensitive. I've added a secondary test for that gate as well, so we can have some confidence

@josh146
Copy link
Member

josh146 commented Sep 14, 2019

I'm happy with that, cutoff of 35 is way too high, and the squeezing is almost vacuum to get it to pass with a cutoff of 5.

@co9olguy
Copy link
Member

@josh146 Ok I removed it. If tests pass, good to merge

@josh146 josh146 merged commit 65a517e into master Sep 18, 2019
@josh146 josh146 deleted the new_tests branch September 18, 2019 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants