Source code for toqito.perms.symmetric_projection

"""Symmetric projection operator."""
from itertools import permutations

import numpy as np
import scipy

from toqito.perms import permutation_operator


[docs] def symmetric_projection( dim: int, p_val: int = 2, partial: bool = False ) -> [np.ndarray, scipy.sparse.lil_matrix]: r""" Produce the projection onto the symmetric subspace [CJKLZ14]_. For a complex Euclidean space :math:`\mathcal{X}` and a positive integer :math:`n`, the projection onto the symmetric subspace is given by .. math:: \frac{1}{n!} \sum_{\pi \in S_n} W_{\pi} where :math:`W_{\pi}` is the swap operator and where :math:`S_n` is the symmetric group on :math:`n` symbols. Produces the orthogonal projection onto the symmetric subspace of :code:`p_val` copies of `dim`-dimensional space. If `partial = True`, then the symmetric projection (PS) isn't the orthogonal projection itself, but rather a matrix whose columns form an orthonormal basis for the symmetric subspace (and hence the PS * PS' is the orthogonal projection onto the symmetric subspace). This function was adapted from the QETLAB package. Examples ========== The :math:`2`-dimensional symmetric projection with :math:`p=1` is given as :math:`2`-by-:math:`2` identity matrix .. math:: \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix}. Using :code:`toqito`, we can see this gives the proper result. >>> from toqito.perms import symmetric_projection >>> symmetric_projection(2, 1).todense() [[1., 0.], [0., 1.]] When :math:`d = 2` and :math:`p = 2` we have that .. math:: \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1/2 & 1/2 & 0 \\ 0 & 1/2 & 1/2 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}. Using :code:`toqito` we can see this gives the proper result. >>> from toqito.perms import symmetric_projection >>> symmetric_projection(dim=2).todense() [[1. , 0. , 0. , 0. ], [0. , 0.5, 0.5, 0. ], [0. , 0.5, 0.5, 0. ], [0. , 0. , 0. , 1. ]] References ========== .. [CJKLZ14] J. Chen, Z. Ji, D. Kribs, N. Lütkenhaus, and B. Zeng. "Symmetric extension of two-qubit states". Physical Review A 90.3 (2014): 032318. https://arxiv.org/abs/1310.3530 E-print: arXiv:1310.3530 [quant-ph] :param dim: The dimension of the local systems. :param p_val: Default value of 2. :param partial: Default value of 0. :return: Projection onto the symmetric subspace. """ dimp = dim**p_val if p_val == 1: return np.eye(dim) p_list = np.array(list(permutations(np.arange(1, p_val + 1)))) p_fac = np.math.factorial(p_val) sym_proj = np.zeros((dimp, dimp)) for j in range(p_fac): sym_proj += permutation_operator(dim * np.ones(p_val), p_list[j, :], False, True) sym_proj = sym_proj / p_fac if partial: sym_proj = scipy.linalg.orth(sym_proj) return sym_proj