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

Hafnian modifications #333

Merged
merged 35 commits into from
Mar 1, 2022
Merged
Changes from 34 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
deffb88
Modify the function f to use charpoly
dleclerc33 Feb 16, 2022
3e54c1a
Replace eigs with powertrace
dleclerc33 Feb 16, 2022
cb5b595
Update hafnian
dleclerc33 Feb 16, 2022
e6a69f8
I had to commit my changes in order to use git pull
benjaminlanthier Feb 16, 2022
6c5ae15
Merge branch 'hafnian_modifications' of github.com:polyquantique/thew…
benjaminlanthier Feb 16, 2022
f172471
Added a comment to f()
JQZ1111 Feb 18, 2022
7e42ddc
Update _hafnian.py
benjaminlanthier Feb 20, 2022
c2c3999
Again, I had to commit in order to use git pull
benjaminlanthier Feb 20, 2022
3d03f66
Merge branch 'hafnian_modifications' of github.com:polyquantique/thew…
benjaminlanthier Feb 20, 2022
ddc749e
Made a few changes to f_loop_odd
JQZ1111 Feb 23, 2022
33850ab
add venv in gitignore
dleclerc33 Feb 23, 2022
52b7d50
Merge branch 'hafnian_modifications' of github.com:polyquantique/thew…
benjaminlanthier Feb 23, 2022
353e22e
f_loop_odd should work now
JQZ1111 Feb 23, 2022
c574e94
Merge branch 'hafnian_modifications' of github.com:polyquantique/thew…
benjaminlanthier Feb 23, 2022
e830ab8
Passed black on _hafnian.py
brandonpolymtl Feb 23, 2022
ed9ba33
Merge branch 'hafnian_modifications' of github.com:polyquantique/thew…
benjaminlanthier Feb 23, 2022
0f51437
Passed pylint on _hafnian.py
benjaminlanthier Feb 23, 2022
c09c264
Tried to fix the docstrings
benjaminlanthier Feb 23, 2022
7cd57c9
Merge branch 'master' into hafnian_modifications
nquesada Feb 23, 2022
2ee5bff
Merge branch 'master' into hafnian_modifications
nquesada Feb 25, 2022
8967c28
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
5f2bff5
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
8c2403b
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
2bdd2c2
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
3a0f434
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
042deaa
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
af26f3b
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
8fbf995
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
e756887
Update thewalrus/_hafnian.py
JQZ1111 Feb 27, 2022
74cf75c
Removed venv
JQZ1111 Feb 27, 2022
1663fa7
Removed unecessary rows in headers
JQZ1111 Feb 28, 2022
5e00389
Removed unecessary rows
JQZ1111 Feb 28, 2022
3605030
Merge branch 'master' into hafnian_modifications
sduquemesa Feb 28, 2022
559ef4a
Update thewalrus/_hafnian.py
nquesada Mar 1, 2022
9610392
Update thewalrus/_hafnian.py
nquesada Mar 1, 2022
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
40 changes: 17 additions & 23 deletions thewalrus/_hafnian.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from itertools import chain, combinations
import numba
import numpy as np
from thewalrus import charpoly


@numba.jit(nopython=True, cache=True)
Expand Down Expand Up @@ -180,25 +181,24 @@ def find_kept_edges(j, reps): # pragma: no cover


@numba.jit(nopython=True, cache=True)
def f(E, n): # pragma: no cover
def f(A, n): # pragma: no cover
"""Evaluate the polynomial coefficients of the function in the eigenvalue-trace formula.

Args:
E (array): eigenvalues of ``AX``
A (array): a two-dimensional matrix
n (int): number of polynomial coefficients to compute

Returns:
array: polynomial coefficients
"""
E_k = E.copy()
# Compute combinations in O(n^2log n) time
# code translated from thewalrus matlab script
count = 0
comb = np.zeros((2, n // 2 + 1), dtype=np.complex128)
comb[0, 0] = 1
powtrace = charpoly.powertrace(A, n // 2 + 1)
for i in range(1, n // 2 + 1):
factor = E_k.sum() / (2 * i)
E_k *= E
factor = powtrace[i] / (2 * i)
powfactor = 1
count = 1 - count
comb[count, :] = comb[1 - count, :]
Expand All @@ -210,11 +210,11 @@ def f(E, n): # pragma: no cover


@numba.jit(nopython=True, cache=True)
def f_loop(E, AX_S, XD_S, D_S, n): # pragma: no cover
def f_loop(AX, AX_S, XD_S, D_S, n): # pragma: no cover
"""Evaluate the polynomial coefficients of the function in the eigenvalue-trace formula.

Args:
E (array): eigenvalues of ``AX``
AX (array): two-dimensional matrix
AX_S (array): ``AX_S`` with weights given by repetitions and excluded rows removed
XD_S (array): diagonal multiplied by ``X``
D_S (array): diagonal
Expand All @@ -223,15 +223,14 @@ def f_loop(E, AX_S, XD_S, D_S, n): # pragma: no cover
Returns:
array: polynomial coefficients
"""
E_k = E.copy()
# Compute combinations in O(n^2log n) time
# code translated from thewalrus matlab script
count = 0
comb = np.zeros((2, n // 2 + 1), dtype=np.complex128)
comb[0, 0] = 1
powtrace = charpoly.powertrace(AX, n // 2 + 1)
for i in range(1, n // 2 + 1):
factor = E_k.sum() / (2 * i) + (XD_S @ D_S) / 2
E_k *= E
factor = powtrace[i] / (2 * i) + (XD_S @ D_S) / 2
XD_S = XD_S @ AX_S
powfactor = 1
count = 1 - count
Expand All @@ -245,12 +244,12 @@ def f_loop(E, AX_S, XD_S, D_S, n): # pragma: no cover

# pylint: disable = too-many-arguments
@numba.jit(nopython=True, cache=True)
def f_loop_odd(E, AX_S, XD_S, D_S, n, oddloop, oddVX_S): # pragma: no cover
def f_loop_odd(AX, AX_S, XD_S, D_S, n, oddloop, oddVX_S): # pragma: no cover
"""Evaluate the polynomial coefficients of the function in the eigenvalue-trace formula
when there is a self-edge in the fixed perfect matching.

Args:
E (array): eigenvalues of ``AX``
AX (array): two-dimensional matrix
AX_S (array): ``AX_S`` with weights given by repetitions and excluded rows removed
XD_S (array): diagonal multiplied by ``X``
D_S (array): diagonal
Expand All @@ -261,17 +260,16 @@ def f_loop_odd(E, AX_S, XD_S, D_S, n, oddloop, oddVX_S): # pragma: no cover
Returns:
array: polynomial coefficients
"""
E_k = E.copy()

count = 0
comb = np.zeros((2, n + 1), dtype=np.complex128)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since now the power traces inherit the type of your matrix, you don't need to make this complex, I believe. Worth checking this in a separate branch before doing the change here.

comb[0, 0] = 1
powtrace = charpoly.powertrace(AX, n + 1)
for i in range(1, n + 1):
if i == 1:
factor = oddloop
elif i % 2 == 0:
factor = E_k.sum() / i + (XD_S @ D_S) / 2
E_k *= E
factor = powtrace[i // 2] / i + (XD_S @ D_S) / 2
else:
factor = oddVX_S @ D_S
D_S = AX_S @ D_S
Expand Down Expand Up @@ -456,13 +454,11 @@ def _calc_hafnian(A, edge_reps, glynn=True): # pragma: no cover

AX_S = get_AX_S(kept_edges, A)

E = eigvals(AX_S) # O(n^3) step

prefac = (-1.0) ** (N // 2 - edge_sum) * binom_prod

if glynn and kept_edges[0] == 0:
prefac *= 0.5
Hnew = prefac * f(E, N)[N // 2]
Hnew = prefac * f(AX_S, N)[N // 2]

H += Hnew

Expand Down Expand Up @@ -561,17 +557,16 @@ def _calc_loop_hafnian(A, D, edge_reps, oddloop=None, oddV=None, glynn=True): #
kept_edges = 2 * kept_edges - edge_reps

AX_S, XD_S, D_S, oddVX_S = get_submatrices(kept_edges, A, D, oddV)

E = eigvals(AX_S) # O(n^3) step
AX = AX_S.copy()

prefac = (-1.0) ** (N // 2 - edge_sum) * binom_prod

if oddloop is not None:
Hnew = prefac * f_loop_odd(E, AX_S, XD_S, D_S, N, oddloop, oddVX_S)[N]
Hnew = prefac * f_loop_odd(AX, AX_S, XD_S, D_S, N, oddloop, oddVX_S)[N]
else:
if glynn and kept_edges[0] == 0:
prefac *= 0.5
Hnew = prefac * f_loop(E, AX_S, XD_S, D_S, N)[N // 2]
Hnew = prefac * f_loop(AX, AX_S, XD_S, D_S, N)[N // 2]

H += Hnew

Expand Down Expand Up @@ -894,7 +889,6 @@ def hafnian_repeated(A, rpt, mu=None, loop=False, rtol=1e-05, atol=1e-08, glynn=

>>> hafnian_repeated(A, rpt) == hafnian(A)


Args:
A (array): a square, symmetric :math:`N\times N` array
rpt (Sequence): a length-:math:`N` positive integer sequence, corresponding
Expand Down