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
Hardware-friendly decomposition #363
Conversation
Codecov Report
@@ Coverage Diff @@
## master #363 +/- ##
=======================================
Coverage 97.77% 97.77%
=======================================
Files 52 52
Lines 6435 6435
=======================================
Hits 6292 6292
Misses 143 143 Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great @shreyapkumar! I left some comments regarding code/documentation/tests, but will leave it to @nquesada and @ishdhand for code review on the decomposition logic itself 🙂
strawberryfields/decompositions.py
Outdated
def BS_mat(theta): | ||
r"""Beam splitter matrix as implemented in hardware | ||
""" | ||
mat = np.array([[np.cos(theta), 1j*np.sin(theta)], [1j*np.sin(theta), np.cos(theta)]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, off the top of my head, the default SF beamsplitter is the following?
np.array([[np.cos(theta), -np.exp(-1j*phi)*np.sin(theta)], [np.exp(1j*phi)*np.sin(theta), np.cos(theta)]])
So isn't this the same as the default SF beamsplitter, just with phi->pi/2? Although I might be misremembering the SF default.
@shreyapkumar, by the way, CodeFactor runs some static analysis on the PR, and picked up the following issues. Running the Black formatter locally should automatically fix most of them,
and the remainder can be fixed by hand. CodeFactor found multiple issues last seen at 2fa0b43: Redefining name 'T' from outer scope (line 233)strawberryfields\decompositions.py:499 No space allowed before :
strawberryfields\decompositions.py:541 Trailing whitespacestrawberryfields\decompositions.py:493 No space allowed before :
|
Co-Authored-By: Josh Izaac <josh146@gmail.com>
strawberryfields/decompositions.py
Outdated
@@ -400,6 +400,114 @@ def mach_zehnder(m, n, internal_phase, external_phase, nmax): | |||
return BS @ Rinternal @ BS @ Rexternal | |||
|
|||
|
|||
def mach_zehnder_inv(m, n, phi_int, phi_ext, nmax): | |||
r"""The inverse of the mach_zehnder matrix.""" | |||
return np.transpose(np.conj(mach_zehnder(m, n, phi_int, phi_ext, nmax))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return np.transpose(np.conj(mach_zehnder(m, n, phi_int, phi_ext, nmax))) | |
return mach_zehnder(m, n, phi_int, phi_ext, nmax).T.conj() |
strawberryfields/decompositions.py
Outdated
localV = V | ||
(nsize, _) = localV.shape | ||
|
||
diffn = np.linalg.norm(V @ V.conj().T - np.identity(nsize)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonder if it would be good to compare closeness to the identity using np.allclose
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the test here is a bit more strict than using np.allclose
.
For example V = U + tol * np.identity(n)
fails the above test, but passes the np.allclose
for the same tolerance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, good to move this and other decompositions to np.allclose
as that is easier to read and might be faster? Do you (or @josh146) have any idea about any potential downsides?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to use allclose
if possible to keep things consistent (all the tests use the np.allclose(result, expected, atol=tol, rtol=0)
pattern
beamsplitters are multiplied together. Test passes if the product | ||
matches the drawn unitary. | ||
""" | ||
# TODO: this test currently uses the T and Ti functions used to compute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this meant to be fixed in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, this was copied from other tests. I don't really know what this todo means, so removed this from the docstrings of test_random_unitary_MZ
and test_identity_MZ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really great @shreyapkumar
Documentation and formatting changes are fixed now. Comments about this or anything else are welcome! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good @shreyapkumar, my comments are all minor, and once addressed can be merged in 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me! Thanks to Josh for the many helpful comments, which I second. Other than those, no changes from my side.
Co-Authored-By: Josh Izaac <josh146@gmail.com>
Co-Authored-By: Josh Izaac <josh146@gmail.com>
Co-Authored-By: Josh Izaac <josh146@gmail.com>
Co-Authored-By: Josh Izaac <josh146@gmail.com>
Co-Authored-By: Josh Izaac <josh146@gmail.com>
Co-Authored-By: Josh Izaac <josh146@gmail.com>
Co-Authored-By: Josh Izaac <josh146@gmail.com>
Co-Authored-By: Josh Izaac <josh146@gmail.com>
…strawberryfields into HW-friendly-decomp
Thanks so much, @josh146 for the very helpful comments! I learnt a lot :) |
@@ -375,10 +375,10 @@ def test_no_unitary(self, tol): | |||
ops.MZgate(np.pi, 0) | (q[0], q[1]) | |||
ops.MZgate(np.pi, 0) | (q[2], q[3]) | |||
ops.MZgate(np.pi, np.pi) | (q[1], q[2]) | |||
ops.MZgate(np.pi, np.pi) | (q[0], q[1]) | |||
ops.MZgate(np.pi, 0) | (q[0], q[1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, looks like this file's changes came in from some merge from upstream. Not sure what to do about it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that was me when I merged master into this branch! I noticed that this was the test that was failing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @shreyapkumar!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice PR!
@shreyapkumar, is this ready to be merged in? |
Yes, nothing more to add from my side! |
Context:
This PR attempts to remove needless complications in the code arising from the difference between how theorists define T matrices and the equivalent transformations that the chip implements.
Currently, the unitary is decomposed into Clements T matrices which are later converted to phases on the chip by
rectangular_symmetric
function. Decomposing the unitary directly into Mach Zehnder units would make the code simpler. It would also make it easier to modify the code and decompositions as planned in order to account for imperfect beamsplitters and also for power reduction, etc.Description of the Change:
MZ
matrices to eventually replaceT
matrices to now represent the units on the chip.rectangular_symmetric
by modifyingrectangular_phase_end_MZ
to directly calculate internal and external phases on chip.Possible Drawbacks: