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_quantum.py DELETED
@@ -1,549 +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 pytest
9
- import tensornetwork as tn
10
- from pytest_lazyfixture import lazy_fixture as lf
11
-
12
- thisfile = os.path.abspath(__file__)
13
- modulepath = os.path.dirname(os.path.dirname(thisfile))
14
-
15
- sys.path.insert(0, modulepath)
16
- import tensorcircuit as tc
17
- from tensorcircuit import quantum as qu
18
-
19
- # Note that the first version of this file is adpated from source code of tensornetwork: (Apache2)
20
- # https://github.com/google/TensorNetwork/blob/master/tensornetwork/quantum/quantum_test.py
21
-
22
- # tc.set_contractor("greedy")
23
- atol = 1e-5 # relax jax 32 precision
24
- decimal = 5
25
-
26
-
27
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
28
- def test_constructor(backend):
29
- psi_tensor = np.random.rand(2, 2)
30
- psi_node = tn.Node(psi_tensor)
31
-
32
- op = qu.quantum_constructor([psi_node[0]], [psi_node[1]])
33
- assert not op.is_scalar()
34
- assert not op.is_vector()
35
- assert not op.is_adjoint_vector()
36
- assert len(op.out_edges) == 1
37
- assert len(op.in_edges) == 1
38
- assert op.out_edges[0] is psi_node[0]
39
- assert op.in_edges[0] is psi_node[1]
40
-
41
- op = qu.quantum_constructor([psi_node[0], psi_node[1]], [])
42
- assert not op.is_scalar()
43
- assert op.is_vector()
44
- assert not op.is_adjoint_vector()
45
- assert len(op.out_edges) == 2
46
- assert len(op.in_edges) == 0
47
- assert op.out_edges[0] is psi_node[0]
48
- assert op.out_edges[1] is psi_node[1]
49
-
50
- op = qu.quantum_constructor([], [psi_node[0], psi_node[1]])
51
- assert not op.is_scalar()
52
- assert not op.is_vector()
53
- assert op.is_adjoint_vector()
54
- assert len(op.out_edges) == 0
55
- assert len(op.in_edges) == 2
56
- assert op.in_edges[0] is psi_node[0]
57
- assert op.in_edges[1] is psi_node[1]
58
-
59
- with pytest.raises(ValueError):
60
- op = qu.quantum_constructor([], [], [psi_node])
61
-
62
- _ = psi_node[0] ^ psi_node[1]
63
- op = qu.quantum_constructor([], [], [psi_node])
64
- assert op.is_scalar()
65
- assert not op.is_vector()
66
- assert not op.is_adjoint_vector()
67
- assert len(op.out_edges) == 0
68
- assert len(op.in_edges) == 0
69
-
70
-
71
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
72
- def test_checks(backend):
73
- node1 = tn.Node(np.random.rand(2, 2))
74
- node2 = tn.Node(np.random.rand(2, 2))
75
- _ = node1[1] ^ node2[0]
76
-
77
- # extra dangling edges must be explicitly ignored
78
- with pytest.raises(ValueError):
79
- _ = qu.QuVector([node1[0]])
80
-
81
- # correctly ignore the extra edge
82
- _ = qu.QuVector([node1[0]], ignore_edges=[node2[1]])
83
-
84
- # in/out edges must be dangling
85
- with pytest.raises(ValueError):
86
- _ = qu.QuVector([node1[0], node1[1], node2[1]])
87
-
88
-
89
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
90
- def test_from_tensor(backend):
91
- psi_tensor = np.random.rand(2, 2)
92
-
93
- op = qu.QuOperator.from_tensor(psi_tensor, [0], [1])
94
- assert not op.is_scalar()
95
- assert not op.is_vector()
96
- assert not op.is_adjoint_vector()
97
- np.testing.assert_almost_equal(op.eval(), psi_tensor, decimal=decimal)
98
-
99
- op = qu.QuVector.from_tensor(psi_tensor, [0, 1])
100
- assert not op.is_scalar()
101
- assert op.is_vector()
102
- assert not op.is_adjoint_vector()
103
- np.testing.assert_almost_equal(op.eval(), psi_tensor, decimal=decimal)
104
-
105
- op = qu.QuAdjointVector.from_tensor(psi_tensor, [0, 1])
106
- assert not op.is_scalar()
107
- assert not op.is_vector()
108
- assert op.is_adjoint_vector()
109
- np.testing.assert_almost_equal(op.eval(), psi_tensor, decimal=decimal)
110
-
111
- op = qu.QuScalar.from_tensor(1.0)
112
- assert op.is_scalar()
113
- assert not op.is_vector()
114
- assert not op.is_adjoint_vector()
115
- assert op.eval() == 1.0
116
-
117
-
118
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
119
- def test_identity(backend):
120
- E = qu.identity((2, 3, 4), dtype=np.float64)
121
- for n in E.nodes:
122
- assert isinstance(n, tn.CopyNode)
123
- twentyfour = E.trace()
124
- for n in twentyfour.nodes:
125
- assert isinstance(n, tn.CopyNode)
126
- assert twentyfour.eval() == 24
127
-
128
- tensor = np.random.rand(2, 2)
129
- psi = qu.QuVector.from_tensor(tensor)
130
- E = qu.identity((2, 2), dtype=np.float64)
131
- np.testing.assert_allclose((E @ psi).eval(), psi.eval(), atol=atol)
132
-
133
- np.testing.assert_allclose(
134
- (psi.adjoint() @ E @ psi).eval(), psi.norm().eval(), atol=atol
135
- )
136
-
137
- op = qu.QuOperator.from_tensor(tensor, [0], [1])
138
- op_I = op.tensor_product(E)
139
- op_times_4 = op_I.partial_trace([1, 2])
140
- np.testing.assert_allclose(op_times_4.eval(), 4 * op.eval(), atol=atol)
141
-
142
-
143
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
144
- def test_tensor_product(backend):
145
- psi = qu.QuVector.from_tensor(np.random.rand(2, 2))
146
- psi_psi = psi.tensor_product(psi)
147
- assert len(psi_psi.subsystem_edges) == 4
148
- np.testing.assert_almost_equal(
149
- psi_psi.norm().eval(), psi.norm().eval() ** 2, decimal=decimal
150
- )
151
-
152
-
153
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
154
- def test_matmul(backend):
155
- mat = np.random.rand(2, 2)
156
- op = qu.QuOperator.from_tensor(mat, [0], [1])
157
- res = (op @ op).eval()
158
- np.testing.assert_allclose(res, mat @ mat, atol=atol)
159
-
160
-
161
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
162
- def test_mul(backend):
163
- mat = np.eye(2)
164
- scal = np.float64(0.5)
165
- op = qu.QuOperator.from_tensor(mat, [0], [1])
166
- scal_op = qu.QuScalar.from_tensor(scal)
167
-
168
- res = (op * scal_op).eval()
169
- np.testing.assert_allclose(res, mat * 0.5, atol=atol)
170
-
171
- res = (scal_op * op).eval()
172
- np.testing.assert_allclose(res, mat * 0.5, atol=atol)
173
-
174
- res = (scal_op * scal_op).eval()
175
- np.testing.assert_almost_equal(res, 0.25, decimal=decimal)
176
-
177
- res = (op * np.float64(0.5)).eval()
178
- np.testing.assert_allclose(res, mat * 0.5, atol=atol)
179
-
180
- res = (np.float64(0.5) * op).eval()
181
- np.testing.assert_allclose(res, mat * 0.5, atol=atol)
182
-
183
- with pytest.raises(ValueError):
184
- _ = op * op
185
-
186
- with pytest.raises(ValueError):
187
- _ = op * mat
188
-
189
-
190
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
191
- def test_expectations(backend):
192
- psi_tensor = np.random.rand(2, 2, 2) + 1.0j * np.random.rand(2, 2, 2)
193
- op_tensor = np.random.rand(2, 2) + 1.0j * np.random.rand(2, 2)
194
-
195
- psi = qu.QuVector.from_tensor(psi_tensor)
196
- op = qu.QuOperator.from_tensor(op_tensor, [0], [1])
197
-
198
- op_3 = op.tensor_product(qu.identity((2, 2), dtype=psi_tensor.dtype))
199
- res1 = (psi.adjoint() @ op_3 @ psi).eval()
200
-
201
- rho_1 = psi.reduced_density([1, 2]) # trace out sites 2 and 3
202
- res2 = (op @ rho_1).trace().eval()
203
-
204
- np.testing.assert_almost_equal(res1, res2, decimal=decimal)
205
-
206
-
207
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
208
- def test_projector(backend):
209
- psi_tensor = np.random.rand(2, 2)
210
- psi_tensor /= np.linalg.norm(psi_tensor)
211
- psi = qu.QuVector.from_tensor(psi_tensor)
212
- P = psi.projector()
213
- np.testing.assert_allclose((P @ psi).eval(), psi_tensor, atol=atol)
214
-
215
- np.testing.assert_allclose((P @ P).eval(), P.eval(), atol=atol)
216
-
217
-
218
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
219
- def test_nonsquare_quop(backend):
220
- op = qu.QuOperator.from_tensor(np.ones([2, 2, 2, 2, 2]), [0, 1, 2], [3, 4])
221
- op2 = qu.QuOperator.from_tensor(np.ones([2, 2, 2, 2, 2]), [0, 1], [2, 3, 4])
222
- np.testing.assert_allclose(
223
- (op @ op2).eval(), 4 * np.ones([2, 2, 2, 2, 2, 2]), atol=atol
224
- )
225
-
226
-
227
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
228
- def test_expectation_local_tensor(backend):
229
- op = qu.QuOperator.from_local_tensor(
230
- np.array([[1.0, 0.0], [0.0, 1.0]]), space=[2, 2, 2, 2], loc=[1]
231
- )
232
- state = np.zeros([2, 2, 2, 2])
233
- state[0, 0, 0, 0] = 1.0
234
- psi = qu.QuVector.from_tensor(state)
235
- psi_d = psi.adjoint()
236
- np.testing.assert_allclose((psi_d @ op @ psi).eval(), 1.0, atol=atol)
237
-
238
-
239
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
240
- def test_rm_state_vs_mps(backend):
241
- @partial(tc.backend.jit, jit_compile=False, static_argnums=(1, 2))
242
- def entanglement1(param, n, nlayers):
243
- c = tc.Circuit(n)
244
- c = tc.templates.blocks.example_block(c, param, nlayers)
245
- w = c.wavefunction()
246
- rm = qu.reduced_density_matrix(w, int(n / 2))
247
- return qu.entropy(rm)
248
-
249
- @partial(tc.backend.jit, jit_compile=False, static_argnums=(1, 2))
250
- def entanglement2(param, n, nlayers):
251
- c = tc.Circuit(n)
252
- c = tc.templates.blocks.example_block(c, param, nlayers)
253
- w = c.get_quvector()
254
- rm = w.reduced_density([i for i in range(int(n / 2))])
255
- return qu.entropy(rm)
256
-
257
- param = tc.backend.ones([6, 6])
258
- rm1 = entanglement1(param, 6, 3)
259
- rm2 = entanglement2(param, 6, 3)
260
- np.testing.assert_allclose(rm1, rm2, atol=atol)
261
-
262
-
263
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
264
- def test_trace_product(backend):
265
- o = np.ones([2, 2])
266
- h = np.eye(2)
267
- np.testing.assert_allclose(qu.trace_product(o, h), 2, atol=atol)
268
- oq = qu.QuOperator.from_tensor(o)
269
- hq = qu.QuOperator.from_tensor(h)
270
- np.testing.assert_allclose(qu.trace_product(oq, hq), 2, atol=atol)
271
- np.testing.assert_allclose(qu.trace_product(oq, h), 2, atol=atol)
272
- np.testing.assert_allclose(qu.trace_product(o, hq), 2, atol=atol)
273
-
274
-
275
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
276
- def test_free_energy(backend):
277
- rho = np.array([[1.0, 0], [0, 0]])
278
- h = np.array([[-1.0, 0], [0, 1]])
279
- np.testing.assert_allclose(qu.free_energy(rho, h, 0.5), -1, atol=atol)
280
- np.testing.assert_allclose(qu.renyi_free_energy(rho, h, 0.5), -1, atol=atol)
281
- hq = qu.QuOperator.from_tensor(h)
282
- np.testing.assert_allclose(qu.free_energy(rho, hq, 0.5), -1, atol=atol)
283
-
284
-
285
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
286
- def test_measurement_counts(backend):
287
- state = np.ones([4])
288
- ct, cs = qu.measurement_counts(state, format="count_tuple")
289
- np.testing.assert_allclose(ct.shape[0], 4, atol=atol)
290
- np.testing.assert_allclose(tc.backend.sum(cs), 8192, atol=atol)
291
- state = np.ones([2, 2])
292
- ct, cs = qu.measurement_counts(state, format="count_tuple")
293
- np.testing.assert_allclose(ct.shape[0], 2, atol=atol)
294
- np.testing.assert_allclose(tc.backend.sum(cs), 8192, atol=atol)
295
- state = np.array([1.0, 1.0, 0, 0])
296
- print(qu.measurement_counts(state))
297
-
298
-
299
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
300
- def test_extract_from_measure(backend):
301
- np.testing.assert_allclose(
302
- qu.spin_by_basis(2, 1), np.array([1, -1, 1, -1]), atol=atol
303
- )
304
- state = tc.array_to_tensor(np.array([0.6, 0.4, 0, 0]))
305
- np.testing.assert_allclose(
306
- qu.correlation_from_counts([0, 1], state), 0.2, atol=atol
307
- )
308
- np.testing.assert_allclose(qu.correlation_from_counts([1], state), 0.2, atol=atol)
309
-
310
- samples_int = tc.array_to_tensor(np.array([0, 0, 3, 3, 3]), dtype="int32")
311
- r = qu.correlation_from_samples([0, 1], samples_int, n=2)
312
- np.testing.assert_allclose(r, 1, atol=1e-5)
313
-
314
-
315
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
316
- def test_heisenberg_ham(backend):
317
- g = tc.templates.graphs.Line1D(6)
318
- h = tc.quantum.heisenberg_hamiltonian(g, sparse=False)
319
- e, _ = tc.backend.eigh(h)
320
- np.testing.assert_allclose(e[0], -11.2111, atol=1e-4)
321
-
322
-
323
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
324
- def test_reduced_density_from_density(backend):
325
- n = 6
326
- w = np.random.normal(size=[2**n]) + 1.0j * np.random.normal(size=[2**n])
327
- w /= np.linalg.norm(w)
328
- rho = np.reshape(w, [-1, 1]) @ np.reshape(np.conj(w), [1, -1])
329
- dm1 = tc.quantum.reduced_density_matrix(w, cut=[0, 2])
330
- dm2 = tc.quantum.reduced_density_matrix(rho, cut=[0, 2])
331
- np.testing.assert_allclose(dm1, dm2, atol=1e-5)
332
-
333
- # with p
334
- n = 5
335
- w = np.random.normal(size=[2**n]) + 1.0j * np.random.normal(size=[2**n])
336
- w /= np.linalg.norm(w)
337
- p = np.random.normal(size=[2**3])
338
- p = tc.backend.softmax(p)
339
- p = tc.backend.cast(p, "complex128")
340
- rho = np.reshape(w, [-1, 1]) @ np.reshape(np.conj(w), [1, -1])
341
- dm1 = tc.quantum.reduced_density_matrix(w, cut=[1, 2, 3], p=p)
342
- dm2 = tc.quantum.reduced_density_matrix(rho, cut=[1, 2, 3], p=p)
343
- np.testing.assert_allclose(dm1, dm2, atol=1e-5)
344
-
345
-
346
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
347
- def test_mutual_information(backend):
348
- n = 5
349
- w = np.random.normal(size=[2**n]) + 1.0j * np.random.normal(size=[2**n])
350
- w /= np.linalg.norm(w)
351
- rho = np.reshape(w, [-1, 1]) @ np.reshape(np.conj(w), [1, -1])
352
- dm1 = tc.quantum.mutual_information(w, cut=[1, 2, 3])
353
- dm2 = tc.quantum.mutual_information(rho, cut=[1, 2, 3])
354
- np.testing.assert_allclose(dm1, dm2, atol=1e-5)
355
-
356
-
357
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
358
- def test_expectation_quantum(backend):
359
- c = tc.Circuit(3)
360
- c.ry(0, theta=0.4)
361
- c.cnot(0, 1)
362
- exp1 = c.expectation([tc.gates.z(), [0]], [tc.gates.z(), [2]], reuse=False)
363
- qv = c.quvector()
364
- exp2 = tc.expectation([tc.gates.z(), [0]], [tc.gates.z(), [2]], ket=qv)
365
- np.testing.assert_allclose(exp1, exp2, atol=1e-5)
366
-
367
-
368
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
369
- def test_ee(backend):
370
- c = tc.Circuit(3)
371
- c.h(0)
372
- c.cx(0, 1)
373
- c.cx(1, 2)
374
- s = c.state()
375
- np.testing.assert_allclose(
376
- tc.quantum.entanglement_entropy(s, [0, 1]), np.log(2.0), atol=1e-5
377
- )
378
-
379
-
380
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
381
- def test_negativity(backend, highp):
382
- c = tc.DMCircuit(2)
383
- c.h(0)
384
- c.cnot(0, 1)
385
- c.depolarizing(0, px=0.1, py=0.1, pz=0.1)
386
- dm = c.state()
387
- np.testing.assert_allclose(
388
- tc.quantum.log_negativity(dm, [0], base="2"), 0.485427, atol=1e-5
389
- )
390
- np.testing.assert_allclose(
391
- tc.quantum.partial_transpose(tc.quantum.partial_transpose(dm, [0]), [0]),
392
- dm,
393
- atol=1e-6,
394
- )
395
- np.testing.assert_allclose(
396
- tc.quantum.entanglement_negativity(dm, [1]), 0.2, atol=1e-5
397
- )
398
-
399
-
400
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
401
- def test_tn2qop(backend):
402
- nwires = 6
403
- dtype = np.complex64
404
- # only obc is supported, even if you supply nwires Jx terms
405
- Jx = np.array([1.0 for _ in range(nwires - 1)]) # strength of xx interaction (OBC)
406
- Bz = np.array([-1.0 for _ in range(nwires)]) # strength of transverse field
407
- tn_mpo = tn.matrixproductstates.mpo.FiniteTFI(Jx, Bz, dtype=dtype)
408
- qu_mpo = tc.quantum.tn2qop(tn_mpo)
409
- h1 = qu_mpo.eval_matrix()
410
- g = tc.templates.graphs.Line1D(nwires, pbc=False)
411
- h2 = tc.quantum.heisenberg_hamiltonian(
412
- g, hzz=0, hxx=1, hyy=0, hz=1, hx=0, hy=0, sparse=False, numpy=True
413
- )
414
- np.testing.assert_allclose(h1, h2, atol=1e-5)
415
-
416
-
417
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
418
- def test_qb2qop(backend):
419
- try:
420
- import quimb
421
- except ImportError:
422
- pytest.skip("quimb is not installed")
423
- nwires = 6
424
- qb_mpo = quimb.tensor.tensor_builder.MPO_ham_ising(nwires, 4, 2, cyclic=True)
425
- qu_mpo = tc.quantum.quimb2qop(qb_mpo)
426
- h1 = qu_mpo.eval_matrix()
427
- g = tc.templates.graphs.Line1D(nwires, pbc=True)
428
- h2 = tc.quantum.heisenberg_hamiltonian(
429
- g, hzz=1, hxx=0, hyy=0, hz=0, hx=-1, hy=0, sparse=False, numpy=True
430
- )
431
- np.testing.assert_allclose(h1, h2, atol=1e-5)
432
-
433
- # in out edge order test
434
- builder = quimb.tensor.tensor_builder.SpinHam1D()
435
- # new version quimb breaking API change: SpinHam1D -> SpinHam
436
- builder += 1, "Y"
437
- builder += 1, "X"
438
- H = builder.build_mpo(3)
439
- h = tc.quantum.quimb2qop(H)
440
- m1 = h.eval_matrix()
441
- g = tc.templates.graphs.Line1D(3, pbc=False)
442
- m2 = tc.quantum.heisenberg_hamiltonian(
443
- g, hzz=0, hxx=0, hyy=0, hz=0, hy=0.5, hx=0.5, sparse=False, numpy=True
444
- )
445
- np.testing.assert_allclose(m1, m2, atol=1e-5)
446
-
447
- # test mps case
448
-
449
- s1 = quimb.tensor.tensor_builder.MPS_rand_state(3, 4)
450
- s2 = tc.quantum.quimb2qop(s1)
451
- m1 = s1.to_dense()
452
- m2 = s2.eval_matrix()
453
- np.testing.assert_allclose(m1, m2, atol=1e-5)
454
-
455
-
456
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
457
- def test_counts_2(backend):
458
- z0 = tc.backend.convert_to_tensor(np.array([0.1, 0, -0.3, 0]))
459
- x, y = tc.quantum.count_d2s(z0)
460
- print(x, y)
461
- np.testing.assert_allclose(x, np.array([0, 2]))
462
- np.testing.assert_allclose(y, np.array([0.1, -0.3]))
463
- z = tc.quantum.count_s2d((x, y), 2)
464
- np.testing.assert_allclose(z, z0)
465
-
466
-
467
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
468
- def test_measurement_results(backend):
469
- n = 4
470
- w = tc.backend.ones([2**n])
471
- r = tc.quantum.measurement_results(w, counts=9, format="sample_bin", jittable=True)
472
- assert tc.backend.shape_tuple(r) == (9, n)
473
- print(r)
474
- r = tc.quantum.measurement_results(w, counts=9, format="sample_int", jittable=True)
475
- assert tc.backend.shape_tuple(r) == (9,)
476
- print(r)
477
- for c in (9, -9):
478
- r = tc.quantum.measurement_results(
479
- w, counts=c, format="count_vector", jittable=True
480
- )
481
- assert tc.backend.shape_tuple(r) == (2**n,)
482
- print(r)
483
- r = tc.quantum.measurement_results(w, counts=c, format="count_tuple")
484
- print(r)
485
- r = tc.quantum.measurement_results(
486
- w, counts=c, format="count_dict_bin", jittable=True
487
- )
488
- print(r)
489
- r = tc.quantum.measurement_results(
490
- w, counts=c, format="count_dict_int", jittable=True
491
- )
492
- print(r)
493
-
494
-
495
- def test_ps2xyz():
496
- xyz = {"x": [1], "z": [2]}
497
- assert tc.quantum.xyz2ps(xyz) == [0, 1, 3]
498
- assert tc.quantum.xyz2ps(xyz, 6) == [0, 1, 3, 0, 0, 0]
499
- xyz.update({"y": []})
500
- assert tc.quantum.ps2xyz([0, 1, 3]) == xyz
501
- assert tc.quantum.ps2xyz([0, 1, 3, 0]) == xyz
502
-
503
-
504
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
505
- def test_reduced_wavefunction(backend):
506
- c = tc.Circuit(3)
507
- c.h(0)
508
- c.cnot(0, 1)
509
- r = c.cond_measure(0)
510
- s = c.state()
511
- s1 = tc.quantum.reduced_wavefunction(s, [0, 2], [r, 0])
512
- if tc.backend.cast(r, tc.rdtypestr) < 0.5:
513
- np.testing.assert_allclose(s1, np.array([1, 0]), atol=1e-5)
514
- else:
515
- np.testing.assert_allclose(s1, np.array([0, 1]), atol=1e-5)
516
-
517
- c = tc.Circuit(3)
518
- c.h(0)
519
- c.cnot(0, 1)
520
- s = c.state()
521
- s1 = tc.quantum.reduced_wavefunction(s, [2], [0])
522
-
523
- c1 = tc.Circuit(2)
524
- c1.h(0)
525
- c1.cnot(0, 1)
526
- np.testing.assert_allclose(s1, c1.state(), atol=1e-5)
527
-
528
-
529
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
530
- def test_u1_mask(backend):
531
- g = tc.templates.graphs.Line1D(8)
532
- sumz = tc.quantum.heisenberg_hamiltonian(g, hzz=0, hxx=0, hyy=0, hz=1)
533
- for i in range(9):
534
- s = tc.quantum.u1_mask(8, i)
535
- s /= tc.backend.norm(s)
536
- c = tc.Circuit(8, inputs=s)
537
- zexp = tc.templates.measurements.operator_expectation(c, sumz)
538
- np.testing.assert_allclose(zexp, 8 - 2 * i, atol=1e-6)
539
-
540
-
541
- @pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
542
- def test_u1_project(backend):
543
- c = tc.Circuit(8)
544
- c.x([0, 2, 4])
545
- c.exp1(0, 1, unitary=tc.gates._swap_matrix, theta=0.6)
546
- s = c.state()
547
- s1 = tc.quantum.u1_project(s, 8, 3)
548
- assert s1.shape[-1] == 56
549
- np.testing.assert_allclose(tc.quantum.u1_enlarge(s1, 8, 3), s)
@@ -1,42 +0,0 @@
1
- import sys
2
- import os
3
-
4
- import numpy as np
5
- import tensorflow as tf
6
-
7
- thisfile = os.path.abspath(__file__)
8
- modulepath = os.path.dirname(os.path.dirname(thisfile))
9
-
10
- sys.path.insert(0, modulepath)
11
- from tensorcircuit.applications.vags import double_state, reduced_density_matrix
12
-
13
-
14
- def test_double_state():
15
- s = double_state(tf.constant([[1.0, 0], [0, -1.0]]), beta=2.0)
16
- np.testing.assert_allclose(np.linalg.norm(s.numpy()), 1.0)
17
- np.testing.assert_allclose(
18
- s.numpy(),
19
- np.array(
20
- [
21
- np.exp(-1) / np.sqrt(np.exp(2) + np.exp(-2)),
22
- 0,
23
- 0,
24
- np.exp(1) / np.sqrt(np.exp(2) + np.exp(-2)),
25
- ]
26
- ),
27
- atol=1e-5,
28
- )
29
- s2 = double_state(tf.constant([[0.0, 1.0], [1.0, 0.0]]), beta=1.0)
30
- np.testing.assert_allclose(np.linalg.norm(s2.numpy()), 1.0)
31
- em = np.exp(-0.5)
32
- ep = np.exp(0.5)
33
- ans = np.array([em + ep, em - ep, em - ep, em + ep])
34
- ans /= np.linalg.norm(ans)
35
- np.testing.assert_allclose(s2.numpy(), ans, atol=1e-5)
36
-
37
-
38
- def test_reduced_dm():
39
- rho = reduced_density_matrix(
40
- tf.random.normal(shape=[128]), freedom=7, cut=[1, 3, 5]
41
- )
42
- np.testing.assert_allclose(np.trace(rho.numpy()), 1, atol=1e-5)