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_circuit.py DELETED
@@ -1,1713 +0,0 @@
1
- # pylint: disable=invalid-name
2
-
3
- import os
4
- import sys
5
- from functools import partial
6
-
7
- import numpy as np
8
- import opt_einsum as oem
9
- import pytest
10
- from pytest_lazyfixture import lazy_fixture as lf
11
-
12
- # see https://stackoverflow.com/questions/56307329/how-can-i-parametrize-tests-to-run-with-different-fixtures-in-pytest
13
-
14
- thisfile = os.path.abspath(__file__)
15
- modulepath = os.path.dirname(os.path.dirname(thisfile))
16
-
17
- sys.path.insert(0, modulepath)
18
- import tensorcircuit as tc
19
-
20
-
21
- @pytest.mark.parametrize("backend", [lf("npb"), lf("cpb")])
22
- def test_wavefunction(backend):
23
- qc = tc.Circuit(2)
24
- qc.unitary(
25
- 0,
26
- 1,
27
- unitary=tc.gates.Gate(np.arange(16).reshape(2, 2, 2, 2).astype(np.complex64)),
28
- )
29
- assert np.real(qc.wavefunction()[2]) == 8
30
- qc = tc.Circuit(2)
31
- qc.unitary(
32
- 1,
33
- 0,
34
- unitary=tc.gates.Gate(np.arange(16).reshape(2, 2, 2, 2).astype(np.complex64)),
35
- )
36
- qc.wavefunction()
37
- assert np.real(qc.wavefunction()[2]) == 4
38
- qc = tc.Circuit(2)
39
- qc.unitary(
40
- 0, unitary=tc.gates.Gate(np.arange(4).reshape(2, 2).astype(np.complex64))
41
- )
42
- qc.wavefunction()
43
- assert np.real(qc.wavefunction()[2]) == 2
44
-
45
-
46
- @pytest.mark.parametrize("backend", [lf("npb"), lf("cpb")])
47
- def test_basics(backend):
48
- c = tc.Circuit(2)
49
- c.x(0)
50
- np.testing.assert_allclose(tc.backend.numpy(c.amplitude("10")), np.array(1.0))
51
- c.CNOT(0, 1)
52
- np.testing.assert_allclose(tc.backend.numpy(c.amplitude("11")), np.array(1.0))
53
-
54
-
55
- @pytest.mark.parametrize("backend", [lf("npb"), lf("cpb")])
56
- def test_measure(backend):
57
- c = tc.Circuit(3)
58
- c.H(0)
59
- c.h(1)
60
- c.toffoli(0, 1, 2)
61
- assert c.measure(2)[0] in [0, 1]
62
-
63
-
64
- def test_gates_in_circuit():
65
- c = tc.Circuit(2, inputs=np.eye(2**2))
66
- c.iswap(0, 1)
67
- ans = tc.gates.iswap_gate().tensor.reshape([4, 4])
68
- np.testing.assert_allclose(c.state().reshape([4, 4]), ans, atol=1e-5)
69
-
70
-
71
- def test_control_vgate():
72
- c = tc.Circuit(2)
73
- c.x(1)
74
- c.crx(1, 0, theta=0.3)
75
- np.testing.assert_allclose(
76
- c.expectation([tc.gates._z_matrix, 0]), 0.95533645, atol=1e-5
77
- )
78
-
79
-
80
- def test_adjoint_gate_circuit():
81
- c = tc.Circuit(1)
82
- c.X(0)
83
- c.SD(0)
84
- np.testing.assert_allclose(c.state(), np.array([0.0, -1.0j]))
85
-
86
-
87
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
88
- def test_jittable_measure(backend):
89
- @partial(tc.backend.jit, static_argnums=(2, 3))
90
- def f(param, key, n=6, nlayers=3):
91
- if key is not None:
92
- tc.backend.set_random_state(key)
93
- c = tc.Circuit(n)
94
- for i in range(n):
95
- c.H(i)
96
- for j in range(nlayers):
97
- for i in range(n - 1):
98
- c.exp1(i, i + 1, theta=param[2 * j, i], hamiltonian=tc.gates._zz_matrix)
99
- for i in range(n):
100
- c.rx(i, theta=param[2 * j + 1, i])
101
- return c.measure_jit(0, 1, 2, with_prob=True)
102
-
103
- if tc.backend.name == "tensorflow":
104
- import tensorflow as tf
105
-
106
- print(f(tc.backend.ones([6, 6]), None))
107
- print(f(tc.backend.ones([6, 6]), None))
108
- print(f(tc.backend.ones([6, 6]), tf.random.Generator.from_seed(23)))
109
- print(f(tc.backend.ones([6, 6]), tf.random.Generator.from_seed(24)))
110
- elif tc.backend.name == "jax":
111
- import jax
112
-
113
- print(f(tc.backend.ones([6, 6]), jax.random.PRNGKey(23)))
114
- print(f(tc.backend.ones([6, 6]), jax.random.PRNGKey(24)))
115
-
116
- # As seen here, though I have tried the best, the random API is still not that consistent under jit
117
-
118
-
119
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
120
- def test_jittable_depolarizing(backend):
121
- @tc.backend.jit
122
- def f1(key):
123
- n = 5
124
- if key is not None:
125
- tc.backend.set_random_state(key)
126
- c = tc.Circuit(n)
127
- for i in range(n):
128
- c.H(i)
129
- for i in range(n):
130
- c.cnot(i, (i + 1) % n)
131
- for i in range(n):
132
- c.unitary_kraus(
133
- [
134
- tc.gates._x_matrix,
135
- tc.gates._y_matrix,
136
- tc.gates._z_matrix,
137
- tc.gates._i_matrix,
138
- ],
139
- i,
140
- prob=[0.2, 0.2, 0.2, 0.4],
141
- )
142
- for i in range(n):
143
- c.cz(i, (i + 1) % n)
144
- return c.wavefunction()
145
-
146
- @tc.backend.jit
147
- def f2(key):
148
- n = 5
149
- if key is not None:
150
- tc.backend.set_random_state(key)
151
- c = tc.Circuit(n)
152
- for i in range(n):
153
- c.H(i)
154
- for i in range(n):
155
- c.cnot(i, (i + 1) % n)
156
- for i in range(n):
157
- c.unitary_kraus(
158
- tc.channels.depolarizingchannel(0.2, 0.2, 0.2),
159
- i,
160
- )
161
- for i in range(n):
162
- c.X(i)
163
- return c.wavefunction()
164
-
165
- @tc.backend.jit
166
- def f3(key):
167
- n = 5
168
- if key is not None:
169
- tc.backend.set_random_state(key)
170
- c = tc.Circuit(n)
171
- for i in range(n):
172
- c.H(i)
173
- for i in range(n):
174
- c.cnot(i, (i + 1) % n)
175
- for i in range(n):
176
- c.depolarizing(i, px=0.2, py=0.2, pz=0.2)
177
- for i in range(n):
178
- c.X(i)
179
- return c.wavefunction()
180
-
181
- @tc.backend.jit
182
- def f4(key):
183
- n = 5
184
- if key is not None:
185
- tc.backend.set_random_state(key)
186
- c = tc.Circuit(n)
187
- for i in range(n):
188
- c.H(i)
189
- for i in range(n):
190
- c.cnot(i, (i + 1) % n)
191
- for i in range(n):
192
- c.depolarizing2(i, px=0.2, py=0.2, pz=0.2)
193
- for i in range(n):
194
- c.X(i)
195
- return c.wavefunction()
196
-
197
- @tc.backend.jit
198
- def f5(key):
199
- n = 5
200
- if key is not None:
201
- tc.backend.set_random_state(key)
202
- c = tc.Circuit(n)
203
- for i in range(n):
204
- c.H(i)
205
- for i in range(n):
206
- c.cnot(i, (i + 1) % n)
207
- for i in range(n):
208
- c.unitary_kraus2(
209
- tc.channels.depolarizingchannel(0.2, 0.2, 0.2),
210
- i,
211
- )
212
- for i in range(n):
213
- c.X(i)
214
- return c.wavefunction()
215
-
216
- for f in [f1, f2, f3, f4, f5]:
217
- if tc.backend.name == "tensorflow":
218
- import tensorflow as tf
219
-
220
- np.testing.assert_allclose(tc.backend.norm(f(None)), 1.0, atol=1e-4)
221
- np.testing.assert_allclose(
222
- tc.backend.norm(f(tf.random.Generator.from_seed(23))), 1.0, atol=1e-4
223
- )
224
- np.testing.assert_allclose(
225
- tc.backend.norm(f(tf.random.Generator.from_seed(24))), 1.0, atol=1e-4
226
- )
227
-
228
- elif tc.backend.name == "jax":
229
- import jax
230
-
231
- np.testing.assert_allclose(
232
- tc.backend.norm(f(jax.random.PRNGKey(23))), 1.0, atol=1e-4
233
- )
234
- np.testing.assert_allclose(
235
- tc.backend.norm(f(jax.random.PRNGKey(24))), 1.0, atol=1e-4
236
- )
237
-
238
-
239
- @pytest.mark.parametrize("backend", [lf("jaxb")]) # too slow for np
240
- def test_large_scale_sample(backend):
241
- L = 30
242
- c = tc.Circuit(L)
243
- c.h(0)
244
- c.cnot([i for i in range(L - 1)], [i + 1 for i in range(L - 1)])
245
- results = c.sample(
246
- allow_state=False, batch=1024, format="count_dict_bin", jittable=False
247
- )
248
- assert (
249
- results["0" * L] / results["1" * L] < 1.2
250
- and results["0" * L] / results["1" * L] > 0.8
251
- )
252
-
253
-
254
- @pytest.mark.parametrize("backend", [lf("npb"), lf("cpb")])
255
- def test_expectation(backend):
256
- c = tc.Circuit(2)
257
- c.H(0)
258
- np.testing.assert_allclose(
259
- tc.backend.numpy(c.expectation((tc.gates.z(), [0]))), 0, atol=1e-7
260
- )
261
-
262
-
263
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb"), lf("cpb")])
264
- def test_exp1(backend):
265
- @partial(tc.backend.jit, jit_compile=True)
266
- def sf():
267
- c = tc.Circuit(2)
268
- xx = np.array(
269
- [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]], dtype=np.complex64
270
- )
271
- c.exp1(0, 1, unitary=xx, theta=tc.num_to_tensor(0.2))
272
- s = c.state()
273
- return s
274
-
275
- @tc.backend.jit
276
- def s1f():
277
- c = tc.Circuit(2)
278
- xx = np.array(
279
- [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]], dtype=np.complex64
280
- )
281
- c.exp(0, 1, unitary=xx, theta=tc.num_to_tensor(0.2))
282
- s1 = c.state()
283
- return s1
284
-
285
- s = tc.backend.numpy(sf())
286
- s1 = tc.backend.numpy(s1f())
287
- np.testing.assert_allclose(s, s1, atol=1e-4)
288
-
289
-
290
- def test_complex128(highp, tfb):
291
- c = tc.Circuit(2)
292
- c.H(1)
293
- c.rx(0, theta=tc.gates.num_to_tensor(1j))
294
- c.wavefunction()
295
- np.testing.assert_allclose(c.expectation((tc.gates.z(), [1])), 0)
296
-
297
-
298
- # def test_qcode():
299
- # qcode = """
300
- # 4
301
- # x 0
302
- # cnot 0 1
303
- # r 2 theta 1.0 alpha 1.57
304
- # """
305
- # c = tc.Circuit.from_qcode(qcode)
306
- # assert c.measure(1)[0] == "1"
307
- # assert c.to_qcode() == qcode[1:]
308
-
309
-
310
- def universal_ad():
311
- @tc.backend.jit
312
- def forward(theta):
313
- c = tc.Circuit(2)
314
- c.R(0, theta=theta, alpha=0.5, phi=0.8)
315
- return tc.backend.real(c.expectation((tc.gates.z(), [0])))
316
-
317
- gg = tc.backend.grad(forward)
318
- vg = tc.backend.value_and_grad(forward)
319
- gg = tc.backend.jit(gg)
320
- vg = tc.backend.jit(vg)
321
- theta = tc.gates.num_to_tensor(1.0)
322
- grad1 = gg(theta)
323
- v2, grad2 = vg(theta)
324
- assert grad1 == grad2
325
- return v2, grad2
326
-
327
-
328
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
329
- def test_ad(backend):
330
- # this amazingly shows how to code once and run in very different AD-ML engines
331
- print(universal_ad())
332
-
333
-
334
- def test_single_qubit():
335
- c = tc.Circuit(1)
336
- c.H(0)
337
- w = c.state()[0]
338
- np.testing.assert_allclose(w, np.array([1, 1]) / np.sqrt(2), atol=1e-4)
339
-
340
-
341
- @pytest.mark.parametrize("backend", [lf("npb"), lf("cpb")])
342
- def test_expectation_between_two_states(backend):
343
- zp = np.array([1.0, 0.0])
344
- zd = np.array([0.0, 1.0])
345
- assert tc.expectation((tc.gates.y(), [0]), ket=zp, bra=zd) == 1j
346
-
347
- c = tc.Circuit(3)
348
- c.H(0)
349
- c.ry(1, theta=tc.num_to_tensor(0.8))
350
- c.cnot(1, 2)
351
-
352
- state = c.wavefunction()
353
- x1z2 = [(tc.gates.x(), [0]), (tc.gates.z(), [1])]
354
- e1 = c.expectation(*x1z2)
355
- e2 = tc.expectation(*x1z2, ket=state, bra=state, normalization=True)
356
- np.testing.assert_allclose(tc.backend.numpy(e2), tc.backend.numpy(e1))
357
-
358
- c = tc.Circuit(3)
359
- c.H(0)
360
- c.ry(1, theta=tc.num_to_tensor(0.8 + 0.7j))
361
- c.cnot(1, 2)
362
-
363
- state = c.wavefunction()
364
- x1z2 = [(tc.gates.x(), [0]), (tc.gates.z(), [1])]
365
- e1 = c.expectation(*x1z2) / tc.backend.norm(state) ** 2
366
- e2 = tc.expectation(*x1z2, ket=state, normalization=True)
367
- np.testing.assert_allclose(tc.backend.numpy(e2), tc.backend.numpy(e1))
368
-
369
- c = tc.Circuit(2)
370
- c.X(1)
371
- s1 = c.state()
372
- c2 = tc.Circuit(2)
373
- c2.X(0)
374
- s2 = c2.state()
375
- c3 = tc.Circuit(2)
376
- c3.H(1)
377
- s3 = c3.state()
378
- x1x2 = [(tc.gates.x(), [0]), (tc.gates.x(), [1])]
379
- e = tc.expectation(*x1x2, ket=s1, bra=s2)
380
- np.testing.assert_allclose(tc.backend.numpy(e), 1.0)
381
- e2 = tc.expectation(*x1x2, ket=s3, bra=s2)
382
- np.testing.assert_allclose(tc.backend.numpy(e2), 1.0 / np.sqrt(2))
383
-
384
-
385
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb"), lf("cpb")])
386
- def test_any_inputs_state(backend):
387
- c = tc.Circuit(2, inputs=tc.array_to_tensor(np.array([0.0, 0.0, 0.0, 1.0])))
388
- c.X(0)
389
- z0 = c.expectation((tc.gates.z(), [0]))
390
- assert z0 == 1.0
391
- c = tc.Circuit(2, inputs=tc.array_to_tensor(np.array([0.0, 0.0, 1.0, 0.0])))
392
- c.X(0)
393
- z0 = c.expectation((tc.gates.z(), [0]))
394
- assert z0 == 1.0
395
- c = tc.Circuit(2, inputs=tc.array_to_tensor(np.array([1.0, 0.0, 0.0, 0.0])))
396
- c.X(0)
397
- z0 = c.expectation((tc.gates.z(), [0]))
398
- assert z0 == -1.0
399
- c = tc.Circuit(
400
- 2,
401
- inputs=tc.array_to_tensor(np.array([1 / np.sqrt(2), 0.0, 1 / np.sqrt(2), 0.0])),
402
- )
403
- c.X(0)
404
- z0 = c.expectation((tc.gates.z(), [0]))
405
- np.testing.assert_allclose(tc.backend.numpy(z0), 0.0, rtol=1e-4, atol=1e-4)
406
-
407
-
408
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("cpb")])
409
- def test_postselection(backend):
410
- c = tc.Circuit(3)
411
- c.H(1)
412
- c.H(2)
413
- c.mid_measurement(1, 1)
414
- c.mid_measurement(2, 1)
415
- s = c.wavefunction()
416
- np.testing.assert_allclose(tc.backend.numpy(s[3]).real, 0.5)
417
-
418
-
419
- @pytest.mark.parametrize("backend", [lf("npb"), lf("cpb")])
420
- def test_unitary(backend):
421
- c = tc.Circuit(2, inputs=np.eye(4))
422
- c.X(0)
423
- c.Y(1)
424
- answer = tc.backend.numpy(np.kron(tc.gates.x().tensor, tc.gates.y().tensor))
425
- np.testing.assert_allclose(
426
- tc.backend.numpy(c.wavefunction().reshape([4, 4])), answer, atol=1e-4
427
- )
428
-
429
-
430
- @pytest.mark.parametrize("backend", [lf("npb"), lf("cpb")])
431
- def test_expectation_ps(backend):
432
- c = tc.Circuit(2)
433
- c.X(0)
434
- r = c.expectation_ps(z=[0, 1])
435
- np.testing.assert_allclose(tc.backend.numpy(r), -1, atol=1e-5)
436
-
437
- c = tc.Circuit(2)
438
- c.H(0)
439
- r = c.expectation_ps(z=[1], x=[0])
440
- np.testing.assert_allclose(tc.backend.numpy(r), 1, atol=1e-5)
441
- r1 = c.expectation_ps(ps=[1, 3])
442
- np.testing.assert_allclose(tc.backend.numpy(r1), 1, atol=1e-5)
443
- r1 = c.expectation_ps(z=[1, 2], ps=[1, 3])
444
- np.testing.assert_allclose(tc.backend.numpy(r1), 1, atol=1e-5)
445
-
446
-
447
- def test_probability():
448
- for c_cls in [tc.Circuit, tc.DMCircuit]:
449
- c = c_cls(2)
450
- c.h(0)
451
- c.h(1)
452
- np.testing.assert_allclose(
453
- c.probability(), np.array([1, 1, 1, 1]) / 4, atol=1e-5
454
- )
455
-
456
-
457
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
458
- def test_dqas_type_circuit(backend):
459
- eye = tc.gates.i().tensor
460
- x = tc.gates.x().tensor
461
- y = tc.gates.y().tensor
462
- z = tc.gates.z().tensor
463
-
464
- def f(params, structures):
465
- paramsc = tc.backend.cast(params, dtype="complex64")
466
- structuresc = tc.backend.softmax(structures, axis=-1)
467
- structuresc = tc.backend.cast(structuresc, dtype="complex64")
468
- c = tc.Circuit(5)
469
- for i in range(5):
470
- c.H(i)
471
- for j in range(2):
472
- for i in range(4):
473
- c.cz(i, i + 1)
474
- for i in range(5):
475
- c.any(
476
- i,
477
- unitary=structuresc[i, j, 0]
478
- * (
479
- tc.backend.cos(paramsc[i, j, 0]) * eye
480
- + tc.backend.sin(paramsc[i, j, 0]) * x
481
- )
482
- + structuresc[i, j, 1]
483
- * (
484
- tc.backend.cos(paramsc[i, j, 1]) * eye
485
- + tc.backend.sin(paramsc[i, j, 1]) * y
486
- )
487
- + structuresc[i, j, 2]
488
- * (
489
- tc.backend.cos(paramsc[i, j, 2]) * eye
490
- + tc.backend.sin(paramsc[i, j, 2]) * z
491
- ),
492
- )
493
- return tc.backend.real(c.expectation([tc.gates.z(), (2,)]))
494
-
495
- structures = tc.array_to_tensor(
496
- np.random.normal(size=[16, 5, 2, 3]), dtype="float32"
497
- )
498
- params = tc.array_to_tensor(np.random.normal(size=[5, 2, 3]), dtype="float32")
499
-
500
- vf = tc.backend.vmap(f, vectorized_argnums=(1,))
501
-
502
- np.testing.assert_allclose(vf(params, structures).shape, [16])
503
-
504
- vvag = tc.backend.vvag(f, argnums=0, vectorized_argnums=1)
505
-
506
- vvag = tc.backend.jit(vvag)
507
-
508
- value, grad = vvag(params, structures)
509
-
510
- np.testing.assert_allclose(value.shape, [16])
511
- np.testing.assert_allclose(grad.shape, [5, 2, 3])
512
-
513
-
514
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
515
- def test_mixed_measurement_circuit(backend):
516
- n = 4
517
-
518
- def f(params, structures):
519
- structuresc = tc.backend.cast(structures, dtype="complex64")
520
- c = tc.Circuit(n)
521
- for i in range(n):
522
- c.H(i)
523
- for j in range(2):
524
- for i in range(n):
525
- c.cnot(i, (i + 1) % n)
526
- for i in range(n):
527
- c.rz(i, theta=params[j, i])
528
- obs = []
529
- for i in range(n):
530
- obs.append(
531
- [
532
- tc.gates.Gate(
533
- sum(
534
- [
535
- structuresc[i, k] * g.tensor
536
- for k, g in enumerate(tc.gates.pauli_gates)
537
- ]
538
- )
539
- ),
540
- (i,),
541
- ]
542
- )
543
- loss = c.expectation(*obs, reuse=False)
544
- return tc.backend.real(loss)
545
-
546
- # measure X0 to X3
547
-
548
- structures = tc.backend.cast(tc.backend.eye(n), "int32")
549
- structures = tc.backend.onehot(structures, num=4)
550
-
551
- f_vvag = tc.backend.jit(tc.backend.vvag(f, vectorized_argnums=1, argnums=0))
552
- v, g = f_vvag(tc.backend.ones([2, n], dtype="float32"), structures)
553
- np.testing.assert_allclose(
554
- v,
555
- np.array(
556
- [
557
- 0.157729,
558
- 0.157729,
559
- 0.157728,
560
- 0.085221,
561
- ]
562
- ),
563
- atol=1e-5,
564
- )
565
- np.testing.assert_allclose(
566
- g[0],
567
- np.array([-0.378372, -0.624019, -0.491295, -0.378372]),
568
- atol=1e-5,
569
- )
570
-
571
-
572
- def test_circuit_add_demo():
573
- # to be refactored for better API
574
- c = tc.Circuit(2)
575
- c.x(0)
576
- c2 = tc.Circuit(2, mps_inputs=c.quvector())
577
- c2.X(0)
578
- answer = np.array([1.0, 0, 0, 0])
579
- np.testing.assert_allclose(c2.wavefunction(), answer, atol=1e-4)
580
- c3 = tc.Circuit(2)
581
- c3.X(0)
582
- c3.replace_mps_inputs(c.quvector())
583
- np.testing.assert_allclose(c3.wavefunction(), answer, atol=1e-4)
584
-
585
-
586
- def test_circuit_replace_inputs():
587
- n = 3
588
- c = tc.Circuit(n, inputs=np.zeros([2**n]))
589
- for i in range(n):
590
- c.H(i)
591
- evenstate = np.ones([2**n])
592
- evenstate /= np.linalg.norm(evenstate)
593
- c.replace_inputs(evenstate)
594
- for i in range(n):
595
- np.testing.assert_allclose(c.expectation_ps(z=[i]), 1.0, atol=1e-5)
596
-
597
-
598
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
599
- def test_circuit_matrix(backend):
600
- c = tc.Circuit(2)
601
- c.x(1)
602
- c.cnot(0, 1)
603
- np.testing.assert_allclose(c.matrix()[3], np.array([0.0, 0.0, 0.0, 1.0]), atol=1e-5)
604
- np.testing.assert_allclose(c.state(), np.array([0, 1.0, 0, 0]), atol=1e-5)
605
-
606
-
607
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
608
- def test_circuit_split(backend):
609
- n = 4
610
-
611
- def f(param, max_singular_values=None, max_truncation_err=None, fixed_choice=None):
612
- if (max_singular_values is None) and (max_truncation_err is None):
613
- split = None
614
- else:
615
- split = {
616
- "max_singular_values": max_singular_values,
617
- "max_truncation_err": max_truncation_err,
618
- "fixed_choice": fixed_choice,
619
- }
620
- c = tc.Circuit(
621
- n,
622
- split=split,
623
- )
624
- for i in range(n):
625
- c.H(i)
626
- for j in range(2):
627
- for i in range(n - 1):
628
- c.exp1(i, i + 1, theta=param[2 * j, i], hermitian=tc.gates._zz_matrix)
629
- for i in range(n):
630
- c.rx(i, theta=param[2 * j + 1, i])
631
- loss = c.expectation(
632
- (
633
- tc.gates.z(),
634
- [1],
635
- ),
636
- (
637
- tc.gates.z(),
638
- [2],
639
- ),
640
- )
641
- return tc.backend.real(loss)
642
-
643
- s1 = f(tc.backend.ones([4, n]))
644
- s2 = f(tc.backend.ones([4, n]), max_truncation_err=1e-5)
645
- s3 = f(tc.backend.ones([4, n]), max_singular_values=2, fixed_choice=1)
646
-
647
- np.testing.assert_allclose(s1, s2, atol=1e-5)
648
- np.testing.assert_allclose(s1, s3, atol=1e-5)
649
-
650
- f_jit = tc.backend.jit(f, static_argnums=(1, 2, 3))
651
-
652
- s1 = f_jit(tc.backend.ones([4, n]))
653
- # s2 = f_jit(tc.backend.ones([4, n]), max_truncation_err=1e-5) # doesn't work now
654
- # this cannot be done anyway, since variable size tensor network will fail opt einsum
655
- s3 = f_jit(tc.backend.ones([4, n]), max_singular_values=2, fixed_choice=1)
656
-
657
- # np.testing.assert_allclose(s1, s2, atol=1e-5)
658
- np.testing.assert_allclose(s1, s3, atol=1e-5)
659
-
660
- f_vg = tc.backend.jit(
661
- tc.backend.value_and_grad(f, argnums=0), static_argnums=(1, 2, 3)
662
- )
663
-
664
- s1, g1 = f_vg(tc.backend.ones([4, n]))
665
- s3, g3 = f_vg(tc.backend.ones([4, n]), max_singular_values=2, fixed_choice=1)
666
-
667
- np.testing.assert_allclose(s1, s3, atol=1e-5)
668
- # DONE(@refraction-ray): nan on jax backend?
669
- # i see, complex value SVD is not supported on jax for now :)
670
- # I shall further customize complex SVD, finally it has applications
671
-
672
- # tf 2.6.2 also doesn't support complex valued SVD AD, weird...
673
- # if tc.backend.name == "tensorflow":
674
- np.testing.assert_allclose(g1, g3, atol=1e-5)
675
-
676
-
677
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
678
- def test_gate_split(backend):
679
- n = 4
680
-
681
- def f(param, max_singular_values=None, max_truncation_err=None, fixed_choice=None):
682
- if (max_singular_values is None) and (max_truncation_err is None):
683
- split = None
684
- else:
685
- split = {
686
- "max_singular_values": max_singular_values,
687
- "max_truncation_err": max_truncation_err,
688
- "fixed_choice": fixed_choice,
689
- }
690
- c = tc.Circuit(
691
- n,
692
- )
693
- for i in range(n):
694
- c.H(i)
695
- for j in range(2):
696
- for i in range(n - 1):
697
- c.exp1(
698
- i,
699
- i + 1,
700
- theta=param[2 * j, i],
701
- unitary=tc.gates._zz_matrix,
702
- split=split,
703
- )
704
- for i in range(n):
705
- c.rx(i, theta=param[2 * j + 1, i])
706
- loss = c.expectation(
707
- (
708
- tc.gates.x(),
709
- [1],
710
- ),
711
- )
712
- return tc.backend.real(loss)
713
-
714
- s1 = f(tc.backend.ones([4, n]))
715
- s2 = f(tc.backend.ones([4, n]), max_truncation_err=1e-5)
716
- s3 = f(tc.backend.ones([4, n]), max_singular_values=2, fixed_choice=1)
717
-
718
- np.testing.assert_allclose(s1, s2, atol=1e-5)
719
- np.testing.assert_allclose(s1, s3, atol=1e-5)
720
-
721
-
722
- def test_toqir():
723
- split = {
724
- "max_singular_values": 2,
725
- "fixed_choice": 1,
726
- }
727
- c = tc.Circuit(3)
728
- c.H(0)
729
- c.rx(1, theta=tc.array_to_tensor(0.7))
730
- c.exp1(
731
- 0, 1, unitary=tc.gates._zz_matrix, theta=tc.array_to_tensor(-0.2), split=split
732
- )
733
- z1 = c.expectation((tc.gates.z(), [1]))
734
- qirs = c.to_qir()
735
- c = tc.Circuit.from_qir(qirs, circuit_params={"nqubits": 3})
736
- assert len(c._nodes) == 7
737
- z2 = c.expectation((tc.gates.z(), [1]))
738
- np.testing.assert_allclose(z1, z2, atol=1e-5)
739
- c.append_from_qir(qirs)
740
- z3 = c.expectation((tc.gates.z(), [1]))
741
- assert len(c._nodes) == 11
742
- np.testing.assert_allclose(z3, 0.202728, atol=1e-5)
743
-
744
-
745
- def test_vis_tex():
746
- c = tc.Circuit(3)
747
- for i in range(3):
748
- c.H(i)
749
- for i in range(3):
750
- c.any(i, (i + 1) % 3, unitary=tc.backend.ones([4, 4]), name="hihi")
751
- c.any(2, unitary=tc.backend.ones([2, 2]), name="invisible")
752
- c.cz(1, 2)
753
- c.any(1, 0, 2, unitary=tc.backend.ones([8, 8]), name="ccha")
754
- c.z(2)
755
- c.cnot(0, 1)
756
- c.cz(2, 1)
757
-
758
- print(c.vis_tex(init=["0", "1", ""], measure=["x", "y", "z"]))
759
-
760
-
761
- def test_debug_contract():
762
- n = 10
763
- d = 4
764
- try:
765
- import cotengra # pylint: disable=unused-import
766
-
767
- except ImportError:
768
- pytest.skip("cotengra is not installed")
769
-
770
- @tc.set_function_contractor(
771
- "custom_stateful",
772
- optimizer=oem.RandomGreedy,
773
- max_time=10,
774
- max_repeats=64,
775
- minimize="size",
776
- debug_level=2,
777
- contraction_info=True,
778
- )
779
- def small_tn():
780
- param = tc.backend.ones([2 * d, n])
781
- c = tc.Circuit(n)
782
- c = tc.templates.blocks.example_block(c, param, nlayers=d)
783
- return c.state()
784
-
785
- np.testing.assert_allclose(small_tn(), np.zeros([2**n]), atol=1e-5)
786
-
787
-
788
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
789
- def test_teleportation(backend):
790
- key = tc.backend.get_random_state(42)
791
-
792
- @tc.backend.jit
793
- def f(key):
794
- tc.backend.set_random_state(key)
795
- c = tc.Circuit(2)
796
- c.H(0)
797
- r = c.cond_measurement(0)
798
- c.conditional_gate(r, [tc.gates.i(), tc.gates.x()], 1)
799
- return r, c.expectation([tc.gates.z(), [1]])
800
-
801
- keys = []
802
- for _ in range(6):
803
- key, subkey = tc.backend.random_split(key)
804
- keys.append(subkey)
805
- rs = [f(k) for k in keys]
806
- for r, e in rs:
807
- if tc.backend.numpy(r) > 0.5:
808
- np.testing.assert_allclose(e, -1, atol=1e-5)
809
- else:
810
- np.testing.assert_allclose(e, 1, atol=1e-5)
811
-
812
-
813
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
814
- def test_append_circuit(backend):
815
- c = tc.Circuit(2)
816
- c.cnot(0, 1)
817
- c1 = tc.Circuit(2)
818
- c1.x(0)
819
- c.append(c1)
820
- np.testing.assert_allclose(c.expectation_ps(z=[1]), 1.0)
821
-
822
- c = tc.Circuit(2)
823
- c.cnot(0, 1)
824
- c1 = tc.Circuit(2)
825
- c1.x(0)
826
- c.prepend(c1)
827
- np.testing.assert_allclose(c.expectation_ps(z=[1]), -1.0)
828
-
829
- c = tc.Circuit(2)
830
- c1 = tc.Circuit(1)
831
- c1.x(0)
832
- c.append(c1, [1])
833
- np.testing.assert_allclose(c.state(), [0, 1, 0, 0])
834
-
835
-
836
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
837
- def test_apply_mpo_gate(backend):
838
- gate = tc.gates.multicontrol_gate(tc.gates._x_matrix, ctrl=[1, 0])
839
- ans = np.array(
840
- [
841
- [1.0, 0, 0, 0, 0, 0, 0, 0],
842
- [0, 1.0, 0, 0, 0, 0, 0, 0],
843
- [0, 0, 1.0, 0, 0, 0, 0, 0],
844
- [0, 0, 0, 1.0, 0, 0, 0, 0],
845
- [0, 0, 0, 0, 0, 1.0, 0, 0],
846
- [0, 0, 0, 0, 1.0, 0, 0, 0],
847
- [0, 0, 0, 0, 0, 0, 1.0, 0],
848
- [0, 0, 0, 0, 0, 0, 0, 1.0],
849
- ]
850
- )
851
- c = tc.Circuit(3)
852
- c.X(0)
853
- c.mpo(0, 1, 2, mpo=gate.copy())
854
- np.testing.assert_allclose(c.expectation([tc.gates.z(), [2]]), -1, atol=1e-5)
855
- c = tc.Circuit(3)
856
- c.X(1)
857
- c.mpo(0, 1, 2, mpo=gate.copy())
858
- np.testing.assert_allclose(c.expectation([tc.gates.z(), [2]]), 1, atol=1e-5)
859
- np.testing.assert_allclose(gate.eval_matrix(), ans, atol=1e-5)
860
-
861
-
862
- def test_apply_multicontrol_gate():
863
- c = tc.Circuit(3)
864
- c.X(2)
865
- c.multicontrol(0, 2, 1, ctrl=[0, 1], unitary=tc.gates._x_matrix)
866
- np.testing.assert_allclose(c.expectation([tc.gates.z(), [1]]), -1, atol=1e-5)
867
- c = tc.Circuit(3)
868
- c.X(0)
869
- c.multicontrol(0, 2, 1, ctrl=[0, 1], unitary=tc.gates._x_matrix)
870
- np.testing.assert_allclose(c.expectation([tc.gates.z(), [1]]), 1, atol=1e-5)
871
- c = tc.Circuit(4)
872
- c.X(0)
873
- c.X(2)
874
- c.multicontrol(0, 1, 2, 3, ctrl=[1, 0], unitary=tc.gates.swap())
875
- np.testing.assert_allclose(c.expectation([tc.gates.z(), [3]]), -1, atol=1e-5)
876
-
877
-
878
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
879
- def test_circuit_quoperator(backend):
880
- c = tc.Circuit(3)
881
- c.x(0)
882
- c.cnot(0, 1)
883
- c.cz(1, 2)
884
- c.y(2)
885
- c.exp1(0, 2, theta=1.0, unitary=tc.gates._xx_matrix)
886
- c.H(1)
887
- c.multicontrol(0, 2, 1, ctrl=[1, 0], unitary=tc.gates.z())
888
- qo = c.quoperator()
889
- np.testing.assert_allclose(qo.eval_matrix(), c.matrix(), atol=1e-5)
890
-
891
-
892
- def test_perm_matrix():
893
- from tensorcircuit.translation import perm_matrix
894
-
895
- p2 = perm_matrix(2)
896
- np.testing.assert_allclose(
897
- p2, np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])
898
- )
899
- p3 = perm_matrix(3)
900
- v = np.arange(8)
901
- vt = np.array([0, 4, 2, 6, 1, 5, 3, 7])
902
- np.testing.assert_allclose(p3 @ v, vt)
903
-
904
-
905
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
906
- def test_qir2cirq(backend):
907
- try:
908
- import cirq
909
- except ImportError:
910
- pytest.skip("cirq is not installed")
911
- n = 6
912
- c = tc.Circuit(n)
913
- for i in range(n):
914
- c.H(i)
915
- zz = np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
916
- for i in range(n):
917
- c.exp(
918
- i,
919
- (i + 1) % n,
920
- theta=tc.array_to_tensor(np.random.uniform()),
921
- unitary=tc.array_to_tensor(zz),
922
- name="zz",
923
- )
924
- c.exp1(
925
- 1, 3, theta=tc.array_to_tensor(0.0j), unitary=tc.array_to_tensor(zz), name="zz"
926
- )
927
- c.fredkin(0, 1, 2)
928
- c.cswap(1, 2, 3)
929
- c.ccnot(1, 2, 3)
930
- c.cx(2, 3)
931
- c.swap(0, 1)
932
- c.iswap(0, 1)
933
- c.iswap(1, 3, theta=-1.9)
934
- c.toffoli(0, 1, 2)
935
- c.s(1)
936
- c.t(1)
937
- c.sd(1)
938
- c.td(1)
939
- c.x(2)
940
- c.y(2)
941
- c.z(2)
942
- c.wroot(3)
943
- c.cnot(0, 1)
944
- c.cy(0, 1)
945
- c.cz(0, 1)
946
- c.oy(4, 3)
947
- c.oz(4, 3)
948
- c.ox(4, 3)
949
- c.oy(4, 3)
950
- c.oz(4, 3)
951
- c.ox(3, 4)
952
- c.phase(2, theta=0.3)
953
- c.cphase(1, 0, theta=-1.2)
954
- c.rxx(0, 2, theta=0.9)
955
- c.ryy(1, 4, theta=-2.0)
956
- c.rzz(1, 3, theta=0.5)
957
- c.u(2, theta=0, lbd=4.6, phi=-0.3)
958
- c.cu(4, 1, theta=1.2)
959
- c.rx(1, theta=tc.array_to_tensor(np.random.uniform()))
960
- c.r(5, theta=tc.array_to_tensor(np.random.uniform()))
961
- c.cr(
962
- 1,
963
- 2,
964
- theta=tc.array_to_tensor(np.random.uniform()),
965
- alpha=tc.array_to_tensor(np.random.uniform()),
966
- phi=tc.array_to_tensor(np.random.uniform()),
967
- )
968
- c.ry(1, theta=tc.array_to_tensor(np.random.uniform()))
969
- c.rz(1, theta=tc.array_to_tensor(np.random.uniform()))
970
- c.crz(2, 3, theta=tc.array_to_tensor(np.random.uniform()))
971
- c.crx(5, 3, theta=tc.array_to_tensor(np.random.uniform()))
972
- c.cry(1, 3, theta=tc.array_to_tensor(np.random.uniform()))
973
- c.orx(5, 3, theta=tc.array_to_tensor(np.random.uniform()))
974
- c.ory(5, 3, theta=tc.array_to_tensor(np.random.uniform()))
975
- c.orz(5, 3, theta=tc.array_to_tensor(np.random.uniform()))
976
-
977
- c.any(1, 3, unitary=tc.array_to_tensor(np.reshape(zz, [2, 2, 2, 2])))
978
-
979
- gate = tc.gates.multicontrol_gate(
980
- tc.array_to_tensor(tc.gates._x_matrix), ctrl=[1, 0]
981
- )
982
- c.mpo(0, 1, 2, mpo=gate.copy())
983
- c.multicontrol(
984
- 0,
985
- 2,
986
- 4,
987
- 1,
988
- 5,
989
- ctrl=[0, 1, 0],
990
- unitary=tc.array_to_tensor(tc.gates._zz_matrix),
991
- name="zz",
992
- )
993
- tc_unitary = c.matrix()
994
- tc_unitary = np.reshape(tc_unitary, [2**n, 2**n])
995
-
996
- cirq = c.to_cirq()
997
- cirq_unitary = cirq.unitary()
998
- cirq_unitary = np.reshape(cirq_unitary, [2**n, 2**n])
999
-
1000
- np.testing.assert_allclose(tc_unitary, cirq_unitary, atol=1e-5)
1001
-
1002
-
1003
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1004
- def test_qir2qiskit(backend):
1005
- try:
1006
- import qiskit.quantum_info as qi
1007
-
1008
- from tensorcircuit.translation import perm_matrix
1009
- except ImportError:
1010
- pytest.skip("qiskit is not installed")
1011
-
1012
- n = 6
1013
- c = tc.Circuit(n, inputs=tc.array_to_tensor(np.eye(2**n)))
1014
-
1015
- for i in range(n):
1016
- c.H(i)
1017
- zz = np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
1018
- for i in range(n):
1019
- c.exp(
1020
- i,
1021
- (i + 1) % n,
1022
- theta=tc.array_to_tensor(np.random.uniform()),
1023
- unitary=tc.array_to_tensor(zz),
1024
- name="zz",
1025
- )
1026
- c.exp1(
1027
- 1, 3, theta=tc.array_to_tensor(0.0j), unitary=tc.array_to_tensor(zz), name="zz"
1028
- )
1029
- c.fredkin(1, 2, 3)
1030
- c.cswap(1, 2, 3)
1031
- c.ccnot(1, 2, 3)
1032
- c.cx(2, 3)
1033
- c.swap(0, 1)
1034
- c.iswap(0, 1)
1035
- c.iswap(1, 3, theta=-1.9)
1036
- c.toffoli(0, 1, 2)
1037
- c.s(1)
1038
- c.t(1)
1039
- c.sd(1)
1040
- c.td(1)
1041
- c.x(2)
1042
- c.y(2)
1043
- c.z(2)
1044
- c.wroot(3)
1045
- c.cnot(0, 1)
1046
- c.cy(0, 1)
1047
- c.cz(0, 1)
1048
- c.oy(4, 3)
1049
- c.oz(4, 3)
1050
- c.ox(4, 3)
1051
- c.oy(4, 3)
1052
- c.oz(4, 3)
1053
- c.ox(3, 4)
1054
- c.phase(2, theta=0.3)
1055
- c.cphase(1, 0, theta=-1.2)
1056
- c.rxx(0, 2, theta=0.9)
1057
- c.ryy(1, 4, theta=-2.0)
1058
- c.rzz(1, 3, theta=0.5)
1059
- c.u(2, theta=0, lbd=4.6, phi=-0.3)
1060
- c.cu(4, 1, theta=1.2)
1061
- c.rx(1, theta=tc.array_to_tensor(np.random.uniform()))
1062
- c.r(5, theta=tc.array_to_tensor(np.random.uniform()))
1063
- c.cr(
1064
- 1,
1065
- 2,
1066
- theta=tc.array_to_tensor(np.random.uniform()),
1067
- alpha=tc.array_to_tensor(np.random.uniform()),
1068
- phi=tc.array_to_tensor(np.random.uniform()),
1069
- )
1070
- c.ry(1, theta=tc.array_to_tensor(np.random.uniform()))
1071
- c.rz(1, theta=tc.array_to_tensor(np.random.uniform()))
1072
- c.crz(2, 3, theta=tc.array_to_tensor(np.random.uniform()))
1073
- c.crx(5, 3, theta=tc.array_to_tensor(np.random.uniform()))
1074
- c.cry(1, 3, theta=tc.array_to_tensor(np.random.uniform()))
1075
- c.orx(5, 3, theta=tc.array_to_tensor(np.random.uniform()))
1076
- c.ory(5, 3, theta=tc.array_to_tensor(np.random.uniform()))
1077
- c.orz(5, 3, theta=tc.array_to_tensor(np.random.uniform()))
1078
-
1079
- c.any(1, 3, unitary=tc.array_to_tensor(np.reshape(zz, [2, 2, 2, 2])))
1080
- gate = tc.gates.multicontrol_gate(
1081
- tc.array_to_tensor(tc.gates._x_matrix), ctrl=[1, 0]
1082
- )
1083
- c.mpo(0, 1, 2, mpo=gate.copy())
1084
- c.multicontrol(
1085
- 0,
1086
- 2,
1087
- 4,
1088
- 1,
1089
- 5,
1090
- ctrl=[0, 1, 0],
1091
- unitary=tc.array_to_tensor(tc.gates._zz_matrix),
1092
- name="zz",
1093
- )
1094
- tc_unitary = c.wavefunction()
1095
- tc_unitary = np.reshape(tc_unitary, [2**n, 2**n])
1096
-
1097
- qisc = c.to_qiskit()
1098
- qis_unitary = qi.Operator(qisc)
1099
- qis_unitary = np.reshape(qis_unitary, [2**n, 2**n])
1100
-
1101
- p_mat = perm_matrix(n)
1102
- np.testing.assert_allclose(p_mat @ tc_unitary @ p_mat, qis_unitary, atol=1e-5)
1103
-
1104
-
1105
- def test_qiskit2tc():
1106
- try:
1107
- import qiskit.quantum_info as qi
1108
- from qiskit import QuantumCircuit
1109
- from qiskit.circuit.library import HamiltonianGate
1110
- from qiskit.circuit.library.standard_gates import MCXGate, SwapGate, CXGate
1111
-
1112
- from tensorcircuit.translation import perm_matrix
1113
- except ImportError:
1114
- pytest.skip("qiskit is not installed")
1115
- n = 6
1116
- qisc = QuantumCircuit(n)
1117
- for i in range(n):
1118
- qisc.h(i)
1119
- zz = np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
1120
- exp_op = qi.Operator(zz)
1121
- for i in range(n):
1122
- gate = HamiltonianGate(exp_op, time=np.random.uniform())
1123
- qisc.append(gate, [i, (i + 1) % n])
1124
- qisc.fredkin(1, 2, 3)
1125
- qisc.cswap(1, 2, 3)
1126
- qisc.swap(0, 1)
1127
- qisc.iswap(0, 1)
1128
- qisc.toffoli(0, 1, 2)
1129
- # test Instructions
1130
- qisc2 = QuantumCircuit(1)
1131
- qisc2.h(0)
1132
- qisc.compose(qisc2, qubits=[1], inplace=True, wrap=True)
1133
- qisc.barrier(0, 1, 2)
1134
- qisc.s(1)
1135
- qisc.t(1)
1136
- qisc.sdg(2)
1137
- qisc.tdg(2)
1138
- qisc.x(3)
1139
- qisc.y(3)
1140
- qisc.z(3)
1141
- qisc.cu(
1142
- 5.868768495722669, 2.24809352294186, 3.59102783505607, 2.0223650288392, 1, 3
1143
- )
1144
- qisc.cnot(0, 1)
1145
- qisc.cy(0, 1)
1146
- qisc.cz(0, 1, ctrl_state=0)
1147
- qisc.cy(0, 1, ctrl_state=0)
1148
- qisc.cx(0, 1, ctrl_state=0)
1149
- qisc.rxx(0.3, 1, 2)
1150
- qisc.rzz(-0.8, 2, 0)
1151
- qisc.u(0.3, 0.9, -1.2, 2)
1152
- qisc.rx(np.random.uniform(), 1)
1153
- qisc.ry(np.random.uniform(), 2)
1154
- qisc.rz(np.random.uniform(), 3)
1155
- qisc.crz(np.random.uniform(), 2, 3)
1156
- qisc.crz(np.random.uniform(), 2, 3)
1157
- qisc.crz(np.random.uniform(), 2, 3)
1158
- qisc.crz(np.random.uniform(), 2, 3, ctrl_state=0)
1159
- qisc.crz(np.random.uniform(), 2, 3, ctrl_state=0)
1160
- qisc.crz(np.random.uniform(), 2, 3, ctrl_state=0)
1161
- qisc.r(np.random.uniform(), np.random.uniform(), 1)
1162
- qisc.unitary(exp_op, [1, 3])
1163
- mcx_g = MCXGate(3, ctrl_state="010")
1164
- qisc.append(mcx_g, [0, 1, 2, 3])
1165
- qisc.ccx(0, 1, 2, ctrl_state="01")
1166
- CCswap = SwapGate().control(2, ctrl_state="01")
1167
- qisc.append(CCswap, [0, 1, 2, 3])
1168
- CCCX = CXGate().control(2, ctrl_state="01")
1169
- qisc.append(CCCX, [1, 2, 3, 4])
1170
-
1171
- c = tc.Circuit.from_qiskit(qisc, n)
1172
- tc_unitary = c.matrix()
1173
- qis_unitary = qi.Operator(qisc)
1174
- qis_unitary = np.reshape(qis_unitary, [2**n, 2**n])
1175
- p_mat = perm_matrix(n)
1176
- np.testing.assert_allclose(p_mat @ tc_unitary @ p_mat, qis_unitary, atol=1e-5)
1177
- qisc_from_tc = c.to_qiskit(enable_instruction=True)
1178
- qis_unitary2 = qi.Operator(qisc_from_tc)
1179
- qis_unitary2 = np.reshape(qis_unitary2, [2**n, 2**n])
1180
- np.testing.assert_allclose(qis_unitary2, qis_unitary, atol=1e-5)
1181
-
1182
-
1183
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb"), lf("torchb")])
1184
- def test_qiskit2tc_parameterized(backend):
1185
- try:
1186
- from qiskit.circuit import Parameter, ParameterVector, QuantumCircuit
1187
- from qiskit.circuit.library import TwoLocal
1188
- from qiskit.quantum_info import Operator
1189
- from qiskit_nature.second_q.circuit.library import UCCSD
1190
- from qiskit_nature.second_q.mappers import ParityMapper
1191
- except ImportError:
1192
- pytest.skip("qiskit or qiskit-nature is not installed")
1193
- from tensorcircuit.translation import perm_matrix
1194
-
1195
- mapper = ParityMapper()
1196
- ansatz1 = UCCSD(2, [1, 1], mapper)
1197
- ansatz2 = TwoLocal(2, rotation_blocks="ry", entanglement_blocks="cz")
1198
- ansatz3 = QuantumCircuit(1)
1199
- ansatz3_param = Parameter("θ")
1200
- ansatz3.rx(ansatz3_param, 0)
1201
- ansatz4 = QuantumCircuit(1)
1202
- ansatz4_param = ParameterVector("φ", 3)
1203
- ansatz4.rx(2.0 * ansatz4_param[0] + 5.0, 0)
1204
- ansatz4.ry(ansatz4_param[0] * ansatz4_param[1] + ansatz4_param[2], 0)
1205
- ansatz4.rz(
1206
- np.exp(np.sin(ansatz4_param[0]))
1207
- + np.abs(ansatz4_param[1]) / np.arctan(ansatz4_param[2]),
1208
- 0,
1209
- )
1210
- ansatz_list = [ansatz1, ansatz2, ansatz3, ansatz4]
1211
- for ansatz in ansatz_list:
1212
- n = ansatz.num_qubits
1213
- if ansatz in [ansatz1, ansatz2, ansatz4]:
1214
- params = np.random.rand(ansatz.num_parameters)
1215
- else:
1216
- params = {ansatz3_param: 0.618}
1217
- qisc = ansatz.assign_parameters(params)
1218
- qiskit_unitary = Operator(qisc)
1219
- qiskit_unitary = np.reshape(qiskit_unitary, [2**n, 2**n])
1220
-
1221
- # test jit
1222
- @tc.backend.jit
1223
- def get_unitary(params):
1224
- return tc.Circuit.from_qiskit(
1225
- ansatz, inputs=np.eye(2**n), binding_params=params
1226
- ).state()
1227
-
1228
- tc_unitary = get_unitary(params)
1229
- tc_unitary = np.reshape(tc_unitary, [2**n, 2**n])
1230
- p_mat = tc.array_to_tensor(perm_matrix(n))
1231
- np.testing.assert_allclose(
1232
- p_mat @ tc_unitary @ p_mat, qiskit_unitary, atol=1e-5
1233
- )
1234
-
1235
- # test grad
1236
- def cost_fn(params):
1237
- return tc.backend.real(tc.backend.sum(get_unitary(params)))
1238
-
1239
- if ansatz in [ansatz1, ansatz2, ansatz4]:
1240
- grad = tc.backend.grad(cost_fn)(tc.backend.convert_to_tensor(params))
1241
- assert tc.backend.sum(tc.num_to_tensor(np.isnan(grad))) == 0
1242
- else:
1243
- # tf only supports tf tensor as input
1244
- grad = tc.backend.grad(cost_fn)(
1245
- {ansatz3_param: tc.backend.convert_to_tensor(0.618)}
1246
- )
1247
- assert not np.isnan(grad[ansatz3_param])
1248
-
1249
-
1250
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1251
- def test_qiskit_vs_tc_intialization(backend):
1252
- try:
1253
- import qiskit.quantum_info as qi
1254
- from qiskit import QuantumCircuit
1255
- except ImportError:
1256
- pytest.skip("qiskit is not installed")
1257
-
1258
- n = 3
1259
-
1260
- qis_c = QuantumCircuit(n)
1261
- qis_c.h(0)
1262
- qis_c.cnot(0, 1)
1263
- qis_c.y(2)
1264
- state = qi.Statevector(qis_c)
1265
- qis_c = QuantumCircuit(n)
1266
- qis_c.initialize(state)
1267
- qis_c.cnot(1, 2)
1268
- c = tc.Circuit.from_qiskit(qis_c)
1269
- c2 = tc.Circuit(n)
1270
- c2.h(0)
1271
- c2.cnot(0, 1)
1272
- c2.y(2)
1273
- c2.cnot(1, 2)
1274
- np.testing.assert_allclose(c.state(), c2.state(), atol=1e-8)
1275
- np.testing.assert_allclose(
1276
- qi.Statevector(c.to_qiskit(enable_inputs=True)),
1277
- qi.Statevector(qis_c),
1278
- atol=1e-8,
1279
- )
1280
-
1281
-
1282
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1283
- def test_batch_sample(backend):
1284
- c = tc.Circuit(3)
1285
- c.H(0)
1286
- c.cnot(0, 1)
1287
- print(c.sample())
1288
- print(c.sample(batch=8))
1289
- print(c.sample(random_generator=tc.backend.get_random_state(42)))
1290
- print(c.sample(allow_state=True))
1291
- print(c.sample(batch=8, allow_state=True))
1292
- print(
1293
- c.sample(
1294
- batch=8, allow_state=True, random_generator=tc.backend.get_random_state(42)
1295
- )
1296
- )
1297
- print(
1298
- c.sample(
1299
- batch=8,
1300
- allow_state=True,
1301
- status=np.random.uniform(size=[8]),
1302
- format="sample_bin",
1303
- )
1304
- )
1305
-
1306
-
1307
- def test_expectation_y_bug():
1308
- c = tc.Circuit(1, inputs=1 / np.sqrt(2) * np.array([-1, 1.0j]))
1309
- m = c.expectation_ps(y=[0])
1310
- np.testing.assert_allclose(m, -1, atol=1e-5)
1311
-
1312
-
1313
- def test_lightcone_expectation():
1314
- def construct_c(pbc=True):
1315
- n = 4
1316
- ns = n
1317
- if pbc is False:
1318
- ns -= 1
1319
- c = tc.Circuit(n)
1320
- for j in range(2):
1321
- for i in range(n):
1322
- c.rx(i, theta=0.2, name="rx" + str(j) + "-" + str(i))
1323
- for i in range(ns):
1324
- c.cnot(i, (i + 1) % n, name="cnot" + str(j) + "-" + str(i))
1325
- return c
1326
-
1327
- for b in [True, False]:
1328
- c = construct_c(b)
1329
- m1 = c.expectation_ps(z=[0], enable_lightcone=True)
1330
- m2 = c.expectation_ps(z=[0])
1331
- np.testing.assert_allclose(m1, m2, atol=1e-5)
1332
- nodes = c.expectation_before([tc.gates.z(), 0], reuse=False)
1333
- l1 = len(nodes)
1334
- nodes = tc.simplify._full_light_cone_cancel(nodes)
1335
- l2 = len(nodes)
1336
- if b is False:
1337
- assert l1 == 37 and l2 == 25
1338
- else:
1339
- assert l1 == 41 and l2 == 41
1340
-
1341
-
1342
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1343
- def test_circuit_inverse(backend):
1344
- inputs = np.random.uniform(size=[8])
1345
- inputs /= np.linalg.norm(inputs)
1346
- c = tc.Circuit(3, inputs=inputs)
1347
- c.H(1)
1348
- c.rx(0, theta=0.5)
1349
- c.cnot(1, 2)
1350
- c.rzz(0, 2, theta=-0.8)
1351
- c1 = c.inverse()
1352
- c.append(c1)
1353
- np.testing.assert_allclose(c.state(), inputs, atol=1e-5)
1354
-
1355
-
1356
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1357
- def test_circuit_inverse_2(backend):
1358
- inputs = np.random.uniform(size=[8])
1359
- inputs /= np.linalg.norm(inputs)
1360
- c = tc.Circuit(3, inputs=inputs)
1361
- c.iswap(0, 1)
1362
- c.iswap(1, 0, theta=0.6)
1363
- c.rxx(1, 2, theta=-0.2)
1364
- c.cu(0, 1, lbd=2.0, theta=-0.7)
1365
- c.r(2, alpha=0.3)
1366
- c.sd(2)
1367
- c.cx(1, 2)
1368
- c.unitary(0, unitary=tc.gates._x_matrix)
1369
- c1 = c.inverse()
1370
- c.append(c1)
1371
- print(c.draw())
1372
- np.testing.assert_allclose(c.state(), inputs, atol=1e-5)
1373
-
1374
-
1375
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
1376
- def test_jittable_amplitude(backend):
1377
- # @tc.backend.jit
1378
- def amp(s):
1379
- c = tc.Circuit(3)
1380
- c.H(0)
1381
- c.cnot(0, 1)
1382
- c.swap(1, 2)
1383
- return c.amplitude(s)
1384
-
1385
- np.testing.assert_allclose(
1386
- amp(tc.array_to_tensor([0, 1, 1], dtype="float32")), 0, atol=1e-5
1387
- )
1388
- np.testing.assert_allclose(
1389
- amp(tc.array_to_tensor([0, 0, 0], dtype="float32")), 1 / np.sqrt(2), atol=1e-5
1390
- )
1391
-
1392
-
1393
- def test_draw_cond_measure():
1394
- c = tc.Circuit(2)
1395
- c.H(0)
1396
- c.cond_measure(0)
1397
- c.cnot(0, 1)
1398
- print("")
1399
- print(c.draw())
1400
-
1401
-
1402
- def test_minus_index():
1403
- c = tc.Circuit(3)
1404
- c.H(-2)
1405
- c.H(0)
1406
- np.testing.assert_allclose(tc.backend.real(c.expectation_ps(x=[0])), 1, atol=1e-5)
1407
- np.testing.assert_allclose(tc.backend.real(c.expectation_ps(x=[1])), 1, atol=1e-5)
1408
- np.testing.assert_allclose(tc.backend.real(c.expectation_ps(x=[-1])), 0, atol=1e-5)
1409
- np.testing.assert_allclose(tc.backend.real(c.expectation_ps(z=[-2])), 0, atol=1e-5)
1410
-
1411
-
1412
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1413
- def test_sexpps(backend):
1414
- c = tc.Circuit(1, inputs=1 / np.sqrt(2) * np.array([1.0, 1.0j]))
1415
- y = c.sample_expectation_ps(y=[0])
1416
- ye = c.expectation_ps(y=[0])
1417
- np.testing.assert_allclose(y, 1.0, atol=1e-5)
1418
- np.testing.assert_allclose(ye, 1.0, atol=1e-5)
1419
-
1420
- c = tc.Circuit(4)
1421
- c.H(0)
1422
- c.cnot(0, 1)
1423
- c.rx(1, theta=0.3)
1424
- c.rz(2, theta=-1.2)
1425
- c.ccnot(2, 3, 1)
1426
- c.rzz(0, 3, theta=0.5)
1427
- c.ry(3, theta=2.2)
1428
- c.s(1)
1429
- c.td(2)
1430
- y = c.sample_expectation_ps(x=[1], y=[0], z=[2, 3])
1431
- ye = c.expectation_ps(x=[1], y=[0], z=[2, 3])
1432
- np.testing.assert_allclose(ye, y, atol=1e-5)
1433
- y2 = c.sample_expectation_ps(x=[1], y=[0], z=[2, 3], shots=81920)
1434
- assert np.abs(y2 - y) < 0.01
1435
-
1436
-
1437
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1438
- def test_sample_format(backend):
1439
- c = tc.Circuit(2)
1440
- c.H(0)
1441
- c.cnot(0, 1)
1442
- key = tc.backend.get_random_state(42)
1443
- for allow_state in [False, True]:
1444
- print("allow_state: ", allow_state)
1445
- for batch in [None, 1, 3]:
1446
- print(" batch: ", batch)
1447
- for format_ in [
1448
- None,
1449
- "sample_int",
1450
- "sample_bin",
1451
- "count_vector",
1452
- "count_tuple",
1453
- "count_dict_bin",
1454
- "count_dict_int",
1455
- ]:
1456
- print(" format: ", format_)
1457
- print(
1458
- " ",
1459
- c.sample(
1460
- batch=batch,
1461
- allow_state=allow_state,
1462
- format_=format_,
1463
- random_generator=key,
1464
- ),
1465
- )
1466
-
1467
-
1468
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1469
- def test_channel_auto_register(backend, highp):
1470
- c = tc.Circuit(2)
1471
- c.H(0)
1472
- c.reset(0, status=0.8)
1473
- s = c.state()
1474
- np.testing.assert_allclose(s[0], 1.0, atol=1e-9)
1475
-
1476
-
1477
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
1478
- def test_circuit_to_json(backend):
1479
- c = tc.Circuit(3)
1480
- c.h(0)
1481
- c.CNOT(1, 2)
1482
- c.rxx(0, 2, theta=0.3)
1483
- c.crx(0, 1, theta=-0.8)
1484
- c.r(1, theta=tc.backend.ones([]), alpha=0.2)
1485
- c.toffoli(0, 2, 1)
1486
- c.ccnot(0, 1, 2)
1487
- c.multicontrol(1, 2, 0, ctrl=[0, 1], unitary=tc.gates._x_matrix)
1488
- s = c.to_json()
1489
- c2 = tc.Circuit.from_json(s)
1490
- print(c2.draw())
1491
- np.testing.assert_allclose(c.state(), c2.state(), atol=1e-5)
1492
-
1493
-
1494
- def test_gate_count():
1495
- c = tc.Circuit(3)
1496
- c.x(0)
1497
- c.h(0)
1498
- c.rx(1, theta=-0.2)
1499
- c.h(2)
1500
- c.multicontrol(0, 1, 2, ctrl=[0, 1], unitary=tc.gates._x_matrix)
1501
- c.toffoli(0, 2, 1)
1502
- c.ccnot(1, 2, 0)
1503
- c.ccx(1, 2, 0)
1504
- assert c.gate_count() == 8
1505
- assert c.gate_count("h") == 2
1506
- assert c.gate_count(["ccnot"]) == 3
1507
- assert c.gate_count(["rx", "multicontrol"]) == 2
1508
- assert c.gate_count_by_condition(lambda qir: qir["index"] == (0,)) == 2
1509
- assert c.gate_count_by_condition(lambda qir: qir["mpo"]) == 1
1510
- print(c.gate_summary())
1511
- # {'x': 1, 'h': 2, 'rx': 1, 'multicontrol': 1, 'toffoli': 3}
1512
-
1513
-
1514
- def test_to_openqasm(tmp_path):
1515
- c = tc.Circuit(3)
1516
- c.H(0)
1517
- c.rz(2, theta=0.2)
1518
- c.cnot(2, 1)
1519
- c.rzz(0, 1, theta=-1.0)
1520
- c.ccx(1, 2, 0)
1521
- c.u(2, theta=0.5, lbd=1.3)
1522
- c.measure_instruction(1)
1523
- print(c.to_openqasm(formatted=True))
1524
- s = c.to_openqasm()
1525
- c1 = tc.Circuit.from_openqasm(s)
1526
- print(c1.draw())
1527
- np.testing.assert_allclose(c.state(), c1.state())
1528
- c.to_openqasm_file(os.path.join(tmp_path, "test.qasm"))
1529
- c2 = tc.Circuit.from_openqasm_file(os.path.join(tmp_path, "test.qasm"))
1530
- np.testing.assert_allclose(c.state(), c2.state())
1531
-
1532
-
1533
- def test_from_qasm_keep_measure_order():
1534
- qasm_str = """OPENQASM 2.0;
1535
- include "qelib1.inc";
1536
- qreg q[2];
1537
- creg c[2];
1538
- h q[0];
1539
- measure q[1] -> c[1];
1540
- measure q[0] -> c[0];"""
1541
- c = tc.Circuit.from_openqasm(qasm_str)
1542
- c.to_openqasm().split("\n")[-2][-3] == "1"
1543
- c = tc.Circuit.from_openqasm(qasm_str, keep_measure_order=True)
1544
- c.to_openqasm().split("\n")[-2][-3] == "0"
1545
-
1546
-
1547
- def test_initial_mapping():
1548
- c = tc.Circuit(3)
1549
- c.cnot(0, 1)
1550
- c.h(1)
1551
- c.rx(1, theta=0.5)
1552
- c.cz(2, 1)
1553
- c.measure_instruction(2)
1554
-
1555
- c1 = c.initial_mapping({0: 1, 1: 2, 2: 0})
1556
- print(c1.draw())
1557
-
1558
- np.testing.assert_allclose(
1559
- c.expectation_ps(z=[1]), c1.expectation_ps(z=[2]), atol=1e-5
1560
- )
1561
- assert c1._extra_qir[0]["index"][0] == 0
1562
-
1563
- c2 = c1.initial_mapping({1: 0, 2: 1, 0: 2})
1564
- np.testing.assert_allclose(
1565
- c.expectation_ps(z=[1]), c2.expectation_ps(z=[1]), atol=1e-5
1566
- )
1567
-
1568
- c3 = c.initial_mapping({0: 2, 1: 7, 2: 0}, n=9)
1569
- np.testing.assert_allclose(
1570
- c.expectation_ps(z=[1]), c3.expectation_ps(z=[7]), atol=1e-5
1571
- )
1572
- print(c3.draw())
1573
-
1574
-
1575
- def test_get_positional_logical_mapping():
1576
- c = tc.Circuit(3)
1577
- c.cx(0, 1)
1578
- c.cz(1, 2)
1579
- c.h(1)
1580
- assert c.get_positional_logical_mapping() == {0: 0, 1: 1, 2: 2}
1581
- c = tc.Circuit(3)
1582
- c.cx(0, 1)
1583
- c.h(1)
1584
- c.measure_instruction(2)
1585
- c.measure_instruction(0)
1586
- assert c.get_positional_logical_mapping() == {0: 2, 1: 0}
1587
-
1588
-
1589
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
1590
- def test_inverse_jit(backend):
1591
- K = tc.backend
1592
-
1593
- def simple_ansatz(param):
1594
- c = tc.Circuit(3)
1595
- for i in range(3):
1596
- c.cx(i, (i + 1) % 3)
1597
- c.rzz(i, (i + 1) % 3, theta=param[i])
1598
- c1 = c.inverse()
1599
- c2 = tc.Circuit(3)
1600
- c2.x(1)
1601
- c1.append(c2)
1602
- return tc.backend.real(c1.expectation_ps(z=[1]))
1603
-
1604
- v_ansatz = K.jit(K.vvag(simple_ansatz))
1605
- vs, gs = v_ansatz(K.ones([2, 3], dtype="float32"))
1606
- assert K.shape_tuple(gs) == (2, 3)
1607
- np.testing.assert_allclose(K.numpy(vs), -1.0 * K.ones([2]), atol=1e-5)
1608
-
1609
-
1610
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb"), lf("npb")])
1611
- def test_fancy_circuit_indexing(backend):
1612
- c = tc.Circuit(4)
1613
- c.cx([0, 1], [-1, -2])
1614
- c.h(range(c._nqubits))
1615
- c.rz([0], theta=0.2)
1616
- c.rx([1, 2], theta=[0.3, 0.5])
1617
- c.rzz([2, 3], [0, 1], theta=tc.backend.ones([2]))
1618
- c.rxx([2, 0, 1], [0, 1, 2], theta=tc.backend.ones([1]))
1619
- assert c.gate_count("h") == 4
1620
- assert c.gate_count("rzz") == 2
1621
- assert c.gate_count("rxx") == 3
1622
-
1623
-
1624
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb"), lf("npb")])
1625
- def test_general_kraus(backend):
1626
- c = tc.Circuit(2)
1627
- c.h([0, 1])
1628
- p = 0.5
1629
- status = [0.3, 0.8]
1630
- rs = []
1631
- for i in range(2):
1632
- rs.append(
1633
- c.general_kraus(
1634
- [
1635
- np.sqrt(p) * np.array([[1.0, 0], [0, 0]]),
1636
- np.sqrt(p) * np.array([[0, 0], [0, 1.0]]),
1637
- np.sqrt(1 - p) * np.eye(2),
1638
- ],
1639
- i,
1640
- status=status[i],
1641
- )
1642
- )
1643
- np.testing.assert_allclose(rs[0], 1)
1644
- np.testing.assert_allclose(rs[1], 2)
1645
- np.testing.assert_allclose(c.expectation_ps(z=[0]), -1, atol=1e-5)
1646
- np.testing.assert_allclose(c.expectation_ps(z=[1]), 0, atol=1e-5)
1647
-
1648
-
1649
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb"), lf("npb")])
1650
- def test_general_kraus_with_prob(backend):
1651
- c = tc.Circuit(2)
1652
- c.h([0, 1])
1653
- p = 0.5
1654
- status = [0.3, 0.8]
1655
- rs = []
1656
- for i in range(2):
1657
- rs.append(
1658
- c.general_kraus(
1659
- [
1660
- np.sqrt(p) * np.array([[1.0, 0], [0, 0]]),
1661
- np.sqrt(p) * np.array([[0, 0], [0, 1.0]]),
1662
- np.sqrt(1 - p) * np.eye(2),
1663
- ],
1664
- i,
1665
- status=status[i],
1666
- with_prob=True,
1667
- )
1668
- )
1669
- np.testing.assert_allclose(rs[0][0], 1)
1670
- np.testing.assert_allclose(rs[1][0], 2)
1671
- np.testing.assert_allclose(c.expectation_ps(z=[0]), -1, atol=1e-5)
1672
- np.testing.assert_allclose(c.expectation_ps(z=[1]), 0, atol=1e-5)
1673
- np.testing.assert_allclose(rs[0][1], [0.25, 0.25, 0.5], atol=1e-5)
1674
- np.testing.assert_allclose(rs[1][1], [0.25, 0.25, 0.5], atol=1e-5)
1675
- np.testing.assert_allclose(tc.backend.norm(c.state()), 1, atol=1e-5)
1676
-
1677
-
1678
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb"), lf("npb")])
1679
- def test_circuit_copy(backend):
1680
- c = tc.Circuit(2)
1681
- c.h(0)
1682
- c1 = c.copy()
1683
- c.rz(0, theta=0.1)
1684
- assert c1.gate_count() == 1
1685
-
1686
-
1687
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb"), lf("npb")])
1688
- def test_projected_subsystem(backend):
1689
- c = tc.Circuit(3)
1690
- c.h(0)
1691
- c.cnot(0, 1)
1692
- c.rx(1, theta=0.9)
1693
- c.cy(1, 2)
1694
- s = c.projected_subsystem(tc.backend.convert_to_tensor(np.array([1, 1, 1.0])), (0,))
1695
- np.testing.assert_allclose(s, np.array([0.43496, 0.900447j]), atol=1e-5)
1696
- s = c.projected_subsystem(
1697
- tc.backend.convert_to_tensor(np.array([0, 0, 0.0])), (0, 2)
1698
- )
1699
- np.testing.assert_allclose(s[0], 0.900447, atol=1e-5)
1700
-
1701
- c = tc.DMCircuit(3)
1702
- c.h(0)
1703
- c.cnot(0, 1)
1704
- c.rx(1, theta=0.9)
1705
- c.cy(1, 2)
1706
- s = c.projected_subsystem(tc.backend.convert_to_tensor(np.array([1, 1, 1.0])), (0,))
1707
- assert tc.backend.shape_tuple(s) == (2, 2)
1708
- np.testing.assert_allclose(s[1, 1], 0.8108051, atol=1e-5)
1709
- s = c.projected_subsystem(
1710
- tc.backend.convert_to_tensor(np.array([1, 1, 1.0])), (1, 2)
1711
- )
1712
- assert tc.backend.shape_tuple(s) == (4, 4)
1713
- np.testing.assert_allclose(s[3, 3], 0.8108051, atol=1e-5)