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.

Files changed (72) hide show
  1. tensorcircuit/__init__.py +5 -1
  2. tensorcircuit/abstractcircuit.py +4 -0
  3. tensorcircuit/analogcircuit.py +413 -0
  4. tensorcircuit/applications/layers.py +1 -1
  5. tensorcircuit/applications/van.py +1 -1
  6. tensorcircuit/backends/abstract_backend.py +312 -5
  7. tensorcircuit/backends/cupy_backend.py +3 -1
  8. tensorcircuit/backends/jax_backend.py +92 -3
  9. tensorcircuit/backends/jax_ops.py +108 -0
  10. tensorcircuit/backends/numpy_backend.py +49 -3
  11. tensorcircuit/backends/pytorch_backend.py +92 -3
  12. tensorcircuit/backends/tensorflow_backend.py +102 -3
  13. tensorcircuit/basecircuit.py +123 -82
  14. tensorcircuit/circuit.py +67 -57
  15. tensorcircuit/cloud/local.py +1 -1
  16. tensorcircuit/cloud/quafu_provider.py +1 -1
  17. tensorcircuit/cloud/tencent.py +1 -1
  18. tensorcircuit/compiler/simple_compiler.py +2 -2
  19. tensorcircuit/cons.py +1 -0
  20. tensorcircuit/densitymatrix.py +16 -11
  21. tensorcircuit/experimental.py +7 -152
  22. tensorcircuit/fgs.py +5 -6
  23. tensorcircuit/gates.py +66 -22
  24. tensorcircuit/keras.py +3 -3
  25. tensorcircuit/mpscircuit.py +109 -61
  26. tensorcircuit/quantum.py +697 -133
  27. tensorcircuit/quditcircuit.py +733 -0
  28. tensorcircuit/quditgates.py +618 -0
  29. tensorcircuit/results/counts.py +45 -31
  30. tensorcircuit/shadows.py +1 -1
  31. tensorcircuit/simplify.py +3 -1
  32. tensorcircuit/stabilizercircuit.py +4 -2
  33. tensorcircuit/templates/blocks.py +2 -2
  34. tensorcircuit/templates/hamiltonians.py +29 -8
  35. tensorcircuit/templates/lattice.py +676 -335
  36. tensorcircuit/timeevol.py +896 -0
  37. {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/METADATA +50 -25
  38. tensorcircuit_nightly-1.4.0.dev20251103.dist-info/RECORD +96 -0
  39. {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/top_level.txt +0 -1
  40. tensorcircuit_nightly-1.3.0.dev20250728.dist-info/RECORD +0 -122
  41. tests/__init__.py +0 -0
  42. tests/conftest.py +0 -67
  43. tests/test_backends.py +0 -1035
  44. tests/test_calibrating.py +0 -149
  45. tests/test_channels.py +0 -409
  46. tests/test_circuit.py +0 -1713
  47. tests/test_cloud.py +0 -219
  48. tests/test_compiler.py +0 -147
  49. tests/test_dmcircuit.py +0 -555
  50. tests/test_ensemble.py +0 -72
  51. tests/test_fgs.py +0 -318
  52. tests/test_gates.py +0 -156
  53. tests/test_hamiltonians.py +0 -159
  54. tests/test_interfaces.py +0 -557
  55. tests/test_keras.py +0 -160
  56. tests/test_lattice.py +0 -1666
  57. tests/test_miscs.py +0 -334
  58. tests/test_mpscircuit.py +0 -341
  59. tests/test_noisemodel.py +0 -156
  60. tests/test_qaoa.py +0 -86
  61. tests/test_qem.py +0 -152
  62. tests/test_quantum.py +0 -549
  63. tests/test_quantum_attr.py +0 -42
  64. tests/test_results.py +0 -379
  65. tests/test_shadows.py +0 -160
  66. tests/test_simplify.py +0 -46
  67. tests/test_stabilizer.py +0 -226
  68. tests/test_templates.py +0 -218
  69. tests/test_torchnn.py +0 -99
  70. tests/test_van.py +0 -102
  71. {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/WHEEL +0 -0
  72. {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)