diff --git a/toqito/channel_metrics/fidelity_of_separability.py b/toqito/channel_metrics/fidelity_of_separability.py index 0a8be9e2e..c979921b8 100644 --- a/toqito/channel_metrics/fidelity_of_separability.py +++ b/toqito/channel_metrics/fidelity_of_separability.py @@ -134,7 +134,7 @@ def fidelity_of_separability( raise ValueError("This function only works for pure states.") # We first permure psi_{BAR} to psi_{RAB} to simplify the code. - psi = permute_systems(psi, [3, 2, 1], psi_dims) + psi = permute_systems(psi, [2, 1, 0], psi_dims) dim_b, dim_a, dim_r = psi_dims psi_dims = [dim_r, dim_a, dim_b] @@ -163,7 +163,7 @@ 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), [0, 3, 2, 1], dim_list), [0, 2], dim_list, ) diff --git a/toqito/channel_ops/partial_channel.py b/toqito/channel_ops/partial_channel.py index af92808bc..57f6fc90e 100644 --- a/toqito/channel_ops/partial_channel.py +++ b/toqito/channel_ops/partial_channel.py @@ -182,7 +182,7 @@ def partial_channel( phi_map = permute_systems( np.kron(np.kron(psi_r1 * psi_c1.conj().T, phi_map), psi_r2 * psi_c2.conj().T), - [1, 3, 5, 2, 4, 6], + [0, 2, 4, 1, 3, 5], dim, ) diff --git a/toqito/channels/partial_trace.py b/toqito/channels/partial_trace.py index 36ba10feb..d5aa37941 100644 --- a/toqito/channels/partial_trace.py +++ b/toqito/channels/partial_trace.py @@ -189,10 +189,10 @@ def partial_trace( sys = np.array(sys) if isinstance(sys, int): sys = np.array([sys]) - set_diff = list(set(list(range(1, num_sys + 1))) - set(sys + 1)) + set_diff = list(set(list(range(num_sys))) - set(sys)) perm = set_diff - perm.extend(sys + 1) + perm.extend(sys) a_mat = permute_systems(input_mat, perm, dim) diff --git a/toqito/channels/partial_transpose.py b/toqito/channels/partial_transpose.py index 4aebb5e2f..693b3d3b3 100644 --- a/toqito/channels/partial_transpose.py +++ b/toqito/channels/partial_transpose.py @@ -167,8 +167,8 @@ def partial_transpose( sub_sys_vec_r = prod_dim_r * np.ones(int(sub_prod_r)) / sub_prod_r sub_sys_vec_c = prod_dim_c * np.ones(int(sub_prod_c)) / sub_prod_c - set_diff = list(set(list(range(1, num_sys + 1))) - set(sys + 1)) - perm = (sys + 1).tolist()[:] + set_diff = list(set(list(range(num_sys ))) - set(sys )) + perm = (sys ).tolist()[:] perm.extend(set_diff) # Permute the subsystems so that we just have to do the partial transpose @@ -198,6 +198,6 @@ def partial_transpose( # Return the subsystems back to their original positions. dim[:, sys] = np.flipud(dim[:, sys]) - dim = dim[:, (np.array(perm) - 1).tolist()] + dim = dim[:, (np.array(perm) ).tolist()] return permute_systems(z_tmp, perm, dim, False, True) diff --git a/toqito/nonlocal_games/quantum_hedging.py b/toqito/nonlocal_games/quantum_hedging.py index 6ae91b16d..252d45fa2 100644 --- a/toqito/nonlocal_games/quantum_hedging.py +++ b/toqito/nonlocal_games/quantum_hedging.py @@ -90,8 +90,8 @@ def __init__(self, q_a: np.ndarray, num_reps: int) -> None: # action: # π(y1 ⊗ y2 ⊗ x1 ⊗ x2) = y1 ⊗ x1 ⊗ y2 ⊗ x2 # for all y1 ∈ Y1, y2 ∈ Y2, x1 ∈ X1, x2 ∈ X2.). - l_1 = list(range(1, self._num_reps + 1)) - l_2 = list(range(self._num_reps + 1, self._num_reps**2 + 1)) + l_1 = list(range(self._num_reps )) + l_2 = list(range(self._num_reps , self._num_reps**2 )) if self._num_reps == 1: self._pperm = np.array([1]) else: diff --git a/toqito/perms/antisymmetric_projection.py b/toqito/perms/antisymmetric_projection.py index ed176ebdd..ad059119c 100644 --- a/toqito/perms/antisymmetric_projection.py +++ b/toqito/perms/antisymmetric_projection.py @@ -84,7 +84,7 @@ def antisymmetric_projection(dim: int, p_param: int = 2, partial: bool = False) if dim < p_param: return np.zeros((dimp, dimp * (1 - partial))) - p_list = np.array(list(permutations(np.arange(1, p_param + 1)))) + p_list = np.array(list(permutations(np.arange(p_param )))) p_fac = p_list.shape[0] anti_proj = np.zeros((dimp, dimp)) diff --git a/toqito/perms/perfect_matchings.py b/toqito/perms/perfect_matchings.py index 1d08af4bd..fd0e8e550 100644 --- a/toqito/perms/perfect_matchings.py +++ b/toqito/perms/perfect_matchings.py @@ -16,14 +16,13 @@ def perfect_matchings(num: list[int] | int | np.ndarray) -> np.ndarray: Examples ========== - - This is an example of how to generate all perfect matchings of the numbers 1, 2, 3, 4. + This is an example of how to generate all perfect matchings of the numbers 0, 1, 2, 3. >>> from toqito.perms import perfect_matchings >>> perfect_matchings(4) - array([[1, 2, 3, 4], - [1, 3, 2, 4], - [1, 4, 3, 2]]) + array([[0, 1, 2, 3], + [0, 2, 1, 3], + [0, 3, 2, 1]]) References ========== @@ -31,13 +30,13 @@ def perfect_matchings(num: list[int] | int | np.ndarray) -> np.ndarray: :filter: docname in docnames :param num: Either an even integer, indicating that you would like all perfect matchings of the - integers 1,2, ... N, or a `list` or `np.array` containing an even number of distinct + integers 0, 1, ... N-1, or a `list` or `np.array` containing an even number of distinct entries, indicating that you would like all perfect matchings of those entries. :return: An array containing all valid perfect matchings of size :code:`num`. """ if isinstance(num, int): - num = np.arange(1, num + 1) + num = np.arange(num) if isinstance(num, list): num = np.array(num) @@ -73,3 +72,4 @@ def perfect_matchings(num: list[int] | int | np.ndarray) -> np.ndarray: matchings = np.vstack((matchings, s_vec)) return matchings + diff --git a/toqito/perms/permutation_operator.py b/toqito/perms/permutation_operator.py index ba08ede62..a1d869095 100644 --- a/toqito/perms/permutation_operator.py +++ b/toqito/perms/permutation_operator.py @@ -27,7 +27,7 @@ def permutation_operator( qubits .. math:: - P_{2, [2, 1]} = + P_{2, [1, 0]} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ @@ -38,13 +38,12 @@ def permutation_operator( Using :code:`toqito`, this can be achieved in the following manner. >>> from toqito.perms import permutation_operator - >>> permutation_operator(2, [2, 1]) + >>> permutation_operator(2, [1, 0]) array([[1., 0., 0., 0.], [0., 0., 1., 0.], [0., 1., 0., 0.], [0., 0., 0., 1.]]) - :param dim: The dimensions of the subsystems to be permuted. :param perm: A permutation vector. :param inv_perm: Boolean dictating if :code:`perm` is inverse or not. @@ -54,10 +53,11 @@ def permutation_operator( """ # Allow the user to enter a single number for `dim`. if isinstance(dim, int): - dim = dim * np.ones(max(perm)) + dim = [dim] * np.ones(max(perm) + 1) if isinstance(dim, list): dim = np.array(dim) mat = sp.sparse.identity(int(np.prod(dim))) if is_sparse else np.identity(int(np.prod(dim))) # Swap the rows of the identity matrix appropriately. + return permute_systems(mat, perm, dim, True, inv_perm) diff --git a/toqito/perms/permute_systems.py b/toqito/perms/permute_systems.py index df750fdd0..02ff186df 100644 --- a/toqito/perms/permute_systems.py +++ b/toqito/perms/permute_systems.py @@ -36,7 +36,7 @@ def permute_systems( For spaces :math:`\mathcal{A}` and :math:`\mathcal{B}` where :math:`\text{dim}(\mathcal{A}) = \text{dim}(\mathcal{B}) = 2` we may consider an operator :math:`X \in \mathcal{A} \otimes \mathcal{B}`. Applying the - `permute_systems` function with vector :math:`[2,1]` on :math:`X`, we may reorient the spaces such that :math:`X \in + `permute_systems` function with vector :math:`[1,0]` on :math:`X`, we may reorient the spaces such that :math:`X \in \mathcal{B} \otimes \mathcal{A}`. For example, if we define :math:`X \in \mathcal{A} \otimes \mathcal{B}` as @@ -53,7 +53,7 @@ def permute_systems( yield the following matrix .. math:: - X_{[2,1]} = \begin{pmatrix} + X_{[1,0]} = \begin{pmatrix} 1 & 3 & 2 & 4 \\ 9 & 11 & 10 & 12 \\ 5 & 7 & 6 & 8 \\ @@ -63,7 +63,7 @@ def permute_systems( >>> from toqito.perms import permute_systems >>> import numpy as np >>> test_input_mat = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) - >>> permute_systems(test_input_mat, [2, 1]) + >>> permute_systems(test_input_mat, [1, 0]) array([[ 1, 3, 2, 4], [ 9, 11, 10, 12], [ 5, 7, 6, 8], @@ -71,7 +71,7 @@ def permute_systems( For spaces :math:`\mathcal{A}, \mathcal{B}`, and :math:`\mathcal{C}` where :math:`\text{dim}(\mathcal{A}) = \text{dim}(\mathcal{B}) = \text{dim}(\mathcal{C}) = 2` we may consider an operator :math:`X \in \mathcal{A} \otimes - \mathcal{B} \otimes \mathcal{C}`. Applying the :code:`permute_systems` function with vector :math:`[2,3,1]` on + \mathcal{B} \otimes \mathcal{C}`. Applying the :code:`permute_systems` function with vector :math:`[1,2,0]` on :math:`X`, we may reorient the spaces such that :math:`X \in \mathcal{B} \otimes \mathcal{C} \otimes \mathcal{A}`. For example, if we define :math:`X \in \mathcal{A} \otimes \mathcal{B} \otimes \mathcal{C}` as @@ -93,7 +93,7 @@ def permute_systems( \otimes \mathcal{C}` yield the following matrix .. math:: - X_{[2, 3, 1]} = + X_{[1, 2, 0]} = \begin{pmatrix} 1 & 5 & 2 & 6 & 3 & 7 & 4, 8 \\ 33 & 37 & 34 & 38 & 35 & 39 & 36 & 40 \\ @@ -119,7 +119,7 @@ def permute_systems( ... [57, 58, 59, 60, 61, 62, 63, 64], ... ] ... ) - >>> permute_systems(test_input_mat, [2, 3, 1]) + >>> permute_systems(test_input_mat, [1, 2, 0]) array([[ 1, 5, 2, 6, 3, 7, 4, 8], [33, 37, 34, 38, 35, 39, 36, 40], [ 9, 13, 10, 14, 11, 15, 12, 16], @@ -145,6 +145,7 @@ def permute_systems( else: input_mat_dims = input_mat.shape + is_vec = np.min(input_mat_dims) == 1 num_sys = len(perm) @@ -176,7 +177,7 @@ def permute_systems( prod_dim_r = int(np.prod(dim[0, :])) prod_dim_c = int(np.prod(dim[1, :])) - if sorted(perm) != list(range(1, num_sys + 1)): + if sorted(perm) != list(range(num_sys )): raise ValueError("InvalidPerm: `perm` must be a permutation vector.") if input_mat_dims[0] != prod_dim_r or (not row_only and input_mat_dims[1] != prod_dim_c): raise ValueError("InvalidDim: The dimensions specified in DIM do not agree with the size of X.") @@ -185,6 +186,10 @@ def permute_systems( if input_mat.shape[0] == 1: input_mat = input_mat[0] vec_orien = 1 + # Rather than using subtraction to generate new indices, + # it's better to use methods designed for handling permutations directly. + # This avoids the risk of negative indices and is more straightforward. + num_sys -= 1 # 0-indexing (Since we're using 0-indexing, we need to subtract 1 from the number of subsystems.) permuted_mat_1 = input_mat.reshape(dim[vec_orien, ::-1].astype(int), order="F") if inv_perm: permuted_mat = vec(np.transpose(permuted_mat_1, np.argsort(num_sys - np.array(perm[::-1])))).T diff --git a/toqito/perms/swap.py b/toqito/perms/swap.py index 384aae764..f6e38066d 100644 --- a/toqito/perms/swap.py +++ b/toqito/perms/swap.py @@ -145,7 +145,7 @@ def swap( raise ValueError("InvalidSys: `sys` must be a vector with exactly two elements.") # Swap the indicated subsystems. - perm = np.array(range(1, num_sys + 1)) + perm = np.array(range(num_sys )) sys = np.array(sys) - 1 perm[sys] = perm[sys[::-1]] diff --git a/toqito/perms/symmetric_projection.py b/toqito/perms/symmetric_projection.py index a032c7ce9..0df82e3ea 100644 --- a/toqito/perms/symmetric_projection.py +++ b/toqito/perms/symmetric_projection.py @@ -81,7 +81,7 @@ def symmetric_projection(dim: int, p_val: int = 2, partial: bool = False) -> [np if p_val == 1: return np.eye(dim) - p_list = np.array(list(permutations(np.arange(1, p_val + 1)))) + p_list = np.array(list(permutations(np.arange(p_val )))) p_fac = math.factorial(p_val) sym_proj = np.zeros((dimp, dimp)) diff --git a/toqito/perms/tests/test_perfect_matchings.py b/toqito/perms/tests/test_perfect_matchings.py index 432133dda..2709ca3ab 100644 --- a/toqito/perms/tests/test_perfect_matchings.py +++ b/toqito/perms/tests/test_perfect_matchings.py @@ -8,15 +8,15 @@ def test_perfect_matchings_num_4(): """All perfect matchings of size 4.""" res = perfect_matchings(4) - expected_res = np.array([[1, 2, 3, 4], [1, 3, 2, 4], [1, 4, 3, 2]]) + expected_res = np.array([[0, 1, 2, 3], [0, 2, 1, 3], [0, 3, 2, 1]]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) def test_perfect_matchings_num_4_list(): """All perfect matchings of size 4 with input as list.""" - res = perfect_matchings([1, 2, 3, 4]) - expected_res = np.array([[1, 2, 3, 4], [1, 3, 2, 4], [1, 4, 3, 2]]) + res = perfect_matchings([0, 1, 2, 3]) + expected_res = np.array([[0, 1, 2, 3], [0, 2, 1, 3], [0, 3, 2, 1]]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) @@ -35,21 +35,21 @@ def test_perfect_matchings_num_6(): expected_res = np.array( [ - [1, 2, 3, 4, 5, 6], - [1, 2, 3, 5, 4, 6], - [1, 2, 3, 6, 5, 4], - [1, 3, 2, 4, 5, 6], - [1, 3, 2, 5, 4, 6], - [1, 3, 2, 6, 5, 4], - [1, 4, 3, 2, 5, 6], - [1, 4, 3, 5, 2, 6], - [1, 4, 3, 6, 5, 2], - [1, 5, 3, 4, 2, 6], - [1, 5, 3, 2, 4, 6], - [1, 5, 3, 6, 2, 4], - [1, 6, 3, 4, 5, 2], - [1, 6, 3, 5, 4, 2], - [1, 6, 3, 2, 5, 4], + [0, 1, 2, 3, 4, 5], + [0, 1, 2, 4, 3, 5], + [0, 1, 2, 5, 4, 3], + [0, 2, 1, 3, 4, 5], + [0, 2, 1, 4, 3, 5], + [0, 2, 1, 5, 4, 3], + [0, 3, 2, 1, 4, 5], + [0, 3, 2, 4, 1, 5], + [0, 3, 2, 5, 4, 1], + [0, 4, 2, 3, 1, 5], + [0, 4, 2, 1, 3, 5], + [0, 4, 2, 5, 1, 3], + [0, 5, 2, 3, 4, 1], + [0, 5, 2, 4, 3, 1], + [0, 5, 2, 1, 4, 3] ] ) bool_mat = np.isclose(res, expected_res) diff --git a/toqito/perms/tests/test_permutation_operator.py b/toqito/perms/tests/test_permutation_operator.py index a7bd831e0..9e2b1e860 100644 --- a/toqito/perms/tests/test_permutation_operator.py +++ b/toqito/perms/tests/test_permutation_operator.py @@ -6,28 +6,28 @@ def test_permutation_operator_standard_swap(): - """Generates the standard swap operator on two qubits.""" + """Generates the standard swap operator on two qubits with zero-based indexing.""" expected_res = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) - res = permutation_operator(2, [2, 1]) + res = permutation_operator(2, [1, 0]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) def test_permutation_operator_standard_swap_list_dim(): - """Generates the standard swap operator on two qubits.""" + """Generates the standard swap operator on two qubits with zero-based indexing.""" expected_res = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) - res = permutation_operator([2, 2], [2, 1]) + res = permutation_operator([2, 2], [1, 0]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) def test_permutation_operator_sparse_option(): - """Sparse swap operator on two qutrits.""" - res = permutation_operator(3, [2, 1], False, True) + """Sparse swap operator on two qutrits with zero-based indexing.""" + res = permutation_operator(3, [1, 0], False, True) expected_res = np.array( [ @@ -46,17 +46,17 @@ def test_permutation_operator_sparse_option(): np.testing.assert_equal(np.all(bool_mat), True) -def test_permutation_operator_dim_3_perm_1_2(): - """Test permutation operator when dim is 3 and perm is [1, 2].""" - res = permutation_operator(3, [1, 2]) +def test_permutation_operator_dim_3_perm_0_1(): + """Test permutation operator when dim is 3 and perm is [0, 1] using zero-based indexing.""" + res = permutation_operator(3, [0, 1]) expected_res = np.identity(9) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) -def test_permutation_operator_dim_2_perm_1_3_2(): - """Test permutation operator when dim is 2 and perm is [1, 3, 2].""" - res = permutation_operator(2, [1, 3, 2]) +def test_permutation_operator_dim_2_perm_0_2_1(): + """Test permutation operator when dim is 2 and perm is [0, 2, 1] using zero-based indexing.""" + res = permutation_operator(2, [0, 2, 1]) expected_res = np.array( [ [ @@ -75,17 +75,17 @@ def test_permutation_operator_dim_2_perm_1_3_2(): np.testing.assert_equal(np.all(bool_mat), True) -def test_permutation_operator_dim_2_2_perm_1_2(): - """Test permutation operator when dim is [2, 2] and perm is [1, 2].""" - res = permutation_operator([2, 2], [1, 2]) +def test_permutation_operator_dim_2_2_perm_0_1(): + """Test permutation operator when dim is [2, 2] and perm is [0, 1] using zero-based indexing.""" + res = permutation_operator([2, 2], [0, 1]) expected_res = np.identity(4) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) -def test_permutation_operator_dim_2_2_perm_2_1(): - """Test permutation operator when dim is [2, 2] and perm is [2, 1].""" - res = permutation_operator([2, 2], [2, 1]) +def test_permutation_operator_dim_2_2_perm_1_0(): + """Test permutation operator when dim is [2, 2] and perm is [1, 0] using zero-based indexing.""" + res = permutation_operator([2, 2], [1, 0]) expected_res = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) diff --git a/toqito/perms/tests/test_permute_systems.py b/toqito/perms/tests/test_permute_systems.py index 4fe098fcd..5dcd5f316 100644 --- a/toqito/perms/tests/test_permute_systems.py +++ b/toqito/perms/tests/test_permute_systems.py @@ -10,19 +10,19 @@ def test_permute_systems_vec(): test_input_mat = np.array([1, 2, 3, 4]) expected_res = np.array([1, 3, 2, 4]) - res = permute_systems(test_input_mat, [2, 1]) + res = permute_systems(test_input_mat, [1, 0]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) def test_permute_systems_m2_m2(): - """Permute system for perm = [2,1] and dim = [2, 2].""" + """Permute system for perm = [0,1] and matrix of dimension [2, 2].""" test_input_mat = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) expected_res = np.array([[1, 3, 2, 4], [9, 11, 10, 12], [5, 7, 6, 8], [13, 15, 14, 16]]) - res = permute_systems(test_input_mat, [2, 1], [2, 2]) + res = permute_systems(test_input_mat, [1, 0], dim=[2, 2]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) @@ -34,7 +34,7 @@ def test_permute_systems_m2_m2_np_array(): expected_res = np.array([[1, 3, 2, 4], [9, 11, 10, 12], [5, 7, 6, 8], [13, 15, 14, 16]]) - res = permute_systems(test_input_mat, np.array([2, 1])) + res = permute_systems(test_input_mat, np.array([1, 0])) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) @@ -68,7 +68,7 @@ def permute_systems_test_2_3_1(): ] ) - res = permute_systems(test_input_mat, [2, 3, 1]) + res = permute_systems(test_input_mat, [1, 2, 0]) bool_mat = np.isclose(res, expected_res) np.testing.assert_equal(np.all(bool_mat), True) @@ -96,9 +96,8 @@ def test_permute_systems_16_by_16(): [151, 152, 183, 184, 215, 216, 247, 248, 159, 160, 191, 192, 223, 224, 255, 256], ] ) - perm = [2, 3, 1, 4] + perm = [1, 2, 0, 3] dim = [[2, 2, 2, 2], [2, 2, 2, 2]] - res = permute_systems(rho, perm, dim, True, False) expected_res = np.array( [ @@ -152,7 +151,7 @@ def test_permute_systems_invalid_perm_vector(): """Invalid input for permute systems.""" with np.testing.assert_raises(ValueError): test_input_mat = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) - permute_systems(test_input_mat, [0, 1]) + permute_systems(test_input_mat, [-1, 0]) def test_permute_systems_invalid_empty_input(): diff --git a/toqito/state_opt/optimal_clone.py b/toqito/state_opt/optimal_clone.py index b9c118060..b086af2df 100644 --- a/toqito/state_opt/optimal_clone.py +++ b/toqito/state_opt/optimal_clone.py @@ -130,7 +130,7 @@ def optimal_clone( # sequence from: https://oeis.org/A023123 q_a = tensor(q_a, num_reps) perm = [] - for i in range(1, num_spaces + 1): + for i in range(num_spaces ): perm.append(i) var = i for j in range(1, num_reps): @@ -141,7 +141,6 @@ def optimal_clone( return primal_problem(q_a, pperm, num_reps) return dual_problem(q_a, pperm, num_reps) - def primal_problem(q_a: np.ndarray, pperm: np.ndarray, num_reps: int) -> float: """Primal problem for counterfeit attack. diff --git a/toqito/state_props/is_product.py b/toqito/state_props/is_product.py index 15ffb5146..9ba1775ec 100644 --- a/toqito/state_props/is_product.py +++ b/toqito/state_props/is_product.py @@ -132,7 +132,7 @@ def _operator_is_product(rho: np.ndarray, dim: int | list[int] = None) -> list[i dim = np.array([dim, dim]) op_1 = rho.reshape(int(np.prod(np.prod(dim))), 1) - perm = swap(np.array(list(range(2 * num_sys))), [1, 2], [2, num_sys]) + 1 + perm = swap(np.array(list(range(2 * num_sys))), [1, 2], [2, num_sys]) perm_dim = np.concatenate((dim[1, :].astype(int), dim[0, :].astype(int))) op_3 = permute_systems(op_1, perm, perm_dim).reshape(-1, 1) diff --git a/toqito/states/werner.py b/toqito/states/werner.py index 6dab7bd1a..f7c7bfda8 100644 --- a/toqito/states/werner.py +++ b/toqito/states/werner.py @@ -106,7 +106,7 @@ def werner(dim: int, alpha: float | list[float]) -> np.ndarray: # Done error checking and computing the number of parties # -- now compute the Werner state. perms = list(itertools.permutations(range(n_var))) - sorted_perms = np.argsort(perms, axis=1) + 1 + sorted_perms = np.argsort(perms, axis=1) rho = np.identity(dim**n_var) for i in range(2, n_fac):