Skip to content

Commit

Permalink
Fix issues raised by pylint (#205)
Browse files Browse the repository at this point in the history
* all pylint issues in tests/

* state_props:eof

* python install

* pylint userwarning

* remove exception and from future annotations

* import lines

* matrix_props/is_positive_def

* fixes Make parameter typing consistent in doc examples #209

* state_metrics/fid_of_sep

* channel_props/is_trace_preserving

* nonlocalgame

* useless suppression

* quick fixes

* all redefinition disabled

* all unsubscriptable object

* possibly unbalanced tuples

* unnecessary-list-index-lookup

* black reformatter no pylint issues

* black reformatter pylint issues

* test useless supression

* Fixes #205 (comment)

* Fixes #205 (comment)

* Fixes #205 (comment)

* fixes #205 (comment) + black reformatter
  • Loading branch information
purva-thakre committed Oct 31, 2023
1 parent 74f8b85 commit ade9c8a
Show file tree
Hide file tree
Showing 43 changed files with 177 additions and 167 deletions.
6 changes: 3 additions & 3 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ unsafe-load-any-extension=no
extension-pkg-allow-list=

# Minimum supported python version
py-version = 3.7.2
py-version = 3.10

# Control the amount of potential inferred values when inferring a single
# object. This can help the performance when dealing with large functions or
Expand Down Expand Up @@ -204,7 +204,7 @@ redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
[FORMAT]

# Maximum number of characters on a single line.
max-line-length=100
max-line-length=120

# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
Expand Down Expand Up @@ -513,7 +513,7 @@ preferred-modules=

# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception
overgeneral-exceptions=builtins.Exception


[TYPING]
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ keywords = ["quantum information", "quantum computing", "nonlocal games"]


[tool.poetry.dependencies]
python = "^3.9"
python = "^3.10"
cvxpy = "^1.2.1"
cvxopt = "^1.2.5"
numpy = "^1.19.4"
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
with open("README.md", "r") as fh:
long_description = fh.read()

requirements = ["cvx", "cvxpy", "numpy", "picos", "scipy", "scikit-image"]
requirements = ["cvx", "cvxpy", "cvxopt", "numpy", "picos", "scipy", "scikit-image", "pytest", "pytest-cov"]

setuptools.setup(
name="toqito",
Expand All @@ -23,7 +23,7 @@
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
],
python_requires=">=3.9",
python_requires=">=3.10",
install_requires=requirements,
test_suite="tests",
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_cb_trace_norm_unitaries_channel():
"""The diamond norm of phi = id- U id U* is the diameter of the smallest circle that contains the eigenvalues of U."""
U = 1 / np.sqrt(2) * np.array([[1, 1], [-1, 1]]) # Hadamard gate
phi = kraus_to_choi([[np.eye(2), np.eye(2)], [U, -U]])
lam, eigv = np.linalg.eig(U)
lam, _ = np.linalg.eig(U)
dist = np.abs(lam[:, None] - lam[None, :]) # all to all distance
diameter = np.max(dist)
np.testing.assert_equal(
Expand Down
4 changes: 2 additions & 2 deletions tests/test_channel_ops/test_dual_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ def test_dual_channel_choi_dims():

def test_dual_channel_nonsquare_matrix():
"""Dual of a channel that transposes 3x2 matrices."""
choi = swap_operator([2, 3])
choi_dual = dual_channel(choi, dims=[[3, 2], [2, 3]])
choi1 = swap_operator([2, 3])
choi_dual = dual_channel(choi1, dims=[[3, 2], [2, 3]])
expected_choi_dual = np.array(
[
[1, 0, 0, 0, 0, 0],
Expand Down
1 change: 0 additions & 1 deletion tests/test_nonlocal_games/test_xor_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import numpy as np

from toqito.nonlocal_games.nonlocal_game import NonlocalGame
from toqito.nonlocal_games.xor_game import XORGame


Expand Down
2 changes: 1 addition & 1 deletion toqito/channel_metrics/completely_bounded_trace_norm.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def completely_bounded_trace_norm(phi: np.ndarray) -> float:
if is_quantum_channel(phi):
return 1

elif is_completely_positive(phi):
if is_completely_positive(phi):
v = apply_channel(np.eye(dim_ly), dual_channel(phi))
return trace_norm(v)

Expand Down
43 changes: 22 additions & 21 deletions toqito/channel_metrics/fidelity_of_separability.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@


def fidelity_of_separability(
psi: np.ndarray, psi_dims: list[int], k: int = 1, verbosity_option=2, solver_option="cvxopt"
psi: np.ndarray,
psi_dims: list[int],
k: int = 1,
verbosity_option: int = 2,
solver_option: str = "cvxopt",
) -> float:
r"""
Define the first benchmark introduced in Appendix I of [Phil23.1]_ .
Expand Down Expand Up @@ -113,28 +117,25 @@ def fidelity_of_separability(
“The Theory of Quantum Information”
Cambridge University Press, 2018
Args:
psi: the density matrix for the tripartite state of interest psi_{BAR}
psi_dims: the dimensions of System A, B, & R in
:param psi: the density matrix for the tripartite state of interest psi_{BAR}
:param psi_dims: the dimensions of System A, B, & R in
the input state density matrix. It is assumed that the first
quantity in this list is the dimension of System B.
k: value for k-extendibility.
verbosity_option: Parameter option for `picos`. Default value is `verbosity = 2`.
For more info, visit https://picos-api.gitlab.io/picos/api/picos.modeling.options.html#option-verbosity
solver_option: Optimization option for `picos` solver. Default option is `solver_option="cvxopt"`
For more info, visit https://picos-api.gitlab.io/picos/api/picos.modeling.options.html#option-solver
Raises:
AssertionError:
* If the provided dimensions are not for a tripartite density
matrix.
TypeError:
* If the matrix is not a density matrix (square matrix that is \n
PSD with trace 1).
TypeError:
* If the input state is a mixed state.
Returns:
Optimized value of the SDP when maximized over a set of linear
operators subject to some constraints.
:param k: value for k-extendibility.
:param verbosity_option: Parameter option for `picos`. Default value is
`verbosity = 2`. For more info, visit
https://picos-api.gitlab.io/picos/api/picos.modeling.options.html#option-verbosity.
:param solver_option: Optimization option for `picos` solver. Default option is
`solver_option="cvxopt"`. For more info, visit
https://picos-api.gitlab.io/picos/api/picos.modeling.options.html#option-solver.
:raises AssertionError: If the provided dimensions are not for a tripartite density matrix.
:raises ValueError: If the matrix is not a density matrix (square matrix that
is PSD with trace 1).
:raises ValueError: the input state is entangled.
:raises ValueError: the input state is a mixed state.
:return: Optimized value of the SDP when maximized over a set of linear
operators subject to some constraints.
"""
if not is_density(psi):
raise ValueError("Provided input state is not a density matrix.")
Expand Down
1 change: 0 additions & 1 deletion toqito/channel_ops/dual_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import numpy as np

from toqito.helper import channel_dim
from toqito.matrix_props import is_square
from toqito.perms import swap


Expand Down
7 changes: 3 additions & 4 deletions toqito/channel_props/is_trace_preserving.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ def is_trace_preserving(
k_r = np.concatenate(phi_r, axis=0)

mat = k_l.conj().T @ k_r
elif dim is None:
mat = partial_trace(phi, [sys - 1])
else:
if dim == None:
mat = partial_trace(phi, [sys - 1])
else:
mat = partial_trace(phi, [sys - 1], dim)
mat = partial_trace(phi, [sys - 1], dim)
return is_identity(np.array(mat), rtol=rtol, atol=atol)
13 changes: 7 additions & 6 deletions toqito/channels/partial_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

def partial_trace(
input_mat: np.ndarray | Variable,
sys: int | list[int] = [1],
sys: int | list[int] = None,
dim: int | list[int] = None,
) -> np.ndarray | Expression:
r"""
Expand Down Expand Up @@ -130,6 +130,9 @@ def partial_trace(
equal.
:return: The partial trace of matrix :code:`input_mat`.
"""
if not isinstance(sys, int):
if sys is None:
sys = [1]
# If the input matrix is a CVX variable for an SDP, we convert it to a numpy array,
# perform the partial trace, and convert it back to a CVX variable.
if isinstance(input_mat, Variable):
Expand All @@ -145,10 +148,8 @@ def partial_trace(
if isinstance(dim, list):
dim = np.array(dim)

num_sys = len(dim)

# Allow the user to enter a single number for dim.
if num_sys == 1:
if (num_sys := len(dim)) == 1:
dim = np.array([dim[0], len(input_mat) / dim[0]])
if np.abs(dim[1] - np.round(dim[1])) >= 2 * len(input_mat) * np.finfo(float).eps:
raise ValueError(
Expand All @@ -166,7 +167,7 @@ def partial_trace(
for idx in sys:
prod_dim_sys *= dim[idx]
elif isinstance(sys, int):
prod_dim_sys = np.prod(dim[sys])
prod_dim_sys = np.prod(dim[sys]) # pylint: disable=redefined-variable-type
else:
raise ValueError(
"Invalid: The variable `sys` must either be of type int or of a list of ints."
Expand All @@ -176,7 +177,7 @@ def partial_trace(
sub_sys_vec = prod_dim * np.ones(int(sub_prod)) / sub_prod

if isinstance(sys, list):
sys = np.array(sys)
sys = np.array(sys) # pylint: disable=redefined-variable-type
if isinstance(sys, int):
sys = np.array([sys])
set_diff = list(set(list(range(1, num_sys + 1))) - set(sys + 1))
Expand Down
10 changes: 6 additions & 4 deletions toqito/channels/partial_transpose.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

def partial_transpose(
rho: np.ndarray | Variable,
sys: list[int] | np.ndarray | int = [1],
sys: list[int] | np.ndarray | int = None,
dim: list[int] | np.ndarray = None,
) -> np.ndarray | Expression:
r"""Compute the partial transpose of a matrix [WikPtrans]_.
Expand Down Expand Up @@ -113,6 +113,9 @@ def partial_transpose(
:raises ValueError: If matrix dimensions are not square.
:returns: The partial transpose of matrix :code:`rho`.
"""
if not isinstance(sys, int):
if sys is None:
sys = [1]
# If the input matrix is a CVX variable for an SDP, we convert it to a
# numpy array, perform the partial transpose, and convert it back to a CVX
# variable.
Expand All @@ -131,13 +134,12 @@ def partial_transpose(
if isinstance(dim, list):
dim = np.array(dim)
if isinstance(sys, list):
sys = np.array(sys)
sys = np.array(sys) # pylint: disable=redefined-variable-type
if isinstance(sys, int):
sys = np.array([sys])

num_sys = max(dim.shape)
# Allow the user to enter a single number for dim.
if num_sys == 1:
if (num_sys := max(dim.shape)) == 1:
dim = np.array([dim, list(rho.shape)[0] / dim])
if np.abs(dim[1] - np.round(dim[1]))[0] >= 2 * list(rho.shape)[0] * np.finfo(float).eps:
raise ValueError(
Expand Down
2 changes: 1 addition & 1 deletion toqito/channels/realignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def realignment(input_mat: np.ndarray, dim: int | list[int] = None) -> np.ndarra
dim = np.array([dim, dim])

dim_x = np.array([[dim[0][1], dim[0][0]], [dim[1][0], dim[1][1]]])
dim_x = np.int_(dim_x)
dim_x = np.int_(dim_x) # pylint: disable=redefined-variable-type
dim_y = np.array([[dim[1][0], dim[0][0]], [dim[0][1], dim[1][1]]])

x_tmp = swap(input_mat, [1, 2], dim, True)
Expand Down
2 changes: 1 addition & 1 deletion toqito/helper/npa_hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def _get_nonlocal_game_params(
return a_out, a_in, b_out, b_in


def npa_constraints(
def npa_constraints( # pylint: disable=too-many-locals
assemblage: dict[tuple[int, int], cvxpy.Variable], k: int | str = 1, referee_dim: int = 1
) -> list[cvxpy.constraints.constraint.Constraint]:
r"""
Expand Down
2 changes: 1 addition & 1 deletion toqito/matrices/pauli.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def pauli(
pauli_mat = np.identity(2)

if is_sparse:
pauli_mat = sparse.csr_matrix(pauli_mat)
pauli_mat = sparse.csr_matrix(pauli_mat) # pylint: disable=redefined-variable-type

return pauli_mat

Expand Down
3 changes: 2 additions & 1 deletion toqito/matrix_ops/inner_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def inner_product(v1: np.ndarray, v2: np.ndarray) -> float:
https://en.wikipedia.org/wiki/Inner_product_space
:raises ValueError: Vector dimensions are mismatched.
:param args: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:param v1: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:param v2: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:return: The computed inner product.
"""
# Check for dimensional validity
Expand Down
3 changes: 2 additions & 1 deletion toqito/matrix_ops/outer_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ def outer_product(v1: np.ndarray, v2: np.ndarray) -> np.ndarray:
https://en.wikipedia.org/wiki/Outer_product
:raises ValueError: Vector dimensions are mismatched.
:param args: v1 and v2, both vectors of dimensions :math:`(n,1)` where :math:`n>1`.
:param v1: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:param v2: v1 and v2, both vectors of dimenstions :math:`(n,1)` where :math:`n>1`.
:return: The computed outer product.
"""
# Check for dimensional validity
Expand Down
8 changes: 6 additions & 2 deletions toqito/matrix_ops/vectors_from_gram_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@


def vectors_from_gram_matrix(gram: np.ndarray) -> list[np.ndarray]:
"""Obtain the corresponding ensemble of states from the Gram matrix."""
"""Obtain the corresponding ensemble of states from the Gram matrix.
:param gram: Input Gram matrix.
:return: list of ensemble states
"""
dim = gram.shape[0]
# If matrix is PD, can do Cholesky decomposition:
try:
decomp = np.linalg.cholesky(gram)
return [decomp[i][:] for i in range(dim)]
# Otherwise, need to do eigendecomposition:
except Exception:
except np.linalg.LinAlgError:
print("Matrix is not positive semidefinite. Using eigendecomposition as alternative.")
d, v = np.linalg.eig(gram)
return [np.sqrt(np.diag(d)) @ v[i].conj().T for i in range(dim)]
1 change: 0 additions & 1 deletion toqito/matrix_props/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,5 @@
from toqito.matrix_props.majorizes import majorizes
from toqito.matrix_props.sk_norm import sk_operator_norm
from toqito.matrix_props.is_block_positive import is_block_positive
from toqito.matrix_props.is_orthonormal import is_orthonormal
from toqito.matrix_props.trace_norm import trace_norm
from toqito.matrix_props.is_diagonally_dominant import is_diagonally_dominant
2 changes: 1 addition & 1 deletion toqito/matrix_props/is_block_positive.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def is_block_positive(

# Allow the user to enter in a single integer for dimension.
if isinstance(dim, int):
dim = np.array([dim, dim_xy / dim])
dim = np.array([dim, dim_xy / dim]) # pylint: disable=redefined-variable-type
if np.abs(dim[1] - np.round(dim[1])) >= 2 * dim_xy * np.finfo(float).eps:
raise ValueError(
"If `dim` is a scalar, it must evenly divide the length of the matrix."
Expand Down
6 changes: 2 additions & 4 deletions toqito/matrix_props/is_positive_definite.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Is matrix a positive definite matrix."""
import numpy as np

from toqito.matrix_props import is_hermitian
from toqito.matrix_props import is_hermitian # pylint: disable=unused-import


def is_positive_definite(mat: np.ndarray, rtol: float = 1e-05, atol: float = 1e-08) -> bool:
def is_positive_definite(mat: np.ndarray) -> bool:
r"""
Check if matrix is positive definite (PD) [WikPD]_.
Expand Down Expand Up @@ -54,8 +54,6 @@ def is_positive_definite(mat: np.ndarray, rtol: float = 1e-05, atol: float = 1e-
https://en.wikipedia.org/wiki/Definiteness_of_a_matrix
:param mat: Matrix to check.
:param rtol: The relative tolerance parameter (default 1e-05).
:param atol: The absolute tolerance parameter (default 1e-08).
:return: Return :code:`True` if matrix is positive definite, and :code:`False` otherwise.
"""
if np.array_equal(mat, mat.conj().T):
Expand Down
Loading

0 comments on commit ade9c8a

Please sign in to comment.