|
| 1 | +""" |
| 2 | +MIT License |
| 3 | +
|
| 4 | +Copyright (c) 2020-present TorchQuantum Authors |
| 5 | +
|
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy |
| 7 | +of this software and associated documentation files (the "Software"), to deal |
| 8 | +in the Software without restriction, including without limitation the rights |
| 9 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 10 | +copies of the Software, and to permit persons to whom the Software is |
| 11 | +furnished to do so, subject to the following conditions: |
| 12 | +
|
| 13 | +The above copyright notice and this permission notice shall be included in all |
| 14 | +copies or substantial portions of the Software. |
| 15 | +
|
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 19 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 20 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 21 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 22 | +SOFTWARE. |
| 23 | +""" |
| 24 | + |
| 25 | +# test the torchquantum.functional against the IBM Qiskit |
| 26 | +import argparse |
| 27 | +import pdb |
| 28 | +import torchquantum as tq |
| 29 | +import numpy as np |
| 30 | + |
| 31 | +import qiskit.circuit.library.standard_gates as qiskit_gate |
| 32 | +from qiskit.quantum_info import DensityMatrix as qiskitDensity |
| 33 | + |
| 34 | +from unittest import TestCase |
| 35 | +import qiskit.circuit.library as qiskit_library |
| 36 | +from qiskit.quantum_info import Operator |
| 37 | + |
| 38 | +RND_TIMES = 100 |
| 39 | + |
| 40 | +single_gate_list = [ |
| 41 | + {"qiskit": qiskit_gate.HGate, "tq": tq.h, "name": "Hadamard"}, |
| 42 | + {"qiskit": qiskit_gate.XGate, "tq": tq.x, "name": "x"}, |
| 43 | + {"qiskit": qiskit_gate.YGate, "tq": tq.y, "name": "y"}, |
| 44 | + {"qiskit": qiskit_gate.ZGate, "tq": tq.z, "name": "z"}, |
| 45 | + {"qiskit": qiskit_gate.SGate, "tq": tq.S, "name": "S"}, |
| 46 | + {"qiskit": qiskit_gate.TGate, "tq": tq.T, "name": "T"}, |
| 47 | + {"qiskit": qiskit_gate.SXGate, "tq": tq.SX, "name": "SX"}, |
| 48 | + {"qiskit": qiskit_gate.SdgGate, "tq": tq.SDG, "name": "SDG"}, |
| 49 | + {"qiskit": qiskit_gate.TdgGate, "tq": tq.TDG, "name": "TDG"} |
| 50 | +] |
| 51 | + |
| 52 | +pair_list = [ |
| 53 | + {"qiskit": qiskit_gate.HGate, "tq": tq.Hadamard}, |
| 54 | + {"qiskit": None, "tq": tq.SHadamard}, |
| 55 | + {"qiskit": qiskit_gate.XGate, "tq": tq.PauliX}, |
| 56 | + {"qiskit": qiskit_gate.YGate, "tq": tq.PauliY}, |
| 57 | + {"qiskit": qiskit_gate.ZGate, "tq": tq.PauliZ}, |
| 58 | + {"qiskit": qiskit_gate.SGate, "tq": tq.S}, |
| 59 | + {"qiskit": qiskit_gate.TGate, "tq": tq.T}, |
| 60 | + {"qiskit": qiskit_gate.SXGate, "tq": tq.SX}, |
| 61 | + {"qiskit": qiskit_gate.CXGate, "tq": tq.CNOT}, |
| 62 | + {"qiskit": qiskit_gate.CYGate, "tq": tq.CY}, |
| 63 | + {"qiskit": qiskit_gate.CZGate, "tq": tq.CZ}, |
| 64 | + {"qiskit": qiskit_gate.RXGate, "tq": tq.RX}, |
| 65 | + {"qiskit": qiskit_gate.RYGate, "tq": tq.RY}, |
| 66 | + {"qiskit": qiskit_gate.RZGate, "tq": tq.RZ}, |
| 67 | + {"qiskit": qiskit_gate.RXXGate, "tq": tq.RXX}, |
| 68 | + {"qiskit": qiskit_gate.RYYGate, "tq": tq.RYY}, |
| 69 | + {"qiskit": qiskit_gate.RZZGate, "tq": tq.RZZ}, |
| 70 | + {"qiskit": qiskit_gate.RZXGate, "tq": tq.RZX}, |
| 71 | + {"qiskit": qiskit_gate.SwapGate, "tq": tq.SWAP}, |
| 72 | + # {'qiskit': qiskit_gate.?, 'tq': tq.SSWAP}, |
| 73 | + {"qiskit": qiskit_gate.CSwapGate, "tq": tq.CSWAP}, |
| 74 | + {"qiskit": qiskit_gate.CCXGate, "tq": tq.Toffoli}, |
| 75 | + {"qiskit": qiskit_gate.PhaseGate, "tq": tq.PhaseShift}, |
| 76 | + # {'qiskit': qiskit_gate.?, 'tq': tq.Rot}, |
| 77 | + # {'qiskit': qiskit_gate.?, 'tq': tq.MultiRZ}, |
| 78 | + {"qiskit": qiskit_gate.CRXGate, "tq": tq.CRX}, |
| 79 | + {"qiskit": qiskit_gate.CRYGate, "tq": tq.CRY}, |
| 80 | + {"qiskit": qiskit_gate.CRZGate, "tq": tq.CRZ}, |
| 81 | + # {'qiskit': qiskit_gate.?, 'tq': tq.CRot}, |
| 82 | + {"qiskit": qiskit_gate.UGate, "tq": tq.U}, |
| 83 | + {"qiskit": qiskit_gate.U1Gate, "tq": tq.U1}, |
| 84 | + {"qiskit": qiskit_gate.U2Gate, "tq": tq.U2}, |
| 85 | + {"qiskit": qiskit_gate.U3Gate, "tq": tq.U3}, |
| 86 | + {"qiskit": qiskit_gate.CUGate, "tq": tq.CU}, |
| 87 | + {"qiskit": qiskit_gate.CU1Gate, "tq": tq.CU1}, |
| 88 | + # {'qiskit': qiskit_gate.?, 'tq': tq.CU2}, |
| 89 | + {"qiskit": qiskit_gate.CU3Gate, "tq": tq.CU3}, |
| 90 | + {"qiskit": qiskit_gate.ECRGate, "tq": tq.ECR}, |
| 91 | + # {"qiskit": qiskit_library.QFT, "tq": tq.QFT}, |
| 92 | + {"qiskit": qiskit_gate.SdgGate, "tq": tq.SDG}, |
| 93 | + {"qiskit": qiskit_gate.TdgGate, "tq": tq.TDG}, |
| 94 | + {"qiskit": qiskit_gate.SXdgGate, "tq": tq.SXDG}, |
| 95 | + {"qiskit": qiskit_gate.CHGate, "tq": tq.CH}, |
| 96 | + {"qiskit": qiskit_gate.CCZGate, "tq": tq.CCZ}, |
| 97 | + {"qiskit": qiskit_gate.iSwapGate, "tq": tq.ISWAP}, |
| 98 | + {"qiskit": qiskit_gate.CSGate, "tq": tq.CS}, |
| 99 | + {"qiskit": qiskit_gate.CSdgGate, "tq": tq.CSDG}, |
| 100 | + {"qiskit": qiskit_gate.CSXGate, "tq": tq.CSX}, |
| 101 | + {"qiskit": qiskit_gate.DCXGate, "tq": tq.DCX}, |
| 102 | + {"qiskit": qiskit_gate.XXMinusYYGate, "tq": tq.XXMINYY}, |
| 103 | + {"qiskit": qiskit_gate.XXPlusYYGate, "tq": tq.XXPLUSYY}, |
| 104 | + {"qiskit": qiskit_gate.C3XGate, "tq": tq.C3X}, |
| 105 | + {"qiskit": qiskit_gate.RGate, "tq": tq.R}, |
| 106 | + {"qiskit": qiskit_gate.C4XGate, "tq": tq.C4X}, |
| 107 | + {"qiskit": qiskit_gate.RCCXGate, "tq": tq.RCCX}, |
| 108 | + {"qiskit": qiskit_gate.RC3XGate, "tq": tq.RC3X}, |
| 109 | + {"qiskit": qiskit_gate.GlobalPhaseGate, "tq": tq.GlobalPhase}, |
| 110 | + {"qiskit": qiskit_gate.C3SXGate, "tq": tq.C3SX}, |
| 111 | +] |
| 112 | + |
| 113 | + |
| 114 | +def density_is_close(mat1: np.ndarray, mat2: np.ndarray): |
| 115 | + assert mat1.shape == mat2.shape |
| 116 | + return np.allclose(mat1, mat2) |
| 117 | + |
| 118 | + |
| 119 | +("Geeks : %2d, Portal : %5.2f" % (1, 05.333)) |
| 120 | + |
| 121 | + |
| 122 | +class single_qubit(TestCase): |
| 123 | + def compare_single_gate(self, gate_pair, qubit_num): |
| 124 | + passed = True |
| 125 | + for index in range(0, qubit_num): |
| 126 | + qdev = tq.NoiseDevice(n_wires=qubit_num, bsz=1, device="cpu", record_op=True) |
| 127 | + gate_pair['tq'](qdev, [index]) |
| 128 | + mat1 = np.array(qdev.get_2d_matrix(0)) |
| 129 | + rho_qiskit = qiskitDensity.from_label('0' * qubit_num) |
| 130 | + rho_qiskit = rho_qiskit.evolve(gate_pair['qiskit'](), [qubit_num - 1 - index]) |
| 131 | + mat2 = np.array(rho_qiskit.to_operator()) |
| 132 | + if density_is_close(mat1, mat2): |
| 133 | + print("Test passed for %s gate on qubit %d when qubit_number is %d!" % ( |
| 134 | + gate_pair['name'], index, qubit_num)) |
| 135 | + else: |
| 136 | + passed = False |
| 137 | + print("Test failed for %s gaet on qubit %d when qubit_number is %d!" % ( |
| 138 | + gate_pair['name'], index, qubit_num)) |
| 139 | + return passed |
| 140 | + |
| 141 | + def test_single_gates(self): |
| 142 | + for i in range(0, len(single_gate_list)): |
| 143 | + self.assertTrue(self.compare_single_gate(single_gate_list[i], 5)) |
0 commit comments