Skip to content

Commit d39dece

Browse files
author
Zhuoyang Ye
committed
[Fix] Fix a bug of matrix conjugation.
1 parent 8f0bbd0 commit d39dece

File tree

3 files changed

+57
-37
lines changed

3 files changed

+57
-37
lines changed

test/density/test_density_op.py

+43-29
Original file line numberDiff line numberDiff line change
@@ -43,58 +43,50 @@
4343
single_gate_list = [
4444
{"qiskit": qiskit_gate.HGate, "tq": tq.h, "name": "Hadamard"},
4545
{"qiskit": qiskit_gate.XGate, "tq": tq.x, "name": "x"},
46-
# {"qiskit": qiskit_gate.YGate, "tq": tq.y, "name": "y"},
46+
{"qiskit": qiskit_gate.YGate, "tq": tq.y, "name": "y"},
4747
{"qiskit": qiskit_gate.ZGate, "tq": tq.z, "name": "z"},
48-
{"qiskit": qiskit_gate.SGate, "tq": tq.S, "name": "S"},
49-
{"qiskit": qiskit_gate.TGate, "tq": tq.T, "name": "T"},
50-
# {"qiskit": qiskit_gate.SXGate, "tq": tq.SX, "name": "SX"},
51-
{"qiskit": qiskit_gate.SdgGate, "tq": tq.SDG, "name": "SDG"},
52-
{"qiskit": qiskit_gate.TdgGate, "tq": tq.TDG, "name": "TDG"}
48+
{"qiskit": qiskit_gate.SGate, "tq": tq.s, "name": "S"},
49+
{"qiskit": qiskit_gate.TGate, "tq": tq.t, "name": "T"},
50+
{"qiskit": qiskit_gate.SdgGate, "tq": tq.sdg, "name": "SDG"},
51+
{"qiskit": qiskit_gate.TdgGate, "tq": tq.tdg, "name": "TDG"}
5352
]
5453

5554
single_param_gate_list = [
5655

5756
]
5857

5958
two_qubit_gate_list = [
60-
{"qiskit": qiskit_gate.CXGate, "tq": tq.CNOT, "name": "CNOT"},
61-
{"qiskit": qiskit_gate.CYGate, "tq": tq.CY, "name": "CY"},
62-
{"qiskit": qiskit_gate.CZGate, "tq": tq.CZ, "name": "CZ"},
63-
{"qiskit": qiskit_gate.SwapGate, "tq": tq.SWAP, "name": "SWAP"}
59+
{"qiskit": qiskit_gate.CXGate, "tq": tq.cnot, "name": "CNOT"},
60+
{"qiskit": qiskit_gate.CXGate, "tq": tq.cx, "name": "CY"},
61+
{"qiskit": qiskit_gate.CYGate, "tq": tq.cy, "name": "CY"},
62+
{"qiskit": qiskit_gate.CZGate, "tq": tq.cz, "name": "CZ"},
63+
{"qiskit": qiskit_gate.CSGate, "tq": tq.cs, "name": "CS"},
64+
{"qiskit": qiskit_gate.SwapGate, "tq": tq.swap, "name": "SWAP"},
65+
{"qiskit": qiskit_gate.iSwapGate, "tq": tq.iswap, "name": "iSWAP"}
6466
]
6567

6668
two_qubit_param_gate_list = [
6769

6870
]
6971

7072
three_qubit_gate_list = [
71-
{"qiskit": qiskit_gate.CCXGate, "tq": tq.Toffoli, "name": "Toffoli"},
72-
{"qiskit": qiskit_gate.CSwapGate, "tq": tq.CSWAP, "name": "CSWAP"}
73+
{"qiskit": qiskit_gate.CCXGate, "tq": tq.ccx, "name": "Toffoli"},
74+
{"qiskit": qiskit_gate.CSwapGate, "tq": tq.cswap, "name": "CSWAP"},
7375
]
7476

7577
three_qubit_param_gate_list = [
7678
]
7779

7880
pair_list = [
79-
{"qiskit": qiskit_gate.HGate, "tq": tq.Hadamard},
80-
{"qiskit": None, "tq": tq.SHadamard},
81-
{"qiskit": qiskit_gate.XGate, "tq": tq.PauliX},
82-
{"qiskit": qiskit_gate.YGate, "tq": tq.PauliY},
83-
{"qiskit": qiskit_gate.ZGate, "tq": tq.PauliZ},
84-
{"qiskit": qiskit_gate.SGate, "tq": tq.S},
85-
{"qiskit": qiskit_gate.TGate, "tq": tq.T},
8681
{"qiskit": qiskit_gate.SXGate, "tq": tq.SX},
8782
{"qiskit": qiskit_gate.CXGate, "tq": tq.CNOT},
88-
{"qiskit": qiskit_gate.CYGate, "tq": tq.CY},
89-
{"qiskit": qiskit_gate.CZGate, "tq": tq.CZ},
9083
{"qiskit": qiskit_gate.RXGate, "tq": tq.RX},
9184
{"qiskit": qiskit_gate.RYGate, "tq": tq.RY},
9285
{"qiskit": qiskit_gate.RZGate, "tq": tq.RZ},
9386
{"qiskit": qiskit_gate.RXXGate, "tq": tq.RXX},
9487
{"qiskit": qiskit_gate.RYYGate, "tq": tq.RYY},
9588
{"qiskit": qiskit_gate.RZZGate, "tq": tq.RZZ},
9689
{"qiskit": qiskit_gate.RZXGate, "tq": tq.RZX},
97-
{"qiskit": qiskit_gate.SwapGate, "tq": tq.SWAP},
9890
# {'qiskit': qiskit_gate.?, 'tq': tq.SSWAP},
9991
{"qiskit": qiskit_gate.CSwapGate, "tq": tq.CSWAP},
10092
{"qiskit": qiskit_gate.CCXGate, "tq": tq.Toffoli},
@@ -136,12 +128,12 @@
136128
{"qiskit": qiskit_gate.C3SXGate, "tq": tq.C3SX},
137129
]
138130

139-
maximum_qubit_num = 5
131+
maximum_qubit_num = 10
140132

141133

142134
def density_is_close(mat1: np.ndarray, mat2: np.ndarray):
143135
assert mat1.shape == mat2.shape
144-
return np.allclose(mat1, mat2)
136+
return np.allclose(mat1, mat2, 1e-3, 1e-6)
145137

146138

147139
class single_qubit_test(TestCase):
@@ -257,13 +249,33 @@ def single_qubit_random_layer(self, gatestrength):
257249
qdev = tq.NoiseDevice(n_wires=qubit_num, bsz=1, device="cpu", record_op=True)
258250
rho_qiskit = qiskitDensity.from_label('0' * qubit_num)
259251
gate_num = int(gatestrength * qubit_num)
260-
for i in range(0, gate_num + 1):
252+
gate_list = []
253+
for i in range(0, gate_num):
261254
random_gate_index = randrange(length)
262255
gate_pair = single_gate_list[random_gate_index]
263256
random_qubit_index = randrange(qubit_num)
257+
gate_list.append(gate_pair["name"])
264258
gate_pair['tq'](qdev, [random_qubit_index])
265259
rho_qiskit = rho_qiskit.evolve(gate_pair['qiskit'](), [qubit_num - 1 - random_qubit_index])
266-
260+
'''
261+
print(i)
262+
print("gate list:")
263+
print(gate_list)
264+
print("qdev history")
265+
print(qdev.op_history)
266+
mat1_tmp = np.array(qdev.get_2d_matrix(0))
267+
mat2_tmp = np.array(rho_qiskit.to_operator())
268+
print("Torch quantum result:")
269+
print(mat1_tmp)
270+
print("Qiskit result:")
271+
print(mat2_tmp)
272+
if not density_is_close(mat1_tmp, mat2_tmp):
273+
passed = False
274+
print("Failed! Current gate list:")
275+
print(gate_list)
276+
print(qdev.op_history)
277+
return passed
278+
'''
267279
mat1 = np.array(qdev.get_2d_matrix(0))
268280
mat2 = np.array(rho_qiskit.to_operator())
269281

@@ -276,11 +288,14 @@ def single_qubit_random_layer(self, gatestrength):
276288
print(
277289
"Test falied for single qubit gate random layer on qubit with %d gates when qubit_number is %d!" % (
278290
gate_num, qubit_num))
291+
print(gate_list)
292+
print(qdev.op_history)
293+
279294
return passed
280295

281296
def test_single_qubit_random_layer(self):
282297
repeat_num = 5
283-
gate_strength_list = [0.5, 1, 1.5, 2]
298+
gate_strength_list = [0.5, 1, 1.5, 2, 2.5, 3.5, 4.5, 5, 5.5, 6.5, 7.5, 8.5, 9.5, 10]
284299
for i in range(0, repeat_num):
285300
for gatestrength in gate_strength_list:
286301
self.assertTrue(self.single_qubit_random_layer(gatestrength))
@@ -434,10 +449,9 @@ def mix_random_layer(self, gatestrength):
434449
gate_num, qubit_num))
435450
return passed
436451

437-
438452
def test_mix_random_layer(self):
439453
repeat_num = 5
440454
gate_strength_list = [0.5, 1, 1.5, 2]
441455
for i in range(0, repeat_num):
442456
for gatestrength in gate_strength_list:
443-
self.assertTrue(self.mix_random_layer(gatestrength))
457+
self.assertTrue(self.mix_random_layer(gatestrength))

torchquantum/functional/gate_wrapper.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from torchpack.utils.logging import logger
99
from torchquantum.util import normalize_statevector
1010

11-
1211
if TYPE_CHECKING:
1312
from torchquantum.device import QuantumDevice, NoiseDevice
1413
else:
@@ -274,6 +273,7 @@ def apply_unitary_density_bmm(density, mat, wires):
274273
device_wires = wires
275274
n_qubit = density.dim() // 2
276275
mat = mat.type(C_DTYPE).to(density.device)
276+
277277
"""
278278
Compute U \rho
279279
"""
@@ -298,7 +298,14 @@ def apply_unitary_density_bmm(density, mat, wires):
298298
"""
299299
Compute \rho U^\dagger
300300
"""
301-
matdag = torch.conj(mat)
301+
302+
303+
matdag = mat.conj()
304+
if matdag.dim() == 3:
305+
matdag = matdag.permute(0, 2, 1)
306+
else:
307+
matdag = matdag.permute(1, 0)
308+
302309
matdag = matdag.type(C_DTYPE).to(density.device)
303310

304311
devices_dims_dag = [n_qubit + w + 1 for w in device_wires]
@@ -431,8 +438,8 @@ def gate_wrapper(
431438
else:
432439
matrix = matrix.permute(1, 0)
433440
assert np.log2(matrix.shape[-1]) == len(wires)
434-
#TODO: There might be a better way to discriminate noisedevice and normal statevector device
435-
if q_device.device_name=="noisedevice":
441+
# TODO: There might be a better way to discriminate noisedevice and normal statevector device
442+
if q_device.device_name == "noisedevice":
436443
density = q_device.densities
437444
if method == "einsum":
438445
return
@@ -444,4 +451,3 @@ def gate_wrapper(
444451
q_device.states = apply_unitary_einsum(state, matrix, wires)
445452
elif method == "bmm":
446453
q_device.states = apply_unitary_bmm(state, matrix, wires)
447-

torchquantum/functional/paulix.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ def toffoli(
508508
509509
"""
510510
name = "toffoli"
511-
mat = mat_dict[name]
511+
mat = _x_mat_dict[name]
512512
gate_wrapper(
513513
name=name,
514514
mat=mat,
@@ -552,7 +552,7 @@ def rc3x(
552552
None.
553553
"""
554554
name = "rc3x"
555-
mat = mat_dict[name]
555+
mat = _x_mat_dict[name]
556556
gate_wrapper(
557557
name=name,
558558
mat=mat,
@@ -596,7 +596,7 @@ def rccx(
596596
None.
597597
"""
598598
name = "rccx"
599-
mat = mat_dict[name]
599+
mat = _x_mat_dict[name]
600600
gate_wrapper(
601601
name=name,
602602
mat=mat,

0 commit comments

Comments
 (0)