Comments (9)
Hey @minseok1999! Can you please edit your post and include the output of the following:
import thewalrus as tw
tw.about()
You can put this in the "System information" box. It would also help if you could include the full error traceback π.
from thewalrus.
Hey @minseok1999! Can you please edit your post and include the output of the following:
import thewalrus as tw tw.about()
You can put this in the "System information" box. It would also help if you could include the full error traceback π.
I have edited as requested!
from thewalrus.
Hmm... I'm not able to replicate the behaviour you're seeing. Here are my package versions:
Python version: 3.9.0
The Walrus version: 0.20.0
Numpy version: 1.23.5
Scipy version: 1.10.1
SymPy version: 1.12
Numba version: 0.57.0
Slightly different from yours. Can you try those versions and see if it works for you?
from thewalrus.
Hmm... I'm not able to replicate the behaviour you're seeing. Here are my package versions:
Python version: 3.9.0 The Walrus version: 0.20.0 Numpy version: 1.23.5 Scipy version: 1.10.1 SymPy version: 1.12 Numba version: 0.57.0
Slightly different from yours. Can you try those versions and see if it works for you?
Here is the list of libraries that I imported
import multiprocessing
from multiprocessing import Pool
import numpy as np
from scipy.special import factorial as fac
from thewalrus._hafnian import hafnian, reduction
from thewalrus._torontonian import tor
from thewalrus.quantum import (
Amat,
Covmat,
Qmat,
Xmat,
gen_Qmat_from_graph,
is_classical_cov,
reduced_gaussian,
density_matrix_element,
)
# ===============================================================================================
# Hafnian sampling
# ===============================================================================================
# pylint: disable=too-many-branches
def generate_hafnian_sample(
cov, mean, hbar=2, cutoff=6, max_photons=30, approx=False, approx_samples=1e5
): # pylint: disable=too-many-branches
r"""Returns a single sample from the Hafnian of a Gaussian state.
Args:
cov (array): a :math:`2N\times 2N` ``np.float64`` covariance matrix
representing an :math:`N` mode quantum state. This can be obtained
via the ``scovmavxp`` method of the Gaussian backend of Strawberry Fields.
mean (array): a :math:`2N`` ``np.float64`` vector of means representing the Gaussian
state.
hbar (float): (default 2) the value of :math:`\hbar` in the commutation
relation :math:`[\x,\p]=i\hbar`.
cutoff (int): the Fock basis truncation.
max_photons (int): specifies the maximum number of photons that can be counted.
approx (bool): if ``True``, the approximate hafnian algorithm is used.
Note that this can only be used for real, non-negative matrices.
approx_samples: the number of samples used to approximate the hafnian if ``approx=True``.
Returns:
np.array[int]: a photon number sample from the Gaussian states.
"""
N = len(cov) // 2
result = []
prev_prob = 1.0
nmodes = N
if mean is None:
local_mu = np.zeros(2 * N)
else:
local_mu = mean
A = Amat(Qmat(cov), hbar=hbar)
for k in range(nmodes):
probs1 = np.zeros([cutoff + 1], dtype=np.float64)
kk = np.arange(k + 1)
mu_red, V_red = reduced_gaussian(local_mu, cov, kk)
if approx:
Q = Qmat(V_red, hbar=hbar)
A = Amat(Q, hbar=hbar, cov_is_qmat=True)
for i in range(cutoff):
indices = result + [i]
ind2 = indices + indices
if approx:
factpref = np.prod(fac(indices))
mat = reduction(A, ind2)
probs1[i] = (
hafnian(np.abs(mat.real), approx=True, num_samples=approx_samples) / factpref
)
else:
probs1[i] = density_matrix_element(
mu_red, V_red, indices, indices, include_prefactor=True, hbar=hbar
).real
if approx:
probs1 = probs1 / np.sqrt(np.linalg.det(Q).real)
probs2 = probs1 / prev_prob
probs3 = np.maximum(
probs2, np.zeros_like(probs2)
) # pylint: disable=assignment-from-no-return
ssum = np.sum(probs3)
if ssum < 1.0:
probs3[-1] = 1.0 - ssum
# The following normalization of probabilities is needed when approx=True
if approx:
if ssum > 1.0:
probs3 = probs3 / ssum
result.append(np.random.choice(a=range(len(probs3)), p=probs3))
if result[-1] == cutoff:
return -1
if sum(result) > max_photons:
return -1
prev_prob = probs1[result[-1]]
return result
def _hafnian_sample(args):
r"""Returns samples from the Hafnian of a Gaussian state.
Note: this is a wrapper function, instead of using this function
directly, please use either :func:`torontonian_sample_state` or
:func:`torontonian_sample_graph`.
Args:
args (list): a list containing the following parameters:
cov (array)
a :math:`2N\times 2N` ``np.float64`` covariance matrix
representing an :math:`N` mode quantum state. This can be obtained
via the ``scovmavxp`` method of the Gaussian backend of Strawberry Fields.
samples (int)
the number of samples to return.
mean (array): a :math:`2N`` ``np.float64`` vector of means representing the Gaussian
state.
hbar (float)
the value of :math:`\hbar` in the commutation relation :math:`[\x,\p]=i\hbar`.
cutoff (int)
the Fock basis truncation.
max_photons (int)
specifies the maximum number of photons that can be counted.
approx (bool)
if ``True``, the approximate hafnian algorithm is used.
Note that this can only be used for real, non-negative matrices.
approx_samples (int)
the number of samples used to approximate the hafnian if ``approx=True``.
Returns:
np.array[int]: photon number samples from the Gaussian state
"""
cov, samples, mean, hbar, cutoff, max_photons, approx, approx_samples = args
if not isinstance(cov, np.ndarray):
raise TypeError("Covariance matrix must be a NumPy array.")
matshape = cov.shape
if matshape[0] != matshape[1]:
raise ValueError("Covariance matrix must be square.")
if np.isnan(cov).any():
raise ValueError("Covariance matrix must not contain NaNs.")
samples_array = []
j = 0
while j < samples:
result = generate_hafnian_sample(
cov,
mean=mean,
hbar=hbar,
cutoff=cutoff,
max_photons=max_photons,
approx=approx,
approx_samples=approx_samples,
)
if result != -1:
# if result == -1, then you never get anything beyond cutoff
samples_array.append(result)
j = j + 1
return np.vstack(samples_array)
def hafnian_sample_state(
cov,
samples,
mean=None,
hbar=2,
cutoff=5,
max_photons=30,
approx=False,
approx_samples=1e5,
pool=False,
):
r"""Returns samples from the Hafnian of a Gaussian state.
Args:
cov (array): a :math:`2N\times 2N` ``np.float64`` covariance matrix
representing an :math:`N` mode quantum state. This can be obtained
via the ``scovmavxp`` method of the Gaussian backend of Strawberry Fields.
samples (int): the number of samples to return.
mean (array): a :math:`2N`` ``np.float64`` vector of means representing the Gaussian
state.
hbar (float): (default 2) the value of :math:`\hbar` in the commutation
relation :math:`[\x,\p]=i\hbar`.
cutoff (int): the Fock basis truncation.
max_photons (int): specifies the maximum number of photons that can be counted.
approx (bool): if ``True``, the :func:`~.hafnian_approx` function is used
to approximate the hafnian. Note that this can only be used for
real, non-negative matrices.
approx_samples: the number of samples used to approximate the hafnian if ``approx=True``.
pool (bool): if ``True``, uses ``multiprocessor.Pool`` for parallelization of samples
Returns:
np.array[int]: photon number samples from the Gaussian state
"""
if not pool:
params = [cov, samples, mean, hbar, cutoff, max_photons, approx, approx_samples]
return _hafnian_sample(params)
pool = Pool()
nprocs = multiprocessing.cpu_count()
localsamps = samples // nprocs
params = [[cov, localsamps, mean, hbar, cutoff, max_photons, approx, approx_samples]] * (nprocs - 1)
params.append(
[
cov,
samples - localsamps * (nprocs - 1),
mean,
hbar,
cutoff,
max_photons,
approx,
approx_samples,
]
)
result = np.vstack(pool.map(_hafnian_sample, params))
pool.close() # no more tasks
pool.join() # wrap up current tasks
return result
def hafnian_sample_graph(
A, n_mean, samples=10, cutoff=5, max_photons=30, approx=False, approx_samples=1e5, pool=False
):
r"""Returns samples from the Gaussian state specified by the adjacency matrix :math:`A`
and with total mean photon number :math:`n_{mean}`
Args:
A (array): a :math:`N\times N` ``np.float64`` (symmetric) adjacency matrix matrix
n_mean (float): mean photon number of the Gaussian state
samples (int): the number of samples to return.
cutoff (int): the Fock basis truncation.
max_photons (int): specifies the maximum number of photons that can be counted.
approx (bool): if ``True``, the approximate hafnian algorithm is used.
Note that this can only be used for real, non-negative matrices.
approx_samples: the number of samples used to approximate the hafnian if ``approx=True``.
pool (bool): if ``True``, uses ``multiprocessor.Pool`` for parallelization of samples
Returns:
np.array[int]: photon number samples from the Gaussian state
"""
Q = gen_Qmat_from_graph(A, n_mean)
cov = Covmat(Q)
return hafnian_sample_state(
cov,
samples,
mean=None,
hbar=2,
cutoff=cutoff,
max_photons=max_photons,
approx=approx,
approx_samples=approx_samples,
pool=pool,
)
def seed(seed_val=None):
r""" Seeds the random number generator used in the sampling algorithms.
This function is a wrapper around ``numpy.random.seed()``. By setting the seed
to a specific integer, the sampling algorithms will exhibit deterministic behaviour.
Args:
seed_val (int): Seed for RandomState. Must be convertible to 32 bit unsigned integers.
"""
np.random.seed(seed_val)
and I have changed the package version as follows
The Walrus: a Python library for for the calculation of hafnians, Hermite polynomials, and Gaussian boson sampling.
Copyright 2018-2021 Xanadu Quantum Technologies Inc.
Python version: 3.10.9
Platform info: macOS-13.4.1-arm64-arm-64bit
Installation path: /Users/ryuminseok/anaconda3/lib/python3.10/site-packages/thewalrus
The Walrus version: 0.20.0
Numpy version: 1.23.5
Scipy version: 1.11.0
SymPy version: 1.12
Numba version: 0.57.1
But I keep seeing this behavior
/Users/ryuminseok/anaconda3/lib/python3.10/site-packages/numpy/linalg/linalg.py:2154: RuntimeWarning: divide by zero encountered in det
r = _umath_linalg.det(a, signature=signature)
/Users/ryuminseok/anaconda3/lib/python3.10/site-packages/numpy/linalg/linalg.py:2154: RuntimeWarning: invalid value encountered in det
r = _umath_linalg.det(a, signature=signature)
OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.
/Users/ryuminseok/anaconda3/lib/python3.10/site-packages/numpy/linalg/linalg.py:2154: RuntimeWarning: divide by zero encountered in det
r = _umath_linalg.det(a, signature=signature)
/Users/ryuminseok/anaconda3/lib/python3.10/site-packages/numpy/linalg/linalg.py:2154: RuntimeWarning: invalid value encountered in det
r = _umath_linalg.det(a, signature=signature)
Can this be because of the specific property of the matrix that I fed into hafnium_sample_graph
as s=hafnian_sample_graph(matrix,6)
?
from thewalrus.
@minseok1999 Let's stick with the simpler example here:
import numpy as np
from thewalrus.samples import hafnian_sample_graph
matrix = np.array(
[
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 0, 0, 1, 0],
[1, 1, 1, 1, 1, 1, 0, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
]
) - np.eye(10)
s = hafnian_sample_graph(matrix, 6, samples=10)
print(s)
Can you provide the entire error traceback when you try to run this? Don't leave anything out π
from thewalrus.
@minseok1999 Let's stick with the simpler example here:
import numpy as np from thewalrus.samples import hafnian_sample_graph matrix = np.array( [ [1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 0, 0, 1, 0], [1, 1, 1, 1, 1, 1, 0, 1, 0, 0], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1], ] ) - np.eye(10) s = hafnian_sample_graph(matrix, 6, samples=10) print(s)
Can you provide the entire error traceback when you try to run this? Don't leave anything out π
I have tried your simpler form and I got
OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.
[[0 0 0 0 0 0 0 0 0 0]
[1 0 1 1 2 0 0 1 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 1 1 0 0 0]
[3 2 3 0 3 1 0 0 0 0]
[4 4 2 1 5 4 0 0 0 0]
[3 2 1 3 0 4 1 0 0 0]
[1 1 1 1 1 1 0 0 0 0]
[2 1 0 1 2 0 0 0 0 0]
[1 0 1 0 0 0 0 0 0 0]]
without the division by zero error anymore. Why is this like this? Should I not be fidgeting with the fixed library? Only change I made to the library was to change the number of samples explicitly in the definition of hafnian_sample_graph itself π
And what is going on with this nested routine deprecation in this case?
from thewalrus.
He @minseok1999, I asked some other folks internally to try and replicate the behaviour you're getting, and nobody is able to β everyone can run this code without error. A couple things you can try:
- use a Google colab session
- Start over with a fresh virtual environment and install the packages you need
Let me know if either of those work!
from thewalrus.
I have tried google colab as you advised and this works cleanly without error.
And by creating a new file without redefining library myself and reinstalling thewalrus library in that new file (pip install thewalrus) I could see that it works fine and I could get result of hafnian_sample_graph without error. (Before the renewing of the library using pip install thewalrus this nested routine deprecation message persisted)
I wish I could figure out why this message
"OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead"
or " divide by zero error"
occurs or locate where the clash happens when I copy and paste from the original library and slightly modify the definition itself in my own Jupyter Notebook, but I ain't an expert on how the library structure works in Jupyter Notebook so I'd better be satisfied with the clean result from sticking to your simpler code with renewed installation of thewalrus libraryπ
from thewalrus.
Awesome! Glad you got this solved π. Sometimes virtual environments get "messed up" and need a refresh just like anything else would π .
from thewalrus.
Related Issues (20)
- Convenience functions to change ordering of quadratures HOT 1
- Why is hbar=2? Physicist may assume hbar=1 HOT 1
- P ( [ β ] ) is not defined. Is it the power set of (0, 1, ...l-1)? HOT 9
- [Thewalrus documentation] The figures in "Basics of Hafnians and Loop Hafnians" are missing HOT 7
- Random interferometer is already implemented in scipy
- [Thewalrus installation] Can not install the version later than 0.15.0 HOT 11
- Add support for calculating the permanent using the BBFG algorithm HOT 4
- Recursive calculation of threshold probabilitites HOT 4
- FTBFS 0.16.2 on aarch64 HOT 5
- I have searched exisisting GitHub issues to make sure the issue does not already exist. HOT 1
- The Qmat functions is off by a complex conjugate
- Library hard crashing when computing BBFG permanent with a 0x0 matrix HOT 4
- Optional arguments in `passive_transformation`
- n_body_marginals is not symmetric
- Displaced torontonian sampling time increase HOT 11
- Tests fail to run: error: unrecognized arguments: --randomly-seed=137 HOT 1
- Banded hafnian algorithm HOT 1
- Default method fails on poorly conditioned matrices HOT 4
- Glynn method has an weird prefactor HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from thewalrus.