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

Ruff format #510

Merged
merged 12 commits into from
Mar 14, 2024
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/build-test-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
python -m pip install --upgrade pip
pip install poetry
poetry install --no-interaction
- name: Code Analyzer Checks
- name: Additional linter/formatter checks
run: |
poetry run pylint --fail-under=10.0 toqito/

Expand Down
19 changes: 9 additions & 10 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@
"sphinx.ext.githubpages",
"sphinx.ext.napoleon",
"sphinxcontrib.bibtex",
"sphinx_wagtail_theme"
"sphinx_wagtail_theme",
]

bibtex_bibfiles = ["books.bib", "articles.bib"]
bibtex_default_style = "unsrt"
suppress_warnings = ["bibtex.duplicate_label", "bibtex.duplicate_citation"]
# we need to skip these warnigns because all the references appear twice, in a function docstring
# and on the references page.
# and on the references page.
master_doc = "index"
# autosummary_generate = True
# autodoc_typehints = "none"
autoapi_dirs = ['../toqito']
autoapi_type = 'python'
autoapi_dirs = ["../toqito"]
autoapi_type = "python"
autoapi_ignore = [
"*/channel_metrics/tests/*",
"*/rand/tests/*",
Expand All @@ -74,8 +74,9 @@
"*/states/tests/*",
"*/channel_props/tests/*",
"*/measurement_ops/tests/*",
"*/measurement_props/tests/*"]
autodoc_typehints = 'description'
"*/measurement_props/tests/*",
]
autodoc_typehints = "description"
autoapi_add_toctree_entry = False
autoapi_keep_files = False

Expand All @@ -94,7 +95,7 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.

html_theme = 'sphinx_wagtail_theme'
html_theme = "sphinx_wagtail_theme"
html_logo = "figures/logo.svg"
html_favicon = "figures/favicon.ico"

Expand All @@ -106,9 +107,7 @@

# This github_url will point to the appropriate page in the default branch.
# Ex: Getting Started -> https://github.com/vprusso/toqito/blob/master/docs/getting_started.rst
html_theme_options = dict(
github_url = "https://github.com/vprusso/toqito/blob/master/docs/"
)
html_theme_options = dict(github_url="https://github.com/vprusso/toqito/blob/master/docs/")

# Show in footer when the docs were last updated.
html_last_updated_fmt = "%b %d, %Y"
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ ignore = ["D407", "D203", "D213", "D416", "PLR0912", "PLR0911", "PLR0915", "PLR2
# PLR0915 -- Checks for functions or methods with too many statements. The default number is 50.
# PLR2004 -- Checks if an equality or an inequality is compared to a variable or a num (prefers variable pre)
# PLR0913 Too many arguments in function definition

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["I001"]
# I001 - skip checking Import block is un-sorted or un-formatted
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"pytest",
"pytest-cov",
"qiskit",
"scs"
"scs",
]

setuptools.setup(
Expand Down
1 change: 1 addition & 0 deletions toqito/channel_metrics/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Distance metrics for quantum channels."""

from toqito.channel_metrics.channel_fidelity import channel_fidelity
from toqito.channel_metrics.diamond_norm import diamond_norm
from toqito.channel_metrics.fidelity_of_separability import fidelity_of_separability
Expand Down
1 change: 1 addition & 0 deletions toqito/channel_metrics/channel_fidelity.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Compute the channel fidelity between two quantum channels."""

import cvxpy
import numpy as np

Expand Down
1 change: 1 addition & 0 deletions toqito/channel_metrics/completely_bounded_spectral_norm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Compute the completely bounded spectral norm of a quantum channel."""

import numpy as np

from toqito.channel_metrics import completely_bounded_trace_norm
Expand Down
8 changes: 3 additions & 5 deletions toqito/channel_metrics/completely_bounded_trace_norm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Compute the completely bounded trace norm of a quantum channel."""

import cvxpy as cp
import numpy as np

Expand Down Expand Up @@ -41,9 +42,7 @@ def completely_bounded_trace_norm(phi: np.ndarray) -> float:
dim_lx, dim_ly = phi.shape

if dim_lx != dim_ly:
raise ValueError(
"The input and output spaces of the superoperator phi must both be square."
)
raise ValueError("The input and output spaces of the superoperator phi must both be square.")

if is_quantum_channel(phi):
return 1
Expand All @@ -65,8 +64,7 @@ def completely_bounded_trace_norm(phi: np.ndarray) -> float:
a_var = cp.bmat([[y0, -phi], [-phi.conj().T, y1]])
constraints += [a_var >> 0]
objective = cp.Minimize(
cp.norm(cp.partial_trace(y0, dims=(dim, dim), axis=1))
+ cp.norm(cp.partial_trace(y1, dims=(dim, dim), axis=1))
cp.norm(cp.partial_trace(y0, dims=(dim, dim), axis=1)) + cp.norm(cp.partial_trace(y1, dims=(dim, dim), axis=1))
)

problem = cp.Problem(objective, constraints)
Expand Down
1 change: 1 addition & 0 deletions toqito/channel_metrics/diamond_norm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Compute the diamond norm between two quantum channels."""

import cvxpy
import numpy as np

Expand Down
10 changes: 3 additions & 7 deletions toqito/channel_metrics/fidelity_of_separability.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def fidelity_of_separability(

# List of extenstion systems and dimension of the Choi matrix.
sys_ext = list(range(2, 2 + k - 1))
dim_choi = dim_r * (dim_a ** k)
dim_choi = dim_r * (dim_a**k)

# Projection onto symmetric subspace on AA'.
pi_sym = symmetric_projection(dim_a, 2)
Expand All @@ -163,19 +163,15 @@ def fidelity_of_separability(
pi_sym
* picos.partial_trace(
(picos.partial_transpose(psi, [0], psi_dims) @ picos.I(dim_a))
* permute_systems(
choi_partial @ picos.I(dim_b * dim_a), [1, 4, 3, 2], dim_list
),
* permute_systems(choi_partial @ picos.I(dim_b * dim_a), [1, 4, 3, 2], dim_list),
[0, 2],
dim_list,
)
)
),
)

problem.add_constraint(
picos.partial_trace(choi, list(range(1, k + 1)), choi_dims) == picos.I(dim_r)
)
problem.add_constraint(picos.partial_trace(choi, list(range(1, k + 1)), choi_dims) == picos.I(dim_r))
problem.add_constraint(choi >> 0)

# k-extendablility of Choi state
Expand Down
37 changes: 25 additions & 12 deletions toqito/channel_metrics/tests/test_channel_fidelity.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Tests for channel_fidelity."""

import numpy as np
import pytest

Expand All @@ -8,24 +9,36 @@
dephasing_channel = dephasing(4)
depolarizing_channel = depolarizing(4)

@pytest.mark.parametrize("input1, input2, expected_value", [
# fidelity of identical channels
(dephasing_channel, dephasing_channel, 1),
# fidelity of different channels
(dephasing_channel, depolarizing_channel, 1/2)])

@pytest.mark.parametrize(
"input1, input2, expected_value",
[
# fidelity of identical channels
(dephasing_channel, dephasing_channel, 1),
# fidelity of different channels
(dephasing_channel, depolarizing_channel, 1 / 2),
],
)
def test_channel_fidelity(input1, input2, expected_value):
"""Test functions works as expected for valid inputs."""
calculated_value = channel_fidelity(input1, input2)
assert pytest.approx(expected_value, 1e-3) == calculated_value


@pytest.mark.parametrize("input1, input2, expected_msg", [
# Inconsistent dimensions between Choi matrices
(depolarizing_channel, depolarizing(2), "The Choi matrices provided should be of equal dimension."),
# Non-square inputs for channel fidelity
(np.array([[1, 2, 3], [4, 5, 6]]), np.array([[1, 2, 3], [4, 5, 6]]), "The Choi matrix provided must be square.")])
@pytest.mark.parametrize(
"input1, input2, expected_msg",
[
# Inconsistent dimensions between Choi matrices
(depolarizing_channel, depolarizing(2), "The Choi matrices provided should be of equal dimension."),
# Non-square inputs for channel fidelity
(
np.array([[1, 2, 3], [4, 5, 6]]),
np.array([[1, 2, 3], [4, 5, 6]]),
"The Choi matrix provided must be square.",
),
],
)
def test_channel_fidelity_raises_error(input1, input2, expected_msg):
"""Test functions works as expected for valid inputs."""
with pytest.raises(ValueError, match = expected_msg):
with pytest.raises(ValueError, match=expected_msg):
channel_fidelity(input1, input2)

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Tests for completely_bounded_spectral_norm."""


from toqito.channel_metrics import (
completely_bounded_spectral_norm,
completely_bounded_trace_norm,
Expand Down
19 changes: 12 additions & 7 deletions toqito/channel_metrics/tests/test_completely_bounded_trace_norm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Tests for completely_bounded_trace_norm."""

import numpy as np
import pytest

Expand All @@ -14,13 +15,17 @@
diameter = np.max(dist)


@pytest.mark.parametrize("test_input, expected", [
# The diamond norm of a quantum channel is 1
(dephasing(2), 1),
# the diamond norm of a CP map
(np.eye(4), 4.0),
# unitaries channel, phi, diameter in terms of the eigenvalues of U
(phi, diameter)])
@pytest.mark.parametrize(
"test_input, expected",
[
# The diamond norm of a quantum channel is 1
(dephasing(2), 1),
# the diamond norm of a CP map
(np.eye(4), 4.0),
# unitaries channel, phi, diameter in terms of the eigenvalues of U
(phi, diameter),
],
)
def test_cb_trace_norm(test_input, expected):
"""Test function works as expected for valid inputs."""
calculated_value = completely_bounded_trace_norm(test_input)
Expand Down
36 changes: 24 additions & 12 deletions toqito/channel_metrics/tests/test_diamond_norm.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
"""Tests for diamond_norm."""

import numpy as np
import pytest

from toqito.channel_metrics import diamond_norm
from toqito.channels import dephasing, depolarizing


@pytest.mark.parametrize("test_input1, test_input_2, expected", [
# The diamond norm of identical channels should yield 0
(dephasing(2), dephasing(2), 0),
# the diamond norm of different channels
(dephasing(2), depolarizing(2), 1)])
@pytest.mark.parametrize(
"test_input1, test_input_2, expected",
[
# The diamond norm of identical channels should yield 0
(dephasing(2), dephasing(2), 0),
# the diamond norm of different channels
(dephasing(2), depolarizing(2), 1),
],
)
def test_diamond_norm_valid_inputs(test_input1, test_input_2, expected):
"""Test function works as expected for valid inputs."""
calculated_value = diamond_norm(test_input1, test_input_2)
assert pytest.approx(expected, 1e-3) == calculated_value


@pytest.mark.parametrize("test_input1, test_input_2, expected_msg", [
# Inconsistent dimensions between Choi matrices
(depolarizing(4), dephasing(2), "The Choi matrices provided should be of equal dimension."),
# Non-square inputs for diamond norm
(np.array([[1, 2, 3], [4, 5, 6]]), np.array([[1, 2, 3], [4, 5, 6]]), "The Choi matrix provided must be square.")])
@pytest.mark.parametrize(
"test_input1, test_input_2, expected_msg",
[
# Inconsistent dimensions between Choi matrices
(depolarizing(4), dephasing(2), "The Choi matrices provided should be of equal dimension."),
# Non-square inputs for diamond norm
(
np.array([[1, 2, 3], [4, 5, 6]]),
np.array([[1, 2, 3], [4, 5, 6]]),
"The Choi matrix provided must be square.",
),
],
)
def test_diamond_norm_invalid_inputs(test_input1, test_input_2, expected_msg):
"""Test function raises error as expected for invalid inputs."""
with pytest.raises(ValueError, match = expected_msg):
with pytest.raises(ValueError, match=expected_msg):
diamond_norm(test_input1, test_input_2)

15 changes: 10 additions & 5 deletions toqito/channel_metrics/tests/test_fidelity_of_separability.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@

mixed_rho = max_mixed(8, is_sparse=False)

@pytest.mark.parametrize("test_input, input_dim, expected_msg, expected_error", [
(bad_rho, [2, 2, 2], "Provided input state is not a density matrix.", ValueError),
(purification_state, [2, 2], "For Channel SDP: require tripartite state dims.", AssertionError),
(mixed_rho, [2, 2, 2], "This function only works for pure states.", ValueError)])

@pytest.mark.parametrize(
"test_input, input_dim, expected_msg, expected_error",
[
(bad_rho, [2, 2, 2], "Provided input state is not a density matrix.", ValueError),
(purification_state, [2, 2], "For Channel SDP: require tripartite state dims.", AssertionError),
(mixed_rho, [2, 2, 2], "This function only works for pure states.", ValueError),
],
)
def test_errors_channel_SDP(test_input, input_dim, expected_msg, expected_error):
"""Tests for raised errors in channel SDP function."""
with pytest.raises(expected_error, match = expected_msg):
with pytest.raises(expected_error, match=expected_msg):
fidelity_of_separability(test_input, input_dim)


Expand Down
1 change: 1 addition & 0 deletions toqito/channel_ops/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""A number of operations on quantum channels."""

from toqito.channel_ops.apply_channel import apply_channel
from toqito.channel_ops.partial_channel import partial_channel
from toqito.channel_ops.choi_to_kraus import choi_to_kraus
Expand Down
6 changes: 1 addition & 5 deletions toqito/channel_ops/apply_channel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Apply channel to an operator."""


import itertools

import numpy as np
Expand Down Expand Up @@ -147,7 +146,4 @@ def apply_channel(mat: np.ndarray, phi_op: np.ndarray | list[list[np.ndarray]])
order="F",
)
return a_mat @ b_mat
raise ValueError(
"Invalid: The variable `phi_op` must either be a list of "
"Kraus operators or as a Choi matrix."
)
raise ValueError("Invalid: The variable `phi_op` must either be a list of Kraus operators or as a Choi matrix.")
4 changes: 1 addition & 3 deletions toqito/channel_ops/choi_to_kraus.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Compute a list of Kraus operators from the Choi matrix."""


import numpy as np

from toqito.helper import channel_dim
Expand Down Expand Up @@ -108,8 +107,7 @@ def choi_to_kraus(
return kraus_0

kraus_1 = [
np.sign(eigval) * k_mat
for eigval, k_mat in zip(filter(lambda eigval: abs(eigval) > tol, eigvals), kraus_0)
np.sign(eigval) * k_mat for eigval, k_mat in zip(filter(lambda eigval: abs(eigval) > tol, eigvals), kraus_0)
]
else:
u_mat, singular_values, vh_mat = np.linalg.svd(choi_mat, full_matrices=False)
Expand Down
6 changes: 1 addition & 5 deletions toqito/channel_ops/dual_channel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Compute the dual of a map."""


import numpy as np

from toqito.helper import channel_dim
Expand Down Expand Up @@ -95,7 +94,4 @@ def dual_channel(
if len(phi_op.shape) == 2:
d_in, d_out, _ = channel_dim(phi_op, dim=dims, compute_env_dim=False)
return swap(phi_op.conj(), dim=[[d_in[0], d_out[0]], [d_in[1], d_out[1]]])
raise ValueError(
"Invalid: The variable `phi_op` must either be a list of "
"Kraus operators or as a Choi matrix."
)
raise ValueError("Invalid: The variable `phi_op` must either be a list of Kraus operators or as a Choi matrix.")
1 change: 1 addition & 0 deletions toqito/channel_ops/kraus_to_choi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Compute the Choi matrix of a list of Kraus operators."""

import numpy as np

from toqito.channel_ops import partial_channel
Expand Down
Loading