tensorcircuit-nightly 1.3.0.dev20250728__py3-none-any.whl → 1.4.0.dev20251103__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tensorcircuit-nightly might be problematic. Click here for more details.
- tensorcircuit/__init__.py +5 -1
- tensorcircuit/abstractcircuit.py +4 -0
- tensorcircuit/analogcircuit.py +413 -0
- tensorcircuit/applications/layers.py +1 -1
- tensorcircuit/applications/van.py +1 -1
- tensorcircuit/backends/abstract_backend.py +312 -5
- tensorcircuit/backends/cupy_backend.py +3 -1
- tensorcircuit/backends/jax_backend.py +92 -3
- tensorcircuit/backends/jax_ops.py +108 -0
- tensorcircuit/backends/numpy_backend.py +49 -3
- tensorcircuit/backends/pytorch_backend.py +92 -3
- tensorcircuit/backends/tensorflow_backend.py +102 -3
- tensorcircuit/basecircuit.py +123 -82
- tensorcircuit/circuit.py +67 -57
- tensorcircuit/cloud/local.py +1 -1
- tensorcircuit/cloud/quafu_provider.py +1 -1
- tensorcircuit/cloud/tencent.py +1 -1
- tensorcircuit/compiler/simple_compiler.py +2 -2
- tensorcircuit/cons.py +1 -0
- tensorcircuit/densitymatrix.py +16 -11
- tensorcircuit/experimental.py +7 -152
- tensorcircuit/fgs.py +5 -6
- tensorcircuit/gates.py +66 -22
- tensorcircuit/keras.py +3 -3
- tensorcircuit/mpscircuit.py +109 -61
- tensorcircuit/quantum.py +697 -133
- tensorcircuit/quditcircuit.py +733 -0
- tensorcircuit/quditgates.py +618 -0
- tensorcircuit/results/counts.py +45 -31
- tensorcircuit/shadows.py +1 -1
- tensorcircuit/simplify.py +3 -1
- tensorcircuit/stabilizercircuit.py +4 -2
- tensorcircuit/templates/blocks.py +2 -2
- tensorcircuit/templates/hamiltonians.py +29 -8
- tensorcircuit/templates/lattice.py +676 -335
- tensorcircuit/timeevol.py +896 -0
- {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/METADATA +50 -25
- tensorcircuit_nightly-1.4.0.dev20251103.dist-info/RECORD +96 -0
- {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/top_level.txt +0 -1
- tensorcircuit_nightly-1.3.0.dev20250728.dist-info/RECORD +0 -122
- tests/__init__.py +0 -0
- tests/conftest.py +0 -67
- tests/test_backends.py +0 -1035
- tests/test_calibrating.py +0 -149
- tests/test_channels.py +0 -409
- tests/test_circuit.py +0 -1713
- tests/test_cloud.py +0 -219
- tests/test_compiler.py +0 -147
- tests/test_dmcircuit.py +0 -555
- tests/test_ensemble.py +0 -72
- tests/test_fgs.py +0 -318
- tests/test_gates.py +0 -156
- tests/test_hamiltonians.py +0 -159
- tests/test_interfaces.py +0 -557
- tests/test_keras.py +0 -160
- tests/test_lattice.py +0 -1666
- tests/test_miscs.py +0 -334
- tests/test_mpscircuit.py +0 -341
- tests/test_noisemodel.py +0 -156
- tests/test_qaoa.py +0 -86
- tests/test_qem.py +0 -152
- tests/test_quantum.py +0 -549
- tests/test_quantum_attr.py +0 -42
- tests/test_results.py +0 -379
- tests/test_shadows.py +0 -160
- tests/test_simplify.py +0 -46
- tests/test_stabilizer.py +0 -226
- tests/test_templates.py +0 -218
- tests/test_torchnn.py +0 -99
- tests/test_van.py +0 -102
- {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/WHEEL +0 -0
- {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/licenses/LICENSE +0 -0
tests/test_calibrating.py
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import os
|
|
3
|
-
import numpy as np
|
|
4
|
-
import pytest
|
|
5
|
-
from pytest_lazyfixture import lazy_fixture as lf
|
|
6
|
-
from scipy.optimize import curve_fit
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
thisfile = os.path.abspath(__file__)
|
|
10
|
-
modulepath = os.path.dirname(os.path.dirname(thisfile))
|
|
11
|
-
|
|
12
|
-
sys.path.insert(0, modulepath)
|
|
13
|
-
import tensorcircuit as tc
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def fit_function(x_values, y_values, function, init_params):
|
|
17
|
-
fitparams, _ = curve_fit(function, x_values, y_values, init_params)
|
|
18
|
-
return fitparams
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def T1_cali(t1, t2, time, method, excitedstatepopulation):
|
|
22
|
-
# calibrating experiments
|
|
23
|
-
nstep = int(4 * t1 / time)
|
|
24
|
-
pex = []
|
|
25
|
-
for i in range(nstep):
|
|
26
|
-
dmc = tc.DMCircuit(1)
|
|
27
|
-
dmc.x(0)
|
|
28
|
-
for _ in range(i):
|
|
29
|
-
dmc.i(0)
|
|
30
|
-
dmc.thermalrelaxation(
|
|
31
|
-
0,
|
|
32
|
-
t1=t1,
|
|
33
|
-
t2=t2,
|
|
34
|
-
time=time,
|
|
35
|
-
method=method,
|
|
36
|
-
excitedstatepopulation=excitedstatepopulation,
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
val = dmc.expectation_ps(z=[0])
|
|
40
|
-
p = (1 - val) / 2.0
|
|
41
|
-
pex.append(p)
|
|
42
|
-
|
|
43
|
-
timelist = np.array([i * time for i in range(nstep)])
|
|
44
|
-
measurement = np.array(np.real(pex))
|
|
45
|
-
|
|
46
|
-
return measurement, timelist
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def T2_cali(t1, t2, time, method, excitedstatepopulation):
|
|
50
|
-
# calibrating experiments
|
|
51
|
-
nstep = int(4 * t2 / time)
|
|
52
|
-
pex = []
|
|
53
|
-
for i in range(nstep):
|
|
54
|
-
dmc = tc.DMCircuit(1)
|
|
55
|
-
dmc.h(0)
|
|
56
|
-
for _ in range(0, i):
|
|
57
|
-
dmc.i(0)
|
|
58
|
-
dmc.thermalrelaxation(
|
|
59
|
-
0,
|
|
60
|
-
t1=t1,
|
|
61
|
-
t2=t2,
|
|
62
|
-
time=time,
|
|
63
|
-
method=method,
|
|
64
|
-
excitedstatepopulation=excitedstatepopulation,
|
|
65
|
-
)
|
|
66
|
-
# dmc.rz(0,theta = i*np.pi/1.5)
|
|
67
|
-
dmc.h(0)
|
|
68
|
-
|
|
69
|
-
val = dmc.expectation_ps(z=[0])
|
|
70
|
-
p = (1 - val) / 2.0
|
|
71
|
-
pex.append(p)
|
|
72
|
-
|
|
73
|
-
timelist = np.array([i * time for i in range(nstep)])
|
|
74
|
-
measurement = np.array(np.real(pex))
|
|
75
|
-
|
|
76
|
-
return measurement, timelist
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def dep_cali(dep, nqubit):
|
|
80
|
-
pex = []
|
|
81
|
-
nstep = 40
|
|
82
|
-
for i in range(nstep):
|
|
83
|
-
dmc = tc.DMCircuit(1)
|
|
84
|
-
dmc.x(0)
|
|
85
|
-
for _ in range(i):
|
|
86
|
-
dmc.s(0)
|
|
87
|
-
dmc.generaldepolarizing(0, p=dep, num_qubits=nqubit)
|
|
88
|
-
|
|
89
|
-
val = dmc.expectation_ps(z=[0])
|
|
90
|
-
p = (1 - val) / 2.0
|
|
91
|
-
if i % 2 == 0:
|
|
92
|
-
pex.append(p)
|
|
93
|
-
|
|
94
|
-
timelist = np.array([i for i in range(0, nstep, 2)])
|
|
95
|
-
measurement = np.array(np.real(pex))
|
|
96
|
-
|
|
97
|
-
return measurement, timelist
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
101
|
-
def test_cali_t1(backend):
|
|
102
|
-
t1 = 300
|
|
103
|
-
t2 = 100
|
|
104
|
-
time = 100
|
|
105
|
-
method = "AUTO"
|
|
106
|
-
excitedstatepopulation = 0
|
|
107
|
-
measurement, timelist = T1_cali(t1, t2, time, method, excitedstatepopulation)
|
|
108
|
-
|
|
109
|
-
fit_params = fit_function(
|
|
110
|
-
timelist, measurement, lambda x, A, C, T: (A * np.exp(-x / T) + C), [-3, 0, 100]
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
_, _, T = fit_params
|
|
114
|
-
|
|
115
|
-
np.testing.assert_allclose(t1, T, atol=1e-1)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
119
|
-
def test_cali_t2(backend):
|
|
120
|
-
t1 = 300
|
|
121
|
-
t2 = 280
|
|
122
|
-
time = 50
|
|
123
|
-
method = "AUTO"
|
|
124
|
-
excitedstatepopulation = 0
|
|
125
|
-
measurement, timelist = T2_cali(t1, t2, time, method, excitedstatepopulation)
|
|
126
|
-
|
|
127
|
-
fit_params = fit_function(
|
|
128
|
-
timelist, measurement, lambda x, A, C, T: (A * np.exp(-x / T) + C), [-3, 0, 100]
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
_, _, T = fit_params
|
|
132
|
-
|
|
133
|
-
np.testing.assert_allclose(t2, T, atol=1e-1)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
137
|
-
def test_cali_dep(backend):
|
|
138
|
-
dep = 0.02
|
|
139
|
-
nqubit = 1
|
|
140
|
-
measurement, timelist = dep_cali(dep, nqubit)
|
|
141
|
-
|
|
142
|
-
fit_params = fit_function(
|
|
143
|
-
timelist, measurement, lambda x, A, B, C: (A * B**x + C), [-0, 0, 0]
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
_, B, _ = fit_params
|
|
147
|
-
dep1 = (1 - B) / 4.0**nqubit
|
|
148
|
-
|
|
149
|
-
np.testing.assert_allclose(dep, dep1, atol=1e-1)
|
tests/test_channels.py
DELETED
|
@@ -1,409 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import os
|
|
3
|
-
import numpy as np
|
|
4
|
-
import pytest
|
|
5
|
-
from pytest_lazyfixture import lazy_fixture as lf
|
|
6
|
-
from scipy.optimize import minimize
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
thisfile = os.path.abspath(__file__)
|
|
10
|
-
modulepath = os.path.dirname(os.path.dirname(thisfile))
|
|
11
|
-
|
|
12
|
-
sys.path.insert(0, modulepath)
|
|
13
|
-
import tensorcircuit as tc
|
|
14
|
-
from tensorcircuit.channels import (
|
|
15
|
-
depolarizingchannel,
|
|
16
|
-
amplitudedampingchannel,
|
|
17
|
-
phasedampingchannel,
|
|
18
|
-
resetchannel,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
23
|
-
def test_channel_identity(backend):
|
|
24
|
-
cs = depolarizingchannel(0.1, 0.15, 0.2)
|
|
25
|
-
tc.channels.single_qubit_kraus_identity_check(cs)
|
|
26
|
-
cs = amplitudedampingchannel(0.25, 0.3)
|
|
27
|
-
tc.channels.single_qubit_kraus_identity_check(cs)
|
|
28
|
-
cs = phasedampingchannel(0.6)
|
|
29
|
-
tc.channels.single_qubit_kraus_identity_check(cs)
|
|
30
|
-
cs = resetchannel()
|
|
31
|
-
tc.channels.single_qubit_kraus_identity_check(cs)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
35
|
-
def test_dep(backend):
|
|
36
|
-
cs = tc.channels.generaldepolarizingchannel(0.1, 1)
|
|
37
|
-
tc.channels.kraus_identity_check(cs)
|
|
38
|
-
|
|
39
|
-
cs = tc.channels.generaldepolarizingchannel([0.1, 0.1, 0.1], 1)
|
|
40
|
-
tc.channels.kraus_identity_check(cs)
|
|
41
|
-
|
|
42
|
-
cs = tc.channels.generaldepolarizingchannel(0.02, 2)
|
|
43
|
-
tc.channels.kraus_identity_check(cs)
|
|
44
|
-
|
|
45
|
-
cs2 = tc.channels.isotropicdepolarizingchannel(0.02 * 15, 2)
|
|
46
|
-
for c1, c2 in zip(cs, cs2):
|
|
47
|
-
np.testing.assert_allclose(c1.tensor, c2.tensor)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
51
|
-
def test_rep_transformation(backend):
|
|
52
|
-
kraus_set = []
|
|
53
|
-
kraus_set.append(tc.channels.phasedampingchannel(0.2))
|
|
54
|
-
kraus_set.append(tc.channels.resetchannel())
|
|
55
|
-
kraus_set.append(tc.channels.generaldepolarizingchannel(0.1, 1))
|
|
56
|
-
kraus_set.append(tc.channels.phasedampingchannel(0.5))
|
|
57
|
-
|
|
58
|
-
density_set = []
|
|
59
|
-
dx = np.array([[0.5, 0.5], [0.5, 0.5]])
|
|
60
|
-
dy = np.array([[0.5, 0.5 * 1j], [-0.5 * 1j, 0.5]])
|
|
61
|
-
density_set.append(dx)
|
|
62
|
-
density_set.append(dy)
|
|
63
|
-
density_set.append(0.1 * dx + 0.9 * dy)
|
|
64
|
-
|
|
65
|
-
for density_matrix in density_set:
|
|
66
|
-
for kraus in kraus_set:
|
|
67
|
-
tc.channels.check_rep_transformation(kraus, density_matrix, verbose=False)
|
|
68
|
-
|
|
69
|
-
kraus = tc.channels.generaldepolarizingchannel(0.01, 2)
|
|
70
|
-
density_matrix = np.array(
|
|
71
|
-
[
|
|
72
|
-
[0.25, 0.25, 0.25, 0.25],
|
|
73
|
-
[0.25, 0.25, 0.25, 0.25],
|
|
74
|
-
[0.25, 0.25, 0.25, 0.25],
|
|
75
|
-
[0.25, 0.25, 0.25, 0.25],
|
|
76
|
-
]
|
|
77
|
-
)
|
|
78
|
-
tc.channels.check_rep_transformation(kraus, density_matrix, verbose=False)
|
|
79
|
-
|
|
80
|
-
# test
|
|
81
|
-
choi = np.zeros([4, 4])
|
|
82
|
-
kraus = tc.channels.choi_to_kraus(choi)
|
|
83
|
-
np.testing.assert_allclose(kraus, [np.zeros([2, 2])], atol=1e-5)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
87
|
-
def test_thermal(backend):
|
|
88
|
-
t2 = 100
|
|
89
|
-
time = 100
|
|
90
|
-
|
|
91
|
-
t1 = 180
|
|
92
|
-
kraus = tc.channels.thermalrelaxationchannel(t1, t2, time, "AUTO", 0.1)
|
|
93
|
-
supop1 = tc.channels.kraus_to_super(kraus)
|
|
94
|
-
|
|
95
|
-
kraus = tc.channels.thermalrelaxationchannel(t1, t2, time, "ByKraus", 0.1)
|
|
96
|
-
supop2 = tc.channels.kraus_to_super(kraus)
|
|
97
|
-
|
|
98
|
-
np.testing.assert_allclose(supop1, supop2, atol=1e-5)
|
|
99
|
-
|
|
100
|
-
t1 = 80
|
|
101
|
-
kraus = tc.channels.thermalrelaxationchannel(t1, t2, time, "AUTO", 0.1)
|
|
102
|
-
supop1 = tc.channels.kraus_to_super(kraus)
|
|
103
|
-
|
|
104
|
-
kraus = tc.channels.thermalrelaxationchannel(t1, t2, time, "ByChoi", 0.1)
|
|
105
|
-
supop2 = tc.channels.kraus_to_super(kraus)
|
|
106
|
-
|
|
107
|
-
np.testing.assert_allclose(supop1, supop2, atol=1e-5)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
111
|
-
def test_noisecircuit(backend):
|
|
112
|
-
# Monte carlo simulation
|
|
113
|
-
def noisecircuit(X):
|
|
114
|
-
n = 1
|
|
115
|
-
c = tc.Circuit(n)
|
|
116
|
-
c.x(0)
|
|
117
|
-
# noise = tc.channels.thermalrelaxationchannel(300, 400, 1000, "AUTO", 0)
|
|
118
|
-
# c.general_kraus(noise, 0, status=X)
|
|
119
|
-
c.thermalrelaxation(
|
|
120
|
-
0,
|
|
121
|
-
t1=300,
|
|
122
|
-
t2=400,
|
|
123
|
-
time=1000,
|
|
124
|
-
method="ByChoi",
|
|
125
|
-
excitedstatepopulation=0,
|
|
126
|
-
status=X,
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
val = c.expectation_ps(z=[0])
|
|
130
|
-
return val
|
|
131
|
-
|
|
132
|
-
noisec_vmap = tc.backend.vmap(noisecircuit, vectorized_argnums=0)
|
|
133
|
-
noisec_jit = tc.backend.jit(noisec_vmap)
|
|
134
|
-
|
|
135
|
-
nmc = 10000
|
|
136
|
-
X = tc.backend.implicit_randu(nmc)
|
|
137
|
-
valuemc = sum(tc.backend.numpy(noisec_jit(X))) / nmc
|
|
138
|
-
|
|
139
|
-
# Density matrix simulation
|
|
140
|
-
def noisecircuitdm():
|
|
141
|
-
n = 1
|
|
142
|
-
dmc = tc.DMCircuit(n)
|
|
143
|
-
dmc.x(0)
|
|
144
|
-
dmc.thermalrelaxation(
|
|
145
|
-
0, t1=300, t2=400, time=1000, method="ByChoi", excitedstatepopulation=0
|
|
146
|
-
)
|
|
147
|
-
val = dmc.expectation_ps(z=[0])
|
|
148
|
-
return val
|
|
149
|
-
|
|
150
|
-
noisec_jit = tc.backend.jit(noisecircuitdm)
|
|
151
|
-
valuedm = noisec_jit()
|
|
152
|
-
|
|
153
|
-
np.testing.assert_allclose(valuemc, valuedm, atol=1e-1)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
157
|
-
def test_readout(backend):
|
|
158
|
-
nqubit = 3
|
|
159
|
-
c = tc.Circuit(nqubit)
|
|
160
|
-
c.X(0)
|
|
161
|
-
|
|
162
|
-
value = c.sample_expectation_ps(z=[0, 1, 2])
|
|
163
|
-
valueaim = -1
|
|
164
|
-
np.testing.assert_allclose(value, valueaim, atol=1e-3)
|
|
165
|
-
|
|
166
|
-
readout_error = []
|
|
167
|
-
readout_error.append([0.9, 0.75]) # readout error of qubit 0
|
|
168
|
-
readout_error.append([0.4, 0.7]) # readout error of qubit 1
|
|
169
|
-
readout_error.append([0.7, 0.9]) # readout error of qubit 2
|
|
170
|
-
|
|
171
|
-
# readout_error is a list
|
|
172
|
-
value = c.sample_expectation_ps(z=[0, 1, 2], readout_error=readout_error)
|
|
173
|
-
valueaim = 0.04
|
|
174
|
-
np.testing.assert_allclose(value, valueaim, atol=1e-1)
|
|
175
|
-
|
|
176
|
-
# readout_error is a tensor
|
|
177
|
-
readout_error = tc.array_to_tensor(readout_error)
|
|
178
|
-
value = c.sample_expectation_ps(z=[0, 1, 2], readout_error=readout_error)
|
|
179
|
-
valueaim = 0.04
|
|
180
|
-
np.testing.assert_allclose(value, valueaim, atol=1e-1)
|
|
181
|
-
|
|
182
|
-
# test jitble
|
|
183
|
-
def jitest(readout_error):
|
|
184
|
-
nqubit = 3
|
|
185
|
-
c = tc.Circuit(nqubit)
|
|
186
|
-
c.X(0)
|
|
187
|
-
return c.sample_expectation_ps(z=[0, 1, 2], readout_error=readout_error)
|
|
188
|
-
|
|
189
|
-
calvalue = tc.backend.jit(jitest)
|
|
190
|
-
value = calvalue(readout_error)
|
|
191
|
-
valueaim = 0.04
|
|
192
|
-
np.testing.assert_allclose(value, valueaim, atol=1e-1)
|
|
193
|
-
|
|
194
|
-
# test contractor time
|
|
195
|
-
# start = timeit.default_timer()
|
|
196
|
-
# def speed(nqubit):
|
|
197
|
-
# c = tc.Circuit(nqubit)
|
|
198
|
-
# c.X(0)
|
|
199
|
-
# readout_error = []
|
|
200
|
-
# for _ in range(nqubit):
|
|
201
|
-
# readout_error.append([0.9, 0.75]) # readout error of qubit 0
|
|
202
|
-
# value = c.sample_expectation_ps(
|
|
203
|
-
# z=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], readout_error=readout_error
|
|
204
|
-
# )
|
|
205
|
-
# return value
|
|
206
|
-
|
|
207
|
-
# speed(10)
|
|
208
|
-
# stop = timeit.default_timer()
|
|
209
|
-
# print("Time: ", stop - start)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
213
|
-
def test_noisesample(backend):
|
|
214
|
-
readout_error = []
|
|
215
|
-
readout_error.append([0.9, 0.75]) # readout error of qubit 0
|
|
216
|
-
readout_error.append([0.4, 0.7]) # readout error of qubit 1
|
|
217
|
-
readout_error.append([0.7, 0.9]) # readout error of qubit 2
|
|
218
|
-
|
|
219
|
-
c = tc.Circuit(3)
|
|
220
|
-
c.H(0)
|
|
221
|
-
c.cnot(0, 1)
|
|
222
|
-
print(c.sample(allow_state=True, readout_error=readout_error))
|
|
223
|
-
print(c.sample(batch=8, allow_state=True, readout_error=readout_error))
|
|
224
|
-
print(
|
|
225
|
-
c.sample(
|
|
226
|
-
batch=8,
|
|
227
|
-
allow_state=True,
|
|
228
|
-
readout_error=readout_error,
|
|
229
|
-
random_generator=tc.backend.get_random_state(42),
|
|
230
|
-
)
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
key = tc.backend.get_random_state(42)
|
|
234
|
-
bs = c.sample(
|
|
235
|
-
batch=1000, allow_state=True, format_="count_dict_bin", random_generator=key
|
|
236
|
-
)
|
|
237
|
-
print(bs)
|
|
238
|
-
bs = c.sample(
|
|
239
|
-
batch=1000,
|
|
240
|
-
allow_state=True,
|
|
241
|
-
readout_error=readout_error,
|
|
242
|
-
format_="count_dict_bin",
|
|
243
|
-
random_generator=key,
|
|
244
|
-
)
|
|
245
|
-
print(bs)
|
|
246
|
-
|
|
247
|
-
# test jitble
|
|
248
|
-
def jitest(readout_error):
|
|
249
|
-
c = tc.Circuit(3)
|
|
250
|
-
c.H(0)
|
|
251
|
-
c.cnot(0, 1)
|
|
252
|
-
return c.sample(batch=8, allow_state=True, format_="sample_int")
|
|
253
|
-
|
|
254
|
-
calsample = tc.backend.jit(jitest)
|
|
255
|
-
sampletest = calsample(readout_error)
|
|
256
|
-
print(sampletest)
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
# mitigate readout error
|
|
260
|
-
def miti_readout_circ(nqubit):
|
|
261
|
-
miticirc = []
|
|
262
|
-
for i in range(2**nqubit):
|
|
263
|
-
name = "{:0" + str(nqubit) + "b}"
|
|
264
|
-
lisbs = [int(x) for x in name.format(i)]
|
|
265
|
-
c = tc.Circuit(nqubit)
|
|
266
|
-
for k in range(nqubit):
|
|
267
|
-
if lisbs[k] == 1:
|
|
268
|
-
c.X(k)
|
|
269
|
-
miticirc.append(c)
|
|
270
|
-
return miticirc
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
def probability_bs(bs):
|
|
274
|
-
nqubit = len(list(bs.keys())[0])
|
|
275
|
-
probability = [0] * 2**nqubit
|
|
276
|
-
shots = sum([bs[s] for s in bs])
|
|
277
|
-
for s in bs:
|
|
278
|
-
probability[int(s, 2)] = bs[s] / shots
|
|
279
|
-
return probability
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
def mitigate_probability(probability_noise, calmatrix, method="inverse"):
|
|
283
|
-
if method == "inverse":
|
|
284
|
-
X = np.linalg.inv(calmatrix)
|
|
285
|
-
Y = probability_noise
|
|
286
|
-
probability_cali = X @ Y
|
|
287
|
-
else: # method="square"
|
|
288
|
-
|
|
289
|
-
def fun(x):
|
|
290
|
-
return sum((probability_noise - calmatrix @ x) ** 2)
|
|
291
|
-
|
|
292
|
-
x0 = np.random.rand(len(probability_noise))
|
|
293
|
-
cons = {"type": "eq", "fun": lambda x: 1 - sum(x)}
|
|
294
|
-
bnds = tuple((0, 1) for x in x0)
|
|
295
|
-
res = minimize(fun, x0, method="SLSQP", constraints=cons, bounds=bnds, tol=1e-6)
|
|
296
|
-
probability_cali = res.x
|
|
297
|
-
return probability_cali
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
def mitigate_readout(nqubit, circ, readout_error):
|
|
301
|
-
key = tc.backend.get_random_state(42)
|
|
302
|
-
keys = []
|
|
303
|
-
for _ in range(2**nqubit):
|
|
304
|
-
key, subkey = tc.backend.random_split(key)
|
|
305
|
-
keys.append(subkey)
|
|
306
|
-
|
|
307
|
-
# calibration matrix
|
|
308
|
-
miticirc = miti_readout_circ(nqubit)
|
|
309
|
-
shots = 100000
|
|
310
|
-
calmatrix = np.zeros((2**nqubit, 2**nqubit))
|
|
311
|
-
for i in range(2**nqubit):
|
|
312
|
-
c = miticirc[i]
|
|
313
|
-
bs = c.sample(
|
|
314
|
-
batch=shots,
|
|
315
|
-
allow_state=True,
|
|
316
|
-
readout_error=readout_error,
|
|
317
|
-
format_="count_dict_bin",
|
|
318
|
-
random_generator=keys[i],
|
|
319
|
-
)
|
|
320
|
-
for s in bs:
|
|
321
|
-
calmatrix[int(s, 2)][i] = bs[s] / shots
|
|
322
|
-
|
|
323
|
-
key, subkey = tc.backend.random_split(key)
|
|
324
|
-
bs = circ.sample(
|
|
325
|
-
batch=shots, allow_state=True, format_="count_dict_bin", random_generator=subkey
|
|
326
|
-
)
|
|
327
|
-
probability_perfect = probability_bs(bs)
|
|
328
|
-
print("probability_without_readouterror", probability_perfect)
|
|
329
|
-
|
|
330
|
-
key, subkey = tc.backend.random_split(key)
|
|
331
|
-
bs = circ.sample(
|
|
332
|
-
batch=shots,
|
|
333
|
-
allow_state=True,
|
|
334
|
-
readout_error=readout_error,
|
|
335
|
-
format_="count_dict_bin",
|
|
336
|
-
random_generator=subkey,
|
|
337
|
-
)
|
|
338
|
-
probability_noise = probability_bs(bs)
|
|
339
|
-
print("probability_with_readouterror", probability_noise)
|
|
340
|
-
|
|
341
|
-
probability_miti = mitigate_probability(
|
|
342
|
-
probability_noise, calmatrix, method="inverse"
|
|
343
|
-
)
|
|
344
|
-
print("mitigate_readouterror_method1", probability_miti)
|
|
345
|
-
|
|
346
|
-
probability_miti = mitigate_probability(
|
|
347
|
-
probability_noise, calmatrix, method="square"
|
|
348
|
-
)
|
|
349
|
-
print("mitigate_readouterror_method2", probability_miti)
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
353
|
-
def test_readout_mitigate(backend):
|
|
354
|
-
nqubit = 3
|
|
355
|
-
c = tc.Circuit(nqubit)
|
|
356
|
-
c.H(0)
|
|
357
|
-
c.cnot(0, 1)
|
|
358
|
-
c.X(2)
|
|
359
|
-
|
|
360
|
-
readout_error = []
|
|
361
|
-
readout_error.append([0.9, 0.75]) # readout error of qubit 0, p0|0=0.9, p1|1=0.75
|
|
362
|
-
readout_error.append([0.4, 0.7]) # readout error of qubit 1
|
|
363
|
-
readout_error.append([0.7, 0.9]) # readout error of qubit 2
|
|
364
|
-
|
|
365
|
-
mitigate_readout(nqubit, c, readout_error)
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
def test_valid_kraus_operators():
|
|
369
|
-
# Test with phase damping channel - should pass
|
|
370
|
-
kraus = phasedampingchannel(0.3)
|
|
371
|
-
assert tc.DMCircuit.check_kraus(kraus) is True
|
|
372
|
-
|
|
373
|
-
# Test with depolarizing channel - should pass
|
|
374
|
-
kraus = depolarizingchannel(0.1, 0.1, 0.1)
|
|
375
|
-
assert tc.DMCircuit.check_kraus(kraus) is True
|
|
376
|
-
|
|
377
|
-
# Test with reset channel - should pass
|
|
378
|
-
kraus = resetchannel()
|
|
379
|
-
assert tc.DMCircuit.check_kraus(kraus) is True
|
|
380
|
-
|
|
381
|
-
# Test with amplitude damping channel - should pass
|
|
382
|
-
kraus = amplitudedampingchannel(0.2, 0.3)
|
|
383
|
-
assert tc.DMCircuit.check_kraus(kraus) is True
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
def test_invalid_kraus_operators():
|
|
387
|
-
# Create invalid Kraus operators that don't sum to identity
|
|
388
|
-
invalid_kraus = [
|
|
389
|
-
tc.gates.Gate(np.array([[1.0, 0], [0, 1.0]])),
|
|
390
|
-
tc.gates.Gate(np.array([[1.0, 0], [0, 1.0]])),
|
|
391
|
-
]
|
|
392
|
-
|
|
393
|
-
with pytest.raises(ValueError):
|
|
394
|
-
tc.DMCircuit.check_kraus(invalid_kraus)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
def test_single_kraus_operator():
|
|
398
|
-
# Test with single unitary operator (should pass)
|
|
399
|
-
kraus = [tc.gates.Gate(np.array([[1.0, 0], [0, 1.0]]))]
|
|
400
|
-
assert tc.DMCircuit.check_kraus(kraus) is True
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
def test_non_square_matrices():
|
|
404
|
-
# Test with non-square matrices (should raise error during matmul)
|
|
405
|
-
invalid_kraus = [
|
|
406
|
-
tc.gates.Gate(np.array([[1.0, 0]])),
|
|
407
|
-
]
|
|
408
|
-
with pytest.raises(ValueError):
|
|
409
|
-
tc.DMCircuit.check_kraus(invalid_kraus)
|