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

Hardware-friendly decomposition #363

Merged
merged 31 commits into from May 5, 2020

Conversation

shreyapkumar
Copy link
Collaborator

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:

  • Adds MZ matrices to eventually replace T matrices to now represent the units on the chip.
  • Removes need for function rectangular_symmetric by modifying rectangular_phase_end_MZ to directly calculate internal and external phases on chip.
  • Tests very similar to the ones already present are added.

Possible Drawbacks:

  • Doesn't match the theoretical conventions in Clements and Xanadu modular decompositions.

@shreyapkumar
Copy link
Collaborator Author

Possible reviewers could be @lneuhaus , @nquesada and/or @ishdhand

@codecov
Copy link

codecov bot commented Apr 14, 2020

Codecov Report

Merging #363 into master will not change coverage.
The diff coverage is n/a.

@@           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.

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

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.

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 Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
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)]])
Copy link
Member

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.

strawberryfields/decompositions.py Show resolved Hide resolved
strawberryfields/decompositions.py Show resolved Hide resolved
@josh146
Copy link
Member

josh146 commented Apr 14, 2020

@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,

black -l 100 strawberryfields/decompositions.py

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 :

if U[n, m] == 0 :
                ^

strawberryfields\decompositions.py:541

Trailing whitespace

strawberryfields\decompositions.py:493
strawberryfields\decompositions.py:654
strawberryfields\decompositions.py:661
strawberryfields\decompositions.py:492
strawberryfields\decompositions.py:548
strawberryfields\decompositions.py:500

No space allowed before :

if U[m, n] == 0 :
                ^

strawberryfields\decompositions.py:520

@@ -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)))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
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()

localV = V
(nsize, _) = localV.shape

diffn = np.linalg.norm(V @ V.conj().T - np.identity(nsize))
Copy link
Collaborator

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

Copy link
Collaborator Author

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.allclosefor the same tolerance.

Copy link
Collaborator Author

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?

Copy link
Member

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
Copy link
Collaborator

@nquesada nquesada Apr 17, 2020

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?

Copy link
Collaborator Author

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

Copy link
Collaborator

@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.

Looks really great @shreyapkumar

@shreyapkumar
Copy link
Collaborator Author

Documentation and formatting changes are fixed now. Comments about this or anything else are welcome!

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.

Looking good @shreyapkumar, my comments are all minor, and once addressed can be merged in 🙂

strawberryfields/decompositions.py Show resolved Hide resolved
strawberryfields/decompositions.py Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
strawberryfields/decompositions.py Outdated Show resolved Hide resolved
Copy link
Contributor

@ishdhand ishdhand left a 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.

shreyapkumar and others added 11 commits April 20, 2020 14:43
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>
@shreyapkumar
Copy link
Collaborator Author

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])
Copy link
Collaborator Author

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!

Copy link
Member

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

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.

Thanks @shreyapkumar!

Copy link
Collaborator

@lneuhaus lneuhaus left a comment

Choose a reason for hiding this comment

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

Nice PR!

@josh146
Copy link
Member

josh146 commented Apr 30, 2020

@shreyapkumar, is this ready to be merged in?

@shreyapkumar
Copy link
Collaborator Author

Yes, nothing more to add from my side!

@josh146 josh146 merged commit 2de5a0f into XanaduAI:master May 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants