1# This file is part of QuTiP: Quantum Toolbox in Python. 2# 3# Copyright (c) 2011 and later, Paul D. Nation and Robert J. Johansson. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are 8# met: 9# 10# 1. Redistributions of source code must retain the above copyright notice, 11# this list of conditions and the following disclaimer. 12# 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 17# 3. Neither the name of the QuTiP: Quantum Toolbox in Python nor the names 18# of its contributors may be used to endorse or promote products derived 19# from this software without specific prior written permission. 20# 21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32############################################################################### 33""" 34Unit tests for QuTiP partial transpose functions. 35""" 36 37import numpy as np 38from numpy.testing import assert_, run_module_suite 39 40from qutip import Qobj, partial_transpose, tensor, rand_dm 41from qutip.partial_transpose import _partial_transpose_reference 42 43 44def test_partial_transpose_bipartite(): 45 """partial transpose of bipartite systems""" 46 47 rho = Qobj(np.arange(16).reshape(4, 4), dims=[[2, 2], [2, 2]]) 48 49 # no transpose 50 rho_pt = partial_transpose(rho, [0, 0]) 51 assert_(np.abs(np.max(rho_pt.full() - rho.full())) < 1e-12) 52 53 # partial transpose subsystem 1 54 rho_pt = partial_transpose(rho, [1, 0]) 55 rho_pt_expected = np.array([[0, 1, 8, 9], 56 [4, 5, 12, 13], 57 [2, 3, 10, 11], 58 [6, 7, 14, 15]]) 59 assert_(np.abs(np.max(rho_pt.full() - rho_pt_expected)) < 1e-12) 60 61 # partial transpose subsystem 2 62 rho_pt = partial_transpose(rho, [0, 1]) 63 rho_pt_expected = np.array([[0, 4, 2, 6], 64 [1, 5, 3, 7], 65 [8, 12, 10, 14], 66 [9, 13, 11, 15]]) 67 assert_(np.abs(np.max(rho_pt.full() - rho_pt_expected)) < 1e-12) 68 69 # full transpose 70 rho_pt = partial_transpose(rho, [1, 1]) 71 assert_(np.abs(np.max(rho_pt.full() - rho.trans().full())) < 1e-12) 72 73 74def test_partial_transpose_comparison(): 75 """partial transpose: comparing sparse and dense implementations""" 76 77 N = 10 78 rho = tensor(rand_dm(N, density=0.5), rand_dm(N, density=0.5)) 79 80 # partial transpose of system 1 81 rho_pt1 = partial_transpose(rho, [1, 0], method="dense") 82 rho_pt2 = partial_transpose(rho, [1, 0], method="sparse") 83 np.abs(np.max(rho_pt1.full() - rho_pt1.full())) < 1e-12 84 85 # partial transpose of system 2 86 rho_pt1 = partial_transpose(rho, [0, 1], method="dense") 87 rho_pt2 = partial_transpose(rho, [0, 1], method="sparse") 88 np.abs(np.max(rho_pt1.full() - rho_pt2.full())) < 1e-12 89 90 91def test_partial_transpose_randomized(): 92 """partial transpose: randomized tests on tripartite system""" 93 94 rho = tensor(rand_dm(2, density=1), 95 rand_dm(2, density=1), 96 rand_dm(2, density=1)) 97 98 mask = np.random.randint(2, size=3) 99 100 rho_pt_ref = _partial_transpose_reference(rho, mask) 101 102 rho_pt1 = partial_transpose(rho, mask, method="dense") 103 np.abs(np.max(rho_pt1.full() - rho_pt_ref.full())) < 1e-12 104 105 rho_pt2 = partial_transpose(rho, mask, method="sparse") 106 np.abs(np.max(rho_pt2.full() - rho_pt_ref.full())) < 1e-12 107 108 109if __name__ == "__main__": 110 run_module_suite() 111