-
Notifications
You must be signed in to change notification settings - Fork 56
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
the Bristolian #316
Merged
Merged
the Bristolian #316
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
656f0fb
pasting in the functions, writing some docstrings@
jakeffbulmer 106b37b
added tests
jakeffbulmer 822f6fd
running black
jakeffbulmer c736f55
update changelog
jakeffbulmer a831697
pragma no cover on jitted functions
jakeffbulmer b99640c
attempt to make codefactor happy
jakeffbulmer e1b7b12
run black
jakeffbulmer 1cf3635
fix bug nico found and add new test
jakeffbulmer c7ed6ec
remove unused variable
jakeffbulmer 09a0233
remove sqrtm when input pattern is a bitstring
jakeffbulmer 11586b1
fix codefactor
jakeffbulmer 48143b4
new test for bunched inputs and normalised probability distributions
jakeffbulmer b486236
add to autosummary
jakeffbulmer 03c7345
change assert to raise value error and add tests
jakeffbulmer a009d4c
add test docstring
jakeffbulmer ee80c9c
Adds contributors name
21c87d0
remove permanent of empty matrix from bristolian loop
jakeffbulmer 019e715
simply E construction for bristolian
jakeffbulmer 3499462
Update thewalrus/_permanent.py
jakeffbulmer bb8de1d
Merge branch 'master' into bristolian
nquesada 6a7c1a6
Passes black
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,12 +13,19 @@ | |
# limitations under the License. | ||
"""Tests for the Python permanent wrapper function""" | ||
# pylint: disable=no-self-use | ||
|
||
from itertools import chain, product | ||
|
||
import pytest | ||
|
||
import numpy as np | ||
|
||
from scipy.special import factorial as fac | ||
from scipy.linalg import sqrtm | ||
from scipy.stats import unitary_group | ||
|
||
from thewalrus import perm, permanent_repeated | ||
from thewalrus import perm, permanent_repeated, brs, ubrs | ||
from thewalrus._permanent import fock_prob, fock_threshold_prob | ||
|
||
perm_real = perm | ||
perm_complex = perm | ||
|
@@ -181,3 +188,185 @@ def test_ones(self, n): | |
A = np.array([[1]]) | ||
p = permanent_repeated(A, [n]) | ||
assert np.allclose(p, fac(n)) | ||
|
||
|
||
Comment on lines
+191
to
+192
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests are really great. Fantastic work @jakeffbulmer ! |
||
def test_brs_HOM(): | ||
"""HOM test""" | ||
|
||
U = np.array([[1, 1], [1, -1]]) / np.sqrt(2) | ||
|
||
n = [1, 1] | ||
d = [1, 1] | ||
|
||
assert np.isclose(fock_threshold_prob(n, d, U), fock_prob(n, d, U)) | ||
|
||
d = [1, 0] | ||
m = [2, 0] | ||
|
||
assert np.isclose(fock_threshold_prob(n, d, U), fock_prob(n, m, U)) | ||
|
||
|
||
@pytest.mark.parametrize("eta", [0.2, 0.5, 0.9, 1]) | ||
def test_brs_HOM_lossy(eta): | ||
"""lossy HOM dip test""" | ||
T = np.sqrt(eta / 2) * np.array([[1, 1], [1, -1]]) | ||
|
||
n = [1, 1] | ||
d = [1, 1] | ||
|
||
assert np.isclose(fock_prob(n, d, T), fock_threshold_prob(n, d, T)) | ||
|
||
|
||
def test_brs_ZTL(): | ||
"""test 3-mode ZTL suppression""" | ||
|
||
U = np.fft.fft(np.eye(3)) / np.sqrt(3) | ||
|
||
n = [1, 1, 1] | ||
d = [1, 1, 0] | ||
|
||
p1 = fock_threshold_prob(n, d, U) | ||
p2 = fock_prob(n, [1, 2, 0], U) + fock_prob(n, [2, 1, 0], U) | ||
assert np.isclose(p1, p2) | ||
|
||
n = [1, 1, 1] | ||
d = [1, 1, 1] | ||
|
||
p1 = fock_threshold_prob(n, d, U) | ||
p2 = fock_prob(n, d, U) | ||
assert np.isclose(p1, p2) | ||
|
||
T = U[:2, :] | ||
d = [1, 1] | ||
|
||
p1 = fock_threshold_prob(n, d, T) | ||
p2 = fock_prob(n, [1, 1, 1], U) | ||
|
||
assert np.isclose(p1, p2) | ||
|
||
d = [1, 0, 0] | ||
|
||
p1 = fock_threshold_prob(n, d, U) | ||
p2 = fock_prob(n, [3, 0, 0], U) | ||
|
||
assert np.isclose(p1, p2) | ||
|
||
n = [1, 2, 0] | ||
d = [0, 1, 1] | ||
|
||
p1 = fock_threshold_prob(n, d, U) | ||
p2 = fock_prob(n, [0, 2, 1], U) + fock_prob(n, [0, 1, 2], U) | ||
|
||
assert np.isclose(p1, p2) | ||
|
||
|
||
@pytest.mark.parametrize("eta", [0.2, 0.5, 0.9, 1]) | ||
def test_brs_ZTL_lossy(eta): | ||
"""test lossy 3-mode ZTL suppression""" | ||
T = np.sqrt(eta) * np.fft.fft(np.eye(3)) / np.sqrt(3) | ||
|
||
n = [1, 1, 1] | ||
d = [1, 1, 0] | ||
|
||
p1 = eta**2 * (1 - eta) / 3 | ||
p2 = fock_threshold_prob(n, d, T) | ||
|
||
assert np.allclose(p1, p2) | ||
|
||
|
||
@pytest.mark.parametrize("d", [[1, 1, 1], [1, 1, 0], [1, 0, 0]]) | ||
def test_brs_ubrs(d): | ||
"""test that brs and ubrs give same results for unitary transformation""" | ||
|
||
U = np.fft.fft(np.eye(3)) / np.sqrt(3) | ||
|
||
n = np.array([2, 1, 0]) | ||
d = np.array(d) | ||
|
||
in_modes = np.array(list(chain(*[[i] * j for i, j in enumerate(n) if j > 0]))) | ||
click_modes = np.where(d > 0)[0] | ||
|
||
U_dn = U[np.ix_(click_modes, in_modes)] | ||
|
||
b1 = ubrs(U_dn) | ||
|
||
R = sqrtm(np.eye(U.shape[1]) - U.conj().T @ U)[:, in_modes] | ||
E = R.conj().T @ R | ||
|
||
b2 = brs(U_dn, E) | ||
|
||
assert np.allclose(b1, b2) | ||
|
||
|
||
@pytest.mark.parametrize("M", range(2, 7)) | ||
def test_brs_random(M): | ||
"""test that brs and per agree for random matices""" | ||
|
||
n = np.ones(M, dtype=int) | ||
n[np.random.randint(0, M)] = 0 | ||
d = np.ones(M, dtype=int) | ||
d[np.random.randint(0, M)] = 0 | ||
|
||
loss_in = np.random.random(M) | ||
loss_out = np.random.random(M) | ||
U = unitary_group.rvs(M) | ||
T = np.diag(loss_in) @ U @ np.diag(loss_out) | ||
|
||
p1 = fock_threshold_prob(n, d, T) | ||
p2 = fock_prob(n, d, T) | ||
|
||
assert np.isclose(p1, p2) | ||
|
||
|
||
@pytest.mark.parametrize("M", range(2, 5)) | ||
def test_brs_prob_normed(M): | ||
"""test that fock threshold probability is normalised""" | ||
|
||
N = M + 1 # guarentee at least some bunching | ||
|
||
in_modes = np.random.choice(np.arange(M), N) | ||
n = np.bincount(in_modes, minlength=M) | ||
|
||
loss_in = np.random.random(M) | ||
loss_out = np.random.random(M) | ||
U = unitary_group.rvs(M) | ||
T = np.diag(loss_in) @ U @ np.diag(loss_out) | ||
|
||
p_total = 0 | ||
for det_pattern in product([0, 1], repeat=M): | ||
p = fock_threshold_prob(n, det_pattern, T) | ||
p_total += p | ||
|
||
assert np.isclose(p_total, 1) | ||
|
||
|
||
def test_fock_thresh_valueerror(): | ||
"""test that input checks are raised""" | ||
with pytest.raises(ValueError): | ||
n = [1, 1, 1] | ||
T = np.ones((2, 2)) | ||
d = [1, 1] | ||
fock_threshold_prob(n, d, T) | ||
|
||
with pytest.raises(ValueError): | ||
n = [1, 1] | ||
d = [1, 1, 1] | ||
T = np.ones((2, 2)) | ||
fock_threshold_prob(n, d, T) | ||
|
||
with pytest.raises(ValueError): | ||
n = [1, 1] | ||
d = [1, 1, 1] | ||
T = np.ones((3, 2)) | ||
fock_threshold_prob(n, d, T) | ||
|
||
|
||
def test_fock_prob_valueerror(): | ||
"""test that input checks are raised""" | ||
with pytest.raises(ValueError): | ||
n = [1, 1, 2, 1] | ||
m = [1, 1, 1, 3] | ||
|
||
U = np.eye((4)) | ||
|
||
fock_prob(n, m, U) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
@jakeffbulmer : you probably want to add
brs
andubrs
into the__all__
list in line 132There 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.
and also into the autosummary in line 78. This is so that they are included when the documentation is generated.