From 76d4fba5f5a0a1f6ff0f63892c020488073cf744 Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Wed, 15 Dec 2021 14:34:34 -0500 Subject: [PATCH 01/11] update readme --- README.rst | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index fb1d2e067..d59bbf928 100644 --- a/README.rst +++ b/README.rst @@ -5,17 +5,13 @@ The Walrus :alt: Tests :target: https://github.com/XanaduAI/thewalrus/actions/workflows/tests.yml -.. image:: https://github.com/XanaduAI/thewalrus/actions/workflows/build.yml/badge.svg - :alt: Build - :target: https://github.com/XanaduAI/thewalrus/actions/workflows/build.yml - .. image:: https://img.shields.io/codecov/c/github/xanaduai/thewalrus/master.svg?style=flat :alt: Codecov coverage :target: https://codecov.io/gh/XanaduAI/thewalrus -.. image:: https://img.shields.io/codacy/grade/df94d22534cf4c05b1bddcf697011a82.svg?style=flat - :alt: Codacy grade - :target: https://app.codacy.com/app/XanaduAI/thewalrus?utm_source=github.com&utm_medium=referral&utm_content=XanaduAI/thewalrus&utm_campaign=badger +.. image:: https://img.shields.io/codefactor/grade/github/XanaduAI/thewalrus/master?style=flat + :alt: CodeFactor Grade + :target: https://www.codefactor.io/repository/github/xanaduai/thewalrus .. image:: https://img.shields.io/readthedocs/the-walrus.svg?style=flat :alt: Read the Docs From 2255f9e8227dcf5858fdd6ca5409a0fde627b142 Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Wed, 15 Dec 2021 14:34:59 -0500 Subject: [PATCH 02/11] fix modules --- docs/code/decompositions.rst | 2 ++ docs/code/fock_gradients.rst | 1 + docs/code/labudde.rst | 2 ++ docs/code/reference.rst | 3 ++- thewalrus/__init__.py | 21 ++++++++++++--------- thewalrus/_hafnian.py | 6 +++--- thewalrus/_permanent.py | 29 +++++++---------------------- thewalrus/csamples.py | 5 +++-- thewalrus/decompositions.py | 16 ++++++++++++++++ thewalrus/fock_gradients.py | 9 +++++++-- thewalrus/labudde.py | 19 +++++++++++++++++++ thewalrus/quantum/__init__.py | 16 +++++++++------- thewalrus/random.py | 7 ++++++- thewalrus/reference.py | 5 +++-- thewalrus/samples.py | 3 ++- thewalrus/symplectic.py | 2 +- 16 files changed, 95 insertions(+), 51 deletions(-) create mode 100644 docs/code/decompositions.rst create mode 100644 docs/code/labudde.rst diff --git a/docs/code/decompositions.rst b/docs/code/decompositions.rst new file mode 100644 index 000000000..c5382513d --- /dev/null +++ b/docs/code/decompositions.rst @@ -0,0 +1,2 @@ +.. automodule:: thewalrus.decompositions + :members: diff --git a/docs/code/fock_gradients.rst b/docs/code/fock_gradients.rst index 6de3480c3..882b13a9c 100644 --- a/docs/code/fock_gradients.rst +++ b/docs/code/fock_gradients.rst @@ -1 +1,2 @@ .. automodule:: thewalrus.fock_gradients + :members: diff --git a/docs/code/labudde.rst b/docs/code/labudde.rst new file mode 100644 index 000000000..812fe44b9 --- /dev/null +++ b/docs/code/labudde.rst @@ -0,0 +1,2 @@ +.. automodule:: thewalrus.labudde + :members: diff --git a/docs/code/reference.rst b/docs/code/reference.rst index f351a247c..e0f34a080 100644 --- a/docs/code/reference.rst +++ b/docs/code/reference.rst @@ -1,2 +1,3 @@ .. automodule:: thewalrus.reference - :members: memoized, partitions, spm, pmp, T + :members: + :exclude-members: LimitedSizeDict, hafnian diff --git a/thewalrus/__init__.py b/thewalrus/__init__.py index 3a29f0ef3..6545eecd6 100644 --- a/thewalrus/__init__.py +++ b/thewalrus/__init__.py @@ -72,8 +72,6 @@ An algorithm that calculates the hafnian of a sparse matrix by taking advantage of the Laplace expansion and memoization, to store only the relevant paths that contribute non-zero values to the final calculation. - - Functions --------- @@ -91,15 +89,17 @@ low_rank_hafnian Code details -^^^^^^^^^^^^ +------------ """ -# pylint: disable=wrong-import-position -import os -import platform - -import numpy as np - import thewalrus.quantum +import thewalrus.csamples +import thewalrus.decompositions +import thewalrus.fock_gradients +import thewalrus.labudde +import thewalrus.random +import thewalrus.reference +import thewalrus.samples +import thewalrus.symplectic from ._hafnian import ( hafnian, @@ -182,6 +182,9 @@ def about(): Cython version: 0.29.24 """ # pylint: disable=import-outside-toplevel + import os + import platform + import sys import numpy import scipy diff --git a/thewalrus/_hafnian.py b/thewalrus/_hafnian.py index 4b67274aa..83f479499 100644 --- a/thewalrus/_hafnian.py +++ b/thewalrus/_hafnian.py @@ -747,7 +747,7 @@ def hafnian( glynn (bool): whether to use finite difference sieve Returns: - int, float, complex: the hafnian of matrix ``A`` + int or float or complex: the hafnian of matrix ``A`` """ # pylint: disable=too-many-return-statements,too-many-branches input_validation(A, rtol=rtol, atol=atol) @@ -890,7 +890,7 @@ def hafnian_repeated(A, rpt, mu=None, loop=False, rtol=1e-05, atol=1e-08, glynn= glynn (bool): whether to use finite difference sieve Returns: - int, float, complex: the hafnian of matrix A + int or float or complex: the hafnian of matrix A """ # pylint: disable=too-many-return-statements,too-many-branches input_validation(A, atol=atol, rtol=rtol) @@ -936,7 +936,7 @@ def hafnian_banded(A, loop=False, rtol=1e-05, atol=1e-08): A (array): a square, symmetric array of even dimensions Returns: - int, float, complex: the loop hafnian of matrix ``A`` + int or float or complex: the loop hafnian of matrix ``A`` """ input_validation(A, atol=atol, rtol=rtol) (n, _) = A.shape diff --git a/thewalrus/_permanent.py b/thewalrus/_permanent.py index aa42e2031..5a69c2b6c 100644 --- a/thewalrus/_permanent.py +++ b/thewalrus/_permanent.py @@ -12,30 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. r""" -Permanent Algorithms -============================= - -.. currentmodule:: thewalrus._permanent - This submodule provides access to tools for finding the permanent of a matrix. The algorithms implemented here was first derived in + * Ryser, Herbert John (1963). Combinatorial Mathematics, The Carus Mathematical Monographs, Vol. 14, Mathematical Association of America. * Glynn, David G. - (2010), "The permanent of a square matrix", European Journal of Combinatorics, 31 (7): 1887–1891. + (2010), "The permanent of a square matrix", European Journal of Combinatorics, 31 (7): 1887-1891. `_ - -Summary -------- -.. autosummary:: - - perm - perm_ryser - perm_bbfg - permanent_repeated - -Code details ------------- """ import numpy as np from numba import jit @@ -54,8 +38,9 @@ def perm(A, method="bbfg"): or ``"bbfg"`` to use the `BBFG formula `_. + Returns: - np.float64 or np.complex128: the permanent of matrix A. + float or complex: the permanent of matrix ``A`` """ if not isinstance(A, np.ndarray): @@ -101,7 +86,7 @@ def perm_ryser(M): # pragma: no cover M (array) : a square array. Returns: - np.float64 or np.complex128: the permanent of matrix M. + float or complex: the permanent of matrix ``M`` """ n = len(M) # row_comb keeps the sum of previous subsets. @@ -143,7 +128,7 @@ def perm_bbfg(M): # pragma: no cover M (array) : a square array. Returns: - np.float64 or np.complex128: the permanent of a matrix M. + float or complex: the permanent of a matrix ``M`` """ n = len(M) @@ -186,7 +171,7 @@ def permanent_repeated(A, rpt): of A to be repeated. Returns: - np.int64 or np.float64 or np.complex128: the permanent of matrix A. + int or float or complex: the permanent of matrix ``A`` """ n = A.shape[0] O = np.zeros([n, n]) diff --git a/thewalrus/csamples.py b/thewalrus/csamples.py index 1205d54b7..abbf6c712 100644 --- a/thewalrus/csamples.py +++ b/thewalrus/csamples.py @@ -15,6 +15,8 @@ Classical sampling algorithms ============================= +**Module name:** :mod:`thewalrus.csamples` + .. currentmodule:: thewalrus.csamples This submodule provides access to classical sampling algorithms for thermal states going through @@ -32,10 +34,9 @@ "Point processes with Gaussian boson sampling" `Phys. Rev. E 101, 022134, (2020). `_. - - Summary ------- + .. autosummary:: rescale_adjacency_matrix_thermal rescale_adjacency_matrix diff --git a/thewalrus/decompositions.py b/thewalrus/decompositions.py index 7d632e048..99d586068 100644 --- a/thewalrus/decompositions.py +++ b/thewalrus/decompositions.py @@ -12,8 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. """ +Decompositions +============== + +**Module name:** :mod:`thewalrus.decompositions` + +.. currentmodule:: thewalrus.decompositions + This module implements common shared matrix decompositions that are used to perform gate decompositions. + +Summary +------- + +.. autosummary:: + williamson + +Code details +------------ """ import numpy as np diff --git a/thewalrus/fock_gradients.py b/thewalrus/fock_gradients.py index a09ec0b89..179394359 100644 --- a/thewalrus/fock_gradients.py +++ b/thewalrus/fock_gradients.py @@ -15,13 +15,16 @@ Fock gradients of Gaussian gates ================================ +**Module name:** :mod:`thewalrus.fock_gradients` + .. currentmodule:: thewalrus.fock_gradients This module contains the Fock representation of the standard Gaussian gates as well as their gradients. -.. autosummary:: - :toctree: api +Summary +------- +.. autosummary:: displacement squeezing beamsplitter @@ -33,6 +36,8 @@ grad_two_mode_squeezing grad_mzgate +Code details +^^^^^^^^^^^^ """ import numpy as np diff --git a/thewalrus/labudde.py b/thewalrus/labudde.py index ae1e02b94..87cd3592b 100644 --- a/thewalrus/labudde.py +++ b/thewalrus/labudde.py @@ -12,8 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. """ +La Budde's algorithm +==================== + +**Module name:** :mod:`thewalrus.labudde` + +.. currentmodule:: thewalrus.labudde + This module implements the La Budde's algorithm to calculate the characteristic polynomials of matrices. + +Summary +------- +.. autosummary:: + get_reflection_vector + apply_householder + reduce_matrix_to_hessenberg + charpoly_from_labudde + power_trace_labudde + +Code details +------------ """ # pylint: disable=too-many-branches import numpy as np diff --git a/thewalrus/quantum/__init__.py b/thewalrus/quantum/__init__.py index 5b6ffabc1..53b7f3ce8 100644 --- a/thewalrus/quantum/__init__.py +++ b/thewalrus/quantum/__init__.py @@ -15,6 +15,8 @@ Quantum algorithms ================== +**Module name:** :mod:`thewalrus.quantum` + .. currentmodule:: thewalrus.quantum This submodule provides access to various utility functions that act on Gaussian @@ -41,7 +43,7 @@ Fock states and tensors -^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- .. autosummary:: @@ -59,7 +61,7 @@ n_body_marginals Adjacency matrices -^^^^^^^^^^^^^^^^^^ +------------------ .. autosummary:: @@ -68,7 +70,7 @@ adj_to_qmat Gaussian checks -^^^^^^^^^^^^^^^ +--------------- .. autosummary:: @@ -78,7 +80,7 @@ fidelity Conversions -^^^^^^^^^^^ +----------- .. autosummary:: @@ -91,7 +93,7 @@ real_to_complex_displacements Means and variances -^^^^^^^^^^^^^^^^^^^ +------------------- .. autosummary:: @@ -110,7 +112,7 @@ click_cumulant Photon number distributions -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +--------------------------- .. autosummary:: @@ -120,7 +122,7 @@ Code details -^^^^^^^^^^^^ +------------ """ import warnings import functools diff --git a/thewalrus/random.py b/thewalrus/random.py index 2e2b66e94..207847199 100644 --- a/thewalrus/random.py +++ b/thewalrus/random.py @@ -15,11 +15,16 @@ Random matrices =============== +**Module name:** :mod:`thewalrus.random` + .. currentmodule:: thewalrus.random This submodule provides access to utility functions to generate random unitary, symplectic and covariance matrices. +Summary +------- + .. autosummary:: random_covariance random_symplectic @@ -28,7 +33,7 @@ random_banded_interferometer Code details -^^^^^^^^^^^^ +------------ """ import numpy as np import scipy as sp diff --git a/thewalrus/reference.py b/thewalrus/reference.py index 33c74de0f..465d232ec 100644 --- a/thewalrus/reference.py +++ b/thewalrus/reference.py @@ -15,6 +15,8 @@ Reference implementations ========================= +**Module name:** :mod:`thewalrus.reference` + .. currentmodule:: thewalrus.reference This submodule provides access to reference implementations of the @@ -27,7 +29,6 @@ complex matrices and its benchmarking on the Titan supercomputer" `arxiv:1805.12498 (2018) `_ - Reference functions ------------------- @@ -51,7 +52,7 @@ T Code details -^^^^^^^^^^^^ +------------ """ import functools diff --git a/thewalrus/samples.py b/thewalrus/samples.py index dc1762a49..e020516dd 100644 --- a/thewalrus/samples.py +++ b/thewalrus/samples.py @@ -15,12 +15,13 @@ Sampling algorithms =================== +**Module name:** :mod:`thewalrus.samples` + .. currentmodule:: thewalrus.samples This submodule provides access to algorithms to sample from the hafnian or the torontonian of Gaussian quantum states. - Hafnian sampling ---------------- diff --git a/thewalrus/symplectic.py b/thewalrus/symplectic.py index 4c5b986c7..6d37c05c4 100644 --- a/thewalrus/symplectic.py +++ b/thewalrus/symplectic.py @@ -54,7 +54,7 @@ rotation Code details -^^^^^^^^^^^^ +------------ """ import numpy as np From ad46af441046898607ac507ea4f63a71138d2d2c Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Wed, 15 Dec 2021 14:51:49 -0500 Subject: [PATCH 03/11] add labudde and decomps to docs --- docs/code.rst | 6 +++++- docs/code/labudde.rst | 1 + docs/index.rst | 2 ++ thewalrus/decompositions.py | 5 +++-- thewalrus/labudde.py | 12 ++++++------ 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/docs/code.rst b/docs/code.rst index ee3566529..1ca07e952 100644 --- a/docs/code.rst +++ b/docs/code.rst @@ -12,6 +12,10 @@ Python API * The :mod:`thewalrus.symplectic` submodule provides access to a convenient set of symplectic matrices and utility functions to manipulate them +* The :mod:`thewalrus.decompositions` submodule provides access to common shared matrix decompositions used to perform gate decompositions + +* The :mod:`thewalrus.labudde` submodule provides access to La Budde's algorithm to calculate the characteristic polynomials of matrices + * The :mod:`thewalrus.random` submodule provides access to random unitary, symplectic and covariance matrices * The :mod:`thewalrus.fock_gradients` submodule provides access to the Fock representation of certain continuous-variable gates and their gradients @@ -22,4 +26,4 @@ Python API Octave ------ -In addition, two auxiallary Octave functions are provided: :download:`octave/hafnian.m <../octave/hafnian.m>` and :download:`octave/loophafnian.m <../octave/loophafnian.m>`. +In addition, two auxiliary Octave functions are provided: :download:`octave/hafnian.m <../octave/hafnian.m>` and :download:`octave/loophafnian.m <../octave/loophafnian.m>`. diff --git a/docs/code/labudde.rst b/docs/code/labudde.rst index 812fe44b9..25797212b 100644 --- a/docs/code/labudde.rst +++ b/docs/code/labudde.rst @@ -1,2 +1,3 @@ .. automodule:: thewalrus.labudde :members: + :exclude-members: alpha, beta, hij, mlo, diff --git a/docs/index.rst b/docs/index.rst index 4951507ab..f0c107a2c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -165,6 +165,8 @@ The Walrus library is **free** and **open source**, released under the Apache Li code/samples code/csamples code/symplectic + code/decompositions + code/labudde code/random code/fock_gradients code/reference diff --git a/thewalrus/decompositions.py b/thewalrus/decompositions.py index 99d586068..556e6d7f4 100644 --- a/thewalrus/decompositions.py +++ b/thewalrus/decompositions.py @@ -40,8 +40,9 @@ def williamson(V, rtol=1e-05, atol=1e-08): r"""Williamson decomposition of positive-definite (real) symmetric matrix. - See https://math.stackexchange.com/questions/1171842/finding-the-symplectic-matrix-in-williamsons-theorem/2682630#2682630 - and https://strawberryfields.ai/photonics/conventions/decompositions.html#williamson-decomposition + See `this thread `_ + and the `Williamson decomposition documentation `_ + Args: V (array[float]): positive definite symmetric (real) matrix rtol (float): the relative tolerance parameter used in ``np.allclose`` diff --git a/thewalrus/labudde.py b/thewalrus/labudde.py index 87cd3592b..8c332636c 100644 --- a/thewalrus/labudde.py +++ b/thewalrus/labudde.py @@ -19,7 +19,7 @@ .. currentmodule:: thewalrus.labudde -This module implements the La Budde's algorithm to calculate the +This module implements La Budde's algorithm to calculate the characteristic polynomials of matrices. Summary @@ -128,7 +128,7 @@ def reduce_matrix_to_hessenberg(matrix): # pragma: no cover @jit(nopython=True, cache=True) def beta(H, i): # pragma: no cover r"""Auxiliary function for Labudde algorithm. See pg 10 of - [arXiv:1104.3769](https://arxiv.org/abs/1104.3769v1) for definition of beta. + `arXiv:1104.3769 `_ for definition of beta. Args: matrix (array): upper-Hessenberg matrix @@ -143,7 +143,7 @@ def beta(H, i): # pragma: no cover @jit(nopython=True, cache=True) def alpha(H, i): # pragma: no cover r"""Auxiliary function for La Budde's algorithm. See pg 10 of - [arXiv:1104.3769](https://arxiv.org/abs/1104.3769v1) for definition of alpha. + `arXiv:1104.3769 `_ for definition of alpha. Args: matrix (array): upper-Hessenberg matrix @@ -158,7 +158,7 @@ def alpha(H, i): # pragma: no cover @jit(nopython=True, cache=True) def hij(H, i, j): # pragma: no cover r"""Auxiliary function for La Budde's algorithm. See pg 10 of - [arXiv:1104.3769](https://arxiv.org/abs/1104.3769v1) for definition of hij. + `arXiv:1104.3769 `_ for definition of hij. Args: matrix (array): upper-Hessenberg matrix @@ -174,7 +174,7 @@ def hij(H, i, j): # pragma: no cover @jit(nopython=True, cache=True) def mlo(i, j): # pragma: no cover """Auxiliary function for La Budde's algorithm. - See [arXiv:1104.3769](https://arxiv.org/abs/1104.3769v1). + See `arXiv:1104.3769 `_. .. note:: @@ -195,7 +195,7 @@ def mlo(i, j): # pragma: no cover @jit(nopython=True, cache=True) def _charpoly_from_labudde(H, k): # pragma: no cover r"""Compute characteristic polynomial using La Budde's algorithm. - See [arXiv:1104.3769](https://arxiv.org/abs/1104.3769v1). + See `arXiv:1104.3769 `_. .. note:: From 4c0d9d3422a6db4632b05646287fb8ef7b9d7540 Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Wed, 15 Dec 2021 14:53:58 -0500 Subject: [PATCH 04/11] fix --- thewalrus/fock_gradients.py | 2 +- thewalrus/reference.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/thewalrus/fock_gradients.py b/thewalrus/fock_gradients.py index 179394359..44b5cc9a9 100644 --- a/thewalrus/fock_gradients.py +++ b/thewalrus/fock_gradients.py @@ -37,7 +37,7 @@ grad_mzgate Code details -^^^^^^^^^^^^ +------------ """ import numpy as np diff --git a/thewalrus/reference.py b/thewalrus/reference.py index 465d232ec..00d7934eb 100644 --- a/thewalrus/reference.py +++ b/thewalrus/reference.py @@ -36,7 +36,7 @@ hafnian Code details -^^^^^^^^^^^^ +------------ .. autofunction:: hafnian From dca9a440a40466c6df8372d3dcf6833d4bdfa95c Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Wed, 15 Dec 2021 15:32:22 -0500 Subject: [PATCH 05/11] add jake credits --- thewalrus/_hafnian.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/thewalrus/_hafnian.py b/thewalrus/_hafnian.py index 83f479499..d7d5f8114 100644 --- a/thewalrus/_hafnian.py +++ b/thewalrus/_hafnian.py @@ -477,6 +477,9 @@ def _calc_hafnian(A, edge_reps, glynn=True): # pragma: no cover def _haf(A, reps=None, glynn=True): r"""Calculate hafnian with (optional) repeated rows and columns. + Code contributed by `Jake Bulmer `_ based on + `arXiv:2108.01622 `_. + Args: A (array): N x N matrix. reps (list): Length-N list of repetitions of each row/col (optional). If not provided, @@ -519,6 +522,9 @@ def _calc_loop_hafnian(A, D, edge_reps, oddloop=None, oddV=None, glynn=True): # """Compute loop hafnian, using inputs as prepared by frontend loop_hafnian function compiled with Numba. + Code contributed by `Jake Bulmer `_ based on + `arXiv:2108.01622 `_. + Args: A (array): matrix ordered according to the chosen perfect matching. D (array): diagonals ordered according to the chosen perfect matchin @@ -586,6 +592,9 @@ def _calc_loop_hafnian(A, D, edge_reps, oddloop=None, oddV=None, glynn=True): # def loop_hafnian(A, D=None, reps=None, glynn=True): """Calculate loop hafnian with (optional) repeated rows and columns. + Code contributed by `Jake Bulmer `_ based on + `arXiv:2108.01622 `_. + Args: A (array): N x N matrix. D (array): Diagonal entries of matrix (optional). If not provided, ``D`` is the diagonal of ``A``. @@ -594,6 +603,7 @@ def loop_hafnian(A, D=None, reps=None, glynn=True): row/column assumed to be repeated once. glynn (bool): If ``True``, use Glynn-style finite difference sieve formula, if ``False``, use Ryser style inclusion/exclusion principle. + Returns complex: result of loop hafnian calculation """ @@ -731,6 +741,9 @@ def hafnian( ): # pylint: disable=too-many-arguments """Returns the hafnian of a matrix. + Code contributed by `Jake Bulmer `_ based on + `arXiv:2108.01622 `_. + Args: A (array): a square, symmetric array of even dimensions loop (bool): If ``True``, the loop hafnian is returned. Default is ``False``. @@ -856,6 +869,9 @@ def lhaf(d: frozenset) -> float: def hafnian_repeated(A, rpt, mu=None, loop=False, rtol=1e-05, atol=1e-08, glynn=True): r"""Returns the hafnian of matrix with repeated rows/columns. + Code contributed by `Jake Bulmer `_ based on + `arXiv:2108.01622 `_. + The :func:`reduction` function may be used to show the resulting matrix with repeated rows and columns as per ``rpt``. From a5fcd9acd229e823074648e0de78a5c407905fa9 Mon Sep 17 00:00:00 2001 From: Theodor Date: Wed, 15 Dec 2021 15:45:12 -0500 Subject: [PATCH 06/11] Apply suggestions from code review Co-authored-by: Nicolas Quesada <991946+nquesada@users.noreply.github.com> --- thewalrus/_hafnian.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/thewalrus/_hafnian.py b/thewalrus/_hafnian.py index d7d5f8114..0310e765c 100644 --- a/thewalrus/_hafnian.py +++ b/thewalrus/_hafnian.py @@ -477,7 +477,7 @@ def _calc_hafnian(A, edge_reps, glynn=True): # pragma: no cover def _haf(A, reps=None, glynn=True): r"""Calculate hafnian with (optional) repeated rows and columns. - Code contributed by `Jake Bulmer `_ based on + Code contributed by `Jake F.F. Bulmer `_ based on `arXiv:2108.01622 `_. Args: @@ -522,7 +522,7 @@ def _calc_loop_hafnian(A, D, edge_reps, oddloop=None, oddV=None, glynn=True): # """Compute loop hafnian, using inputs as prepared by frontend loop_hafnian function compiled with Numba. - Code contributed by `Jake Bulmer `_ based on + Code contributed by `Jake F.F. Bulmer `_ based on `arXiv:2108.01622 `_. Args: @@ -592,7 +592,7 @@ def _calc_loop_hafnian(A, D, edge_reps, oddloop=None, oddV=None, glynn=True): # def loop_hafnian(A, D=None, reps=None, glynn=True): """Calculate loop hafnian with (optional) repeated rows and columns. - Code contributed by `Jake Bulmer `_ based on + Code contributed by `Jake F.F. Bulmer `_ based on `arXiv:2108.01622 `_. Args: @@ -741,7 +741,7 @@ def hafnian( ): # pylint: disable=too-many-arguments """Returns the hafnian of a matrix. - Code contributed by `Jake Bulmer `_ based on + Code contributed by `Jake F.F. Bulmer `_ based on `arXiv:2108.01622 `_. Args: @@ -869,7 +869,7 @@ def lhaf(d: frozenset) -> float: def hafnian_repeated(A, rpt, mu=None, loop=False, rtol=1e-05, atol=1e-08, glynn=True): r"""Returns the hafnian of matrix with repeated rows/columns. - Code contributed by `Jake Bulmer `_ based on + Code contributed by `Jake F.F. Bulmer `_ based on `arXiv:2108.01622 `_. The :func:`reduction` function may be used to show the resulting matrix From 1619c9ee7c076353fde81648cbc83b17e199f6ac Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Wed, 15 Dec 2021 18:06:24 -0500 Subject: [PATCH 07/11] remove omp --- thewalrus/quantum/fock_tensors.py | 11 ----------- thewalrus/tests/test_quantum.py | 9 --------- 2 files changed, 20 deletions(-) diff --git a/thewalrus/quantum/fock_tensors.py b/thewalrus/quantum/fock_tensors.py index 2db4ebc8c..7de014bd1 100644 --- a/thewalrus/quantum/fock_tensors.py +++ b/thewalrus/quantum/fock_tensors.py @@ -392,17 +392,6 @@ def fock_tensor( def probabilities(mu, cov, cutoff, parallel=False, hbar=2.0, rtol=1e-05, atol=1e-08): r"""Generate the Fock space probabilities of a Gaussian state up to a Fock space cutoff. - .. note:: - - Individual density matrix elements are computed using multithreading by OpenMP. - Setting ``parallel=True`` will further result in *multiple* density matrix elements - being computed in parallel. - - When setting ``parallel=True``, OpenMP will need to be turned off by setting the - environment variable ``OMP_NUM_THREADS=1`` (forcing single threaded use for individual - matrix elements). Remove the environment variable or set it to ``OMP_NUM_THREADS=''`` - to again use multithreading with OpenMP. - Args: mu (array): vector of means of length ``2*n_modes`` cov (array): covariance matrix of shape ``[2*n_modes, 2*n_modes]`` diff --git a/thewalrus/tests/test_quantum.py b/thewalrus/tests/test_quantum.py index 52f04b9e3..a78814675 100644 --- a/thewalrus/tests/test_quantum.py +++ b/thewalrus/tests/test_quantum.py @@ -1161,9 +1161,6 @@ def test_photon_number_covmat_random_state(hbar): def test_update_with_loss_two_mode_squeezed(etas, etai, parallel, hbar, monkeypatch): """Test the probabilities are updated correctly for a lossy two mode squeezed vacuum state""" - if parallel: # set single-thread use in OpenMP - monkeypatch.setenv("OMP_NUM_THREADS", "1") - cov2 = two_mode_squeezing(np.arcsinh(1.0), 0.0) cov2 = hbar * cov2 @ cov2.T / 2.0 mean2 = np.zeros([4]) @@ -1188,9 +1185,6 @@ def test_update_with_loss_two_mode_squeezed(etas, etai, parallel, hbar, monkeypa def test_update_with_loss_coherent_states(etas, etai, parallel, hbar, monkeypatch): """Checks probabilities are updated correctly for coherent states""" - if parallel: # set single-thread use in OpenMP - monkeypatch.setenv("OMP_NUM_THREADS", "1") - n_modes = 2 cov = hbar * np.identity(2 * n_modes) / 2 eta_vals = [etas, etai] @@ -1237,9 +1231,6 @@ def test_loss_value_error(eta): def test_update_with_noise_coherent(num_modes, parallel, monkeypatch): """Test that adding noise on coherent states gives the same probabilities at some other coherent states""" - if parallel: # set single-thread use in OpenMP - monkeypatch.setenv("OMP_NUM_THREADS", "1") - cutoff = 15 nbar_vals = np.random.rand(num_modes) noise_dists = np.array([poisson.pmf(np.arange(cutoff), nbar) for nbar in nbar_vals]) From bb00aa1d9e850e1b06e97e813b5842ecd4d22e93 Mon Sep 17 00:00:00 2001 From: Theodor Date: Thu, 16 Dec 2021 09:16:19 -0500 Subject: [PATCH 08/11] Update docs/code.rst Co-authored-by: Josh Izaac --- docs/code.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/code.rst b/docs/code.rst index 1ca07e952..34cceb343 100644 --- a/docs/code.rst +++ b/docs/code.rst @@ -26,4 +26,4 @@ Python API Octave ------ -In addition, two auxiliary Octave functions are provided: :download:`octave/hafnian.m <../octave/hafnian.m>` and :download:`octave/loophafnian.m <../octave/loophafnian.m>`. +In addition, two Octave functions are provided: :download:`octave/hafnian.m <../octave/hafnian.m>` and :download:`octave/loophafnian.m <../octave/loophafnian.m>`. From c3ec503a620ed406715b83ebb3e0981fb3d41939 Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Thu, 16 Dec 2021 11:54:55 -0500 Subject: [PATCH 09/11] remove unused args --- thewalrus/tests/test_quantum.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/thewalrus/tests/test_quantum.py b/thewalrus/tests/test_quantum.py index a78814675..dbc24fd21 100644 --- a/thewalrus/tests/test_quantum.py +++ b/thewalrus/tests/test_quantum.py @@ -1158,7 +1158,7 @@ def test_photon_number_covmat_random_state(hbar): @pytest.mark.parametrize("etas", [0.1, 0.4, 0.9, 1.0]) @pytest.mark.parametrize("etai", [0.1, 0.4, 0.9, 1.0]) @pytest.mark.parametrize("parallel", [True, False]) -def test_update_with_loss_two_mode_squeezed(etas, etai, parallel, hbar, monkeypatch): +def test_update_with_loss_two_mode_squeezed(etas, etai, parallel, hbar): """Test the probabilities are updated correctly for a lossy two mode squeezed vacuum state""" cov2 = two_mode_squeezing(np.arcsinh(1.0), 0.0) @@ -1182,7 +1182,7 @@ def test_update_with_loss_two_mode_squeezed(etas, etai, parallel, hbar, monkeypa @pytest.mark.parametrize("etas", [0.1, 0.4, 0.9, 1.0]) @pytest.mark.parametrize("etai", [0.1, 0.4, 0.9, 1.0]) @pytest.mark.parametrize("parallel", [True, False]) -def test_update_with_loss_coherent_states(etas, etai, parallel, hbar, monkeypatch): +def test_update_with_loss_coherent_states(etas, etai, parallel, hbar): """Checks probabilities are updated correctly for coherent states""" n_modes = 2 @@ -1228,7 +1228,7 @@ def test_loss_value_error(eta): @pytest.mark.parametrize("num_modes", [1, 2, 3]) @pytest.mark.parametrize("parallel", [True, False]) -def test_update_with_noise_coherent(num_modes, parallel, monkeypatch): +def test_update_with_noise_coherent(num_modes, parallel): """Test that adding noise on coherent states gives the same probabilities at some other coherent states""" cutoff = 15 From 33ea19ce9d82e11c224a7ca3c40d43049be5b466 Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Thu, 16 Dec 2021 11:55:07 -0500 Subject: [PATCH 10/11] suggestions from code review --- docs/code.rst | 2 +- docs/code/{labudde.rst => charpoly.rst} | 2 +- docs/index.rst | 4 ++-- thewalrus/__init__.py | 2 +- thewalrus/{labudde.py => charpoly.py} | 22 +++++++++++----------- thewalrus/fock_gradients.py | 4 ++-- thewalrus/tests/test_labudde.py | 12 ++++++------ 7 files changed, 24 insertions(+), 24 deletions(-) rename docs/code/{labudde.rst => charpoly.rst} (60%) rename thewalrus/{labudde.py => charpoly.py} (95%) diff --git a/docs/code.rst b/docs/code.rst index 34cceb343..96a8b0b04 100644 --- a/docs/code.rst +++ b/docs/code.rst @@ -14,7 +14,7 @@ Python API * The :mod:`thewalrus.decompositions` submodule provides access to common shared matrix decompositions used to perform gate decompositions -* The :mod:`thewalrus.labudde` submodule provides access to La Budde's algorithm to calculate the characteristic polynomials of matrices +* The :mod:`thewalrus.charpoly` submodule provides access to La Budde's algorithm to calculate the characteristic polynomials of matrices * The :mod:`thewalrus.random` submodule provides access to random unitary, symplectic and covariance matrices diff --git a/docs/code/labudde.rst b/docs/code/charpoly.rst similarity index 60% rename from docs/code/labudde.rst rename to docs/code/charpoly.rst index 25797212b..a30ad67a6 100644 --- a/docs/code/labudde.rst +++ b/docs/code/charpoly.rst @@ -1,3 +1,3 @@ -.. automodule:: thewalrus.labudde +.. automodule:: thewalrus.charpoly :members: :exclude-members: alpha, beta, hij, mlo, diff --git a/docs/index.rst b/docs/index.rst index f0c107a2c..8d52422a0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -165,8 +165,8 @@ The Walrus library is **free** and **open source**, released under the Apache Li code/samples code/csamples code/symplectic - code/decompositions - code/labudde + code/charpoly code/random code/fock_gradients + code/decompositions code/reference diff --git a/thewalrus/__init__.py b/thewalrus/__init__.py index 6545eecd6..b34297c3f 100644 --- a/thewalrus/__init__.py +++ b/thewalrus/__init__.py @@ -95,7 +95,7 @@ import thewalrus.csamples import thewalrus.decompositions import thewalrus.fock_gradients -import thewalrus.labudde +import thewalrus.charpoly import thewalrus.random import thewalrus.reference import thewalrus.samples diff --git a/thewalrus/labudde.py b/thewalrus/charpoly.py similarity index 95% rename from thewalrus/labudde.py rename to thewalrus/charpoly.py index 8c332636c..dd32cd943 100644 --- a/thewalrus/labudde.py +++ b/thewalrus/charpoly.py @@ -12,12 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. """ -La Budde's algorithm -==================== +Characteristic polynomials +========================== -**Module name:** :mod:`thewalrus.labudde` +**Module name:** :mod:`thewalrus.charpoly` -.. currentmodule:: thewalrus.labudde +.. currentmodule:: thewalrus.charpoly This module implements La Budde's algorithm to calculate the characteristic polynomials of matrices. @@ -28,8 +28,8 @@ get_reflection_vector apply_householder reduce_matrix_to_hessenberg - charpoly_from_labudde - power_trace_labudde + charpoly + powertrace Code details ------------ @@ -193,7 +193,7 @@ def mlo(i, j): # pragma: no cover @jit(nopython=True, cache=True) -def _charpoly_from_labudde(H, k): # pragma: no cover +def _charpoly(H, k): # pragma: no cover r"""Compute characteristic polynomial using La Budde's algorithm. See `arXiv:1104.3769 `_. @@ -283,7 +283,7 @@ def _charpoly_from_labudde(H, k): # pragma: no cover @jit(nopython=True, cache=True) -def charpoly_from_labudde(H): # pragma: no cover +def charpoly(H): # pragma: no cover """Calculates the characteristic polynomial of the matrix ``H``. Args: @@ -294,12 +294,12 @@ def charpoly_from_labudde(H): # pragma: no cover """ n = len(H) reduce_matrix_to_hessenberg(H) - coeff = _charpoly_from_labudde(H, n) + coeff = _charpoly(H, n) return coeff @jit(nopython=True, cache=True) -def power_trace_labudde(H, n): # pragma: no cover +def powertrace(H, n): # pragma: no cover """Calculates the powertraces of the matrix ``H`` up to power ``n-1``. Args: @@ -318,7 +318,7 @@ def power_trace_labudde(H, n): # pragma: no cover pow_traces.append(np.trace(A)) if n <= m: return np.array(pow_traces, dtype=H.dtype) - char_pol = charpoly_from_labudde(H) + char_pol = charpoly(H) for _ in range(min_val, n): ssum = 0 for k in range(m): diff --git a/thewalrus/fock_gradients.py b/thewalrus/fock_gradients.py index 44b5cc9a9..bce8b0174 100644 --- a/thewalrus/fock_gradients.py +++ b/thewalrus/fock_gradients.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. """ -Fock gradients of Gaussian gates -================================ +Fock representations +==================== **Module name:** :mod:`thewalrus.fock_gradients` diff --git a/thewalrus/tests/test_labudde.py b/thewalrus/tests/test_labudde.py index 87348fd17..8538eab21 100644 --- a/thewalrus/tests/test_labudde.py +++ b/thewalrus/tests/test_labudde.py @@ -14,7 +14,7 @@ """Labudde tests""" import math import numpy as np -import thewalrus.labudde +import thewalrus.charpoly import pytest @@ -26,19 +26,19 @@ def test_labudde_2by2(phi): sinh_phi = math.sinh(phi) cosh_phi = math.cosh(phi) mat = np.array([[cosh_phi, sinh_phi], [sinh_phi, cosh_phi]]) - charpoly = thewalrus.labudde.charpoly_from_labudde(mat) + charpoly = thewalrus.charpoly.charpoly(mat) assert np.allclose(charpoly[0], -2 * cosh_phi) assert np.allclose(charpoly[1], 1) @pytest.mark.parametrize("n", [1, 2, 3]) def test_powtrace_2by2(n): - """Consistency test between power_trace_eigen and power_trace_labudde""" + """Consistency test between power_trace_eigen and powertrace""" phi = 0.1 * math.pi sinh_phi = math.sinh(phi) cosh_phi = math.cosh(phi) mat = np.array([[cosh_phi, sinh_phi], [sinh_phi, cosh_phi]]) - pow_trace_lab = thewalrus.labudde.power_trace_labudde(mat, n + 1) + pow_trace_lab = thewalrus.charpoly.powertrace(mat, n + 1) # Use wolfram alpha to verify with: # Trace[[[1.04975523, 0.31935254], [0.31935254, 1.04975523]]^1] @@ -55,7 +55,7 @@ def test_powtrace_2by2(n): @pytest.mark.parametrize("n", [1, 2, 4]) def test_powtrace_4by4(n): - """Consistency test between power_trace_eigen and power_trace_labudde""" + """Consistency test between power_trace_eigen and powertrace""" mat = np.array( [ @@ -65,7 +65,7 @@ def test_powtrace_4by4(n): [21.31935254, 3.14975523, 7, 8], ] ) - pow_trace_lab = thewalrus.labudde.power_trace_labudde(mat, n + 1) + pow_trace_lab = thewalrus.charpoly.powertrace(mat, n + 1) if n == 1: assert np.allclose(pow_trace_lab[-1], 15.0995) if n == 2: From 0e3119ba9290ddc0fd09af1d81d1b2b896b007ee Mon Sep 17 00:00:00 2001 From: Theodor Isacsson Date: Thu, 16 Dec 2021 12:46:06 -0500 Subject: [PATCH 11/11] update changelog --- .github/CHANGELOG.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index cbdc7cec5..400d9748d 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -6,18 +6,31 @@ ### Improvements -* Permanent algorithms are implemented in numba, hence reducing the C++ dependencies of The Walrus. [#300](https://github.com/XanaduAI/thewalrus/pull/300) +* Permanent algorithms are implemented in Python using Numba just-in-time compilation. [#300](https://github.com/XanaduAI/thewalrus/pull/300) + +* Hafnian algorithms are implemented in Python using Numba just-in-time compilation. [#311](https://github.com/XanaduAI/thewalrus/pull/311) + +* The Walrus is no longer dependent on C++, and all C++-related code and documentation is removed. Instead, all code has been ported to Python using just-in-time compilation to improve performance. [#311](https://github.com/XanaduAI/thewalrus/pull/311) + +* Documentation is updated to include the characteristic polynomials and decompositions modules. [#312](https://github.com/XanaduAI/thewalrus/pull/312) ### Bug fixes +* Makes modules reachable via the global namespace, instead of requiring importing the modules explicitly. [#312](https://github.com/XanaduAI/thewalrus/pull/312) + + ```python + import thewalrus as tw + tw.samples.generate_torontonian_sample + ``` + ### Breaking changes ### Contributors This release contains contributions from (in alphabetical order): -Benjamin Lanthier, Dominic Leclerc, Nicolas Quesada, Brandon Turcotte, Trevor Vincent, Jiaqi Zhao +Theodor Isacsson, Benjamin Lanthier, Dominic Leclerc, Nicolas Quesada, Brandon Turcotte, Trevor Vincent, Jiaqi Zhao ---