tensorcircuit-nightly 1.2.0.dev20250326__py3-none-any.whl → 1.4.0.dev20251128__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 (77) 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 +100 -4
  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 +157 -98
  14. tensorcircuit/circuit.py +115 -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 +105 -23
  20. tensorcircuit/densitymatrix.py +16 -11
  21. tensorcircuit/experimental.py +733 -153
  22. tensorcircuit/fgs.py +254 -73
  23. tensorcircuit/gates.py +66 -22
  24. tensorcircuit/interfaces/jax.py +5 -3
  25. tensorcircuit/interfaces/tensortrans.py +6 -2
  26. tensorcircuit/interfaces/torch.py +14 -4
  27. tensorcircuit/keras.py +3 -3
  28. tensorcircuit/mpscircuit.py +154 -65
  29. tensorcircuit/quantum.py +698 -134
  30. tensorcircuit/quditcircuit.py +733 -0
  31. tensorcircuit/quditgates.py +618 -0
  32. tensorcircuit/results/counts.py +131 -18
  33. tensorcircuit/results/readout_mitigation.py +4 -1
  34. tensorcircuit/shadows.py +1 -1
  35. tensorcircuit/simplify.py +3 -1
  36. tensorcircuit/stabilizercircuit.py +29 -17
  37. tensorcircuit/templates/__init__.py +2 -0
  38. tensorcircuit/templates/blocks.py +2 -2
  39. tensorcircuit/templates/hamiltonians.py +174 -0
  40. tensorcircuit/templates/lattice.py +1789 -0
  41. tensorcircuit/timeevol.py +896 -0
  42. tensorcircuit/translation.py +10 -3
  43. tensorcircuit/utils.py +7 -0
  44. {tensorcircuit_nightly-1.2.0.dev20250326.dist-info → tensorcircuit_nightly-1.4.0.dev20251128.dist-info}/METADATA +66 -29
  45. tensorcircuit_nightly-1.4.0.dev20251128.dist-info/RECORD +96 -0
  46. {tensorcircuit_nightly-1.2.0.dev20250326.dist-info → tensorcircuit_nightly-1.4.0.dev20251128.dist-info}/WHEEL +1 -1
  47. {tensorcircuit_nightly-1.2.0.dev20250326.dist-info → tensorcircuit_nightly-1.4.0.dev20251128.dist-info}/top_level.txt +0 -1
  48. tensorcircuit_nightly-1.2.0.dev20250326.dist-info/RECORD +0 -118
  49. tests/__init__.py +0 -0
  50. tests/conftest.py +0 -67
  51. tests/test_backends.py +0 -1035
  52. tests/test_calibrating.py +0 -149
  53. tests/test_channels.py +0 -409
  54. tests/test_circuit.py +0 -1699
  55. tests/test_cloud.py +0 -219
  56. tests/test_compiler.py +0 -147
  57. tests/test_dmcircuit.py +0 -555
  58. tests/test_ensemble.py +0 -72
  59. tests/test_fgs.py +0 -310
  60. tests/test_gates.py +0 -156
  61. tests/test_interfaces.py +0 -562
  62. tests/test_keras.py +0 -160
  63. tests/test_miscs.py +0 -282
  64. tests/test_mpscircuit.py +0 -341
  65. tests/test_noisemodel.py +0 -156
  66. tests/test_qaoa.py +0 -86
  67. tests/test_qem.py +0 -152
  68. tests/test_quantum.py +0 -549
  69. tests/test_quantum_attr.py +0 -42
  70. tests/test_results.py +0 -380
  71. tests/test_shadows.py +0 -160
  72. tests/test_simplify.py +0 -46
  73. tests/test_stabilizer.py +0 -217
  74. tests/test_templates.py +0 -218
  75. tests/test_torchnn.py +0 -99
  76. tests/test_van.py +0 -102
  77. {tensorcircuit_nightly-1.2.0.dev20250326.dist-info → tensorcircuit_nightly-1.4.0.dev20251128.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)