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

takagi fix #394

Merged
merged 12 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

### Bug fixes

* Add the calculation method of `takagi` when the matrix is diagonal.

### Documentation

### Contributors
Expand Down
9 changes: 9 additions & 0 deletions thewalrus/decompositions.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,15 @@ def takagi(A, svd_order=True):
vals, U = takagi(Amr, svd_order=svd_order)
return vals, U * np.exp(1j * phi / 2)

# If the matrix is diagonal, Takagi decomposition is easy
if np.allclose(A, np.diag(np.diag(A))):
Copy link
Collaborator

Choose a reason for hiding this comment

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

You need an rtol inside the np.allclose

d = np.diag(A)
U = np.diag(np.exp(1j * 0.5 * np.angle(d)))
l = np.abs(d)
if svd_order is False:
Copy link
Collaborator

Choose a reason for hiding this comment

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

You need to correct this. First you need to sort l and rearrange U accordingly. Then you can decide if you flip the order. As is, this will not return the takagi singular values sorted correctly.

return l[::-1], U[:, ::-1]
return l, U

u, d, v = np.linalg.svd(A)
U = u @ sqrtm((v @ np.conjugate(u)).T)
if svd_order is False:
Expand Down
8 changes: 8 additions & 0 deletions thewalrus/tests/test_decompositions.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,14 @@ def test_takagi_error():
with pytest.raises(ValueError, match="The input matrix is not square"):
takagi(A)

def test_takagi_sepcific_matrix():
RyosukeNORO marked this conversation as resolved.
Show resolved Hide resolved
"""Test the takagi decomposition works well for a specific matrix that was not deecomposed accuratelyin a previous version.
RyosukeNORO marked this conversation as resolved.
Show resolved Hide resolved
See more info in PR #393 (https://github.com/XanaduAI/thewalrus/pull/393)"""
A = np.load('test_matrix_for_takagi.npy')
Copy link
Collaborator

Choose a reason for hiding this comment

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

You should write the matrix explicitly here instead of importing it from a npy file. It is, after all, just a 3x3 matrix so it should not occupy a lof of space. If you want to minimize the space, you could write separately the real and imaginary part and the construct the matrix by summing them.

d, U = takagi(A)
assert np.allclose(A, U @ np.diag(d) @ U.T)
assert np.allclose(U @ np.conjugate(U).T, np.eye(len(U)))
assert np.all(d >= 0)

def test_real_degenerate():
"""Verify that the Takagi decomposition returns a matrix that is unitary and results in a
Expand Down
Binary file added thewalrus/tests/test_matrix_for_takagi.npy
Binary file not shown.
Loading