Skip to content

Commit

Permalink
Add partial transpose function in quantum_info (#9566)
Browse files Browse the repository at this point in the history
* partial_transpose included

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included partial_transpose

* included test for partial transpose

* included test for partial transpose

* included test for partial transpose

* added docstring

* included DensityMatrix(rho1)

* changed rho1

* addition of release note

* fix

* fix

* fir partial_transpose

* Update utils.py

* refactor and add tests

---------

Co-authored-by: Ikko Hamamura <ikkoham@users.noreply.github.com>
  • Loading branch information
PayalSolanki2906 and ikkoham authored Apr 17, 2023
1 parent 5dbac1e commit 580590f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
19 changes: 19 additions & 0 deletions qiskit/quantum_info/states/densitymatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,3 +814,22 @@ def to_statevector(self, atol=None, rtol=None):

psi = evecs[:, np.argmax(evals)] # eigenvectors returned in columns.
return Statevector(psi)

def partial_transpose(self, qargs):
"""Return partially transposed density matrix.
Args:
qargs (list): The subsystems to be transposed.
Returns:
DensityMatrix: The partially transposed density matrix.
"""
arr = self._data.reshape(self._op_shape.tensor_shape)
qargs = len(self._op_shape.dims_l()) - 1 - np.array(qargs)
n = len(self.dims())
lst = list(range(2 * n))
for i in qargs:
lst[i], lst[i + n] = lst[i + n], lst[i]
rho = np.transpose(arr, lst)
rho = np.reshape(rho, self._op_shape.shape)
return DensityMatrix(rho)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

features:
- |
The partial transpose operation has been integrated into the quantum_info module, allowing for partial transposition of matrices.
This operation is key in detecting entanglement between bipartite quantum system.
35 changes: 26 additions & 9 deletions test/python/quantum_info/states/test_densitymatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,20 @@

"""Tests for DensityMatrix quantum state class."""

import unittest
import logging
from ddt import ddt, data
import unittest

import numpy as np
from ddt import data, ddt
from numpy.testing import assert_allclose

from qiskit.test import QiskitTestCase
from qiskit import QiskitError
from qiskit import QuantumRegister, QuantumCircuit
from qiskit.circuit.library import HGate, QFT

from qiskit.quantum_info.random import random_unitary, random_density_matrix, random_pauli
from qiskit.quantum_info.states import DensityMatrix, Statevector
from qiskit import QiskitError, QuantumCircuit, QuantumRegister
from qiskit.circuit.library import QFT, HGate
from qiskit.quantum_info.operators.operator import Operator
from qiskit.quantum_info.operators.symplectic import Pauli, SparsePauliOp
from qiskit.quantum_info.random import random_density_matrix, random_pauli, random_unitary
from qiskit.quantum_info.states import DensityMatrix, Statevector
from qiskit.test import QiskitTestCase

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -1202,6 +1201,24 @@ def test_drawings(self):
with self.subTest(msg=f"draw('{drawtype}')"):
dm.draw(drawtype)

def test_density_matrix_partial_transpose(self):
"""Test partial_transpose function on density matrices"""
with self.subTest(msg="separable"):
rho = DensityMatrix.from_label("10+")
rho1 = np.zeros((8, 8), complex)
rho1[4, 4] = 0.5
rho1[4, 5] = 0.5
rho1[5, 4] = 0.5
rho1[5, 5] = 0.5
self.assertEqual(rho.partial_transpose([0, 1]), DensityMatrix(rho1))
self.assertEqual(rho.partial_transpose([0, 2]), DensityMatrix(rho1))

with self.subTest(msg="entangled"):
rho = DensityMatrix([[0, 0, 0, 0], [0, 0.5, -0.5, 0], [0, -0.5, 0.5, 0], [0, 0, 0, 0]])
rho1 = DensityMatrix([[0, 0, 0, -0.5], [0, 0.5, 0, 0], [0, 0, 0.5, 0], [-0.5, 0, 0, 0]])
self.assertEqual(rho.partial_transpose([0]), DensityMatrix(rho1))
self.assertEqual(rho.partial_transpose([1]), DensityMatrix(rho1))

def test_clip_probabilities(self):
"""Test probabilities are clipped to [0, 1]."""
dm = DensityMatrix([[1.1, 0], [0, 0]])
Expand Down

0 comments on commit 580590f

Please sign in to comment.