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_miscs.py DELETED
@@ -1,282 +0,0 @@
1
- # pylint: disable=invalid-name
2
-
3
- import sys
4
- import os
5
- from functools import partial
6
- import numpy as np
7
- import tensorflow as tf
8
- import pytest
9
- from pytest_lazyfixture import lazy_fixture as lf
10
-
11
- thisfile = os.path.abspath(__file__)
12
- modulepath = os.path.dirname(os.path.dirname(thisfile))
13
-
14
- sys.path.insert(0, modulepath)
15
- import tensorcircuit as tc
16
- from tensorcircuit import experimental
17
- from tensorcircuit.quantum import PauliString2COO, PauliStringSum2COO
18
- from tensorcircuit.applications.vqes import construct_matrix_v2
19
- from tensorcircuit.applications.physics.baseline import TFIM1Denergy, Heisenberg1Denergy
20
-
21
- i, x, y, z = [t.tensor for t in tc.gates.pauli_gates]
22
-
23
- # note i is in use!
24
-
25
- check_pairs = [
26
- ([0, 0], np.eye(4)),
27
- ([0, 1], np.kron(i, x)),
28
- ([2, 1], np.kron(y, x)),
29
- ([3, 1], np.kron(z, x)),
30
- ([3, 2, 2, 0], np.kron(np.kron(np.kron(z, y), y), i)),
31
- ([0, 1, 1, 1], np.kron(np.kron(np.kron(i, x), x), x)),
32
- ]
33
-
34
-
35
- def test_about():
36
- print(tc.about())
37
-
38
-
39
- def test_cite():
40
- print(tc.cite())
41
- print(tc.cite("aps"))
42
-
43
-
44
- def test_ps2coo(tfb):
45
- for l, a in check_pairs:
46
- r1 = PauliString2COO(tf.constant(l, dtype=tf.int64))
47
- np.testing.assert_allclose(tc.backend.to_dense(r1), a, atol=1e-5)
48
-
49
-
50
- def test_pss2coo(tfb):
51
- l = [t[0] for t in check_pairs[:4]]
52
- a = sum([t[1] for t in check_pairs[:4]])
53
- r1 = PauliStringSum2COO(tf.constant(l, dtype=tf.int64))
54
- np.testing.assert_allclose(tc.backend.to_dense(r1), a, atol=1e-5)
55
- l = [t[0] for t in check_pairs[4:]]
56
- a = sum([t[1] for t in check_pairs[4:]])
57
- r1 = PauliStringSum2COO(tf.constant(l, dtype=tf.int64), weight=[0.5, 1])
58
- a = check_pairs[4][1] * 0.5 + check_pairs[5][1] * 1.0
59
- np.testing.assert_allclose(tc.backend.to_dense(r1), a, atol=1e-5)
60
-
61
-
62
- def test_sparse(benchmark, tfb):
63
- def sparse(h):
64
- return PauliStringSum2COO(h)
65
-
66
- h = [[1 for _ in range(12)], [2 for _ in range(12)]]
67
- h = tf.constant(h, dtype=tf.int64)
68
- sparse(h)
69
- benchmark(sparse, h)
70
-
71
-
72
- def test_dense(benchmark, tfb):
73
- def dense(h):
74
- return construct_matrix_v2(h, dtype=tf.complex64)
75
-
76
- h = [[1 for _ in range(12)], [2 for _ in range(12)]]
77
- h = [[1.0] + hi for hi in h]
78
- dense(h)
79
- benchmark(dense, h)
80
-
81
-
82
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
83
- def test_adaptive_vmap(backend):
84
- def f(x):
85
- return x**2
86
-
87
- x = tc.backend.ones([30, 2])
88
-
89
- vf = experimental.adaptive_vmap(f, chunk_size=6)
90
- np.testing.assert_allclose(vf(x), tc.backend.ones([30, 2]), atol=1e-5)
91
-
92
- vf2 = experimental.adaptive_vmap(f, chunk_size=7)
93
- np.testing.assert_allclose(vf2(x), tc.backend.ones([30, 2]), atol=1e-5)
94
-
95
- def f2(x):
96
- return tc.backend.sum(x)
97
-
98
- vf3 = experimental.adaptive_vmap(f2, chunk_size=7)
99
- np.testing.assert_allclose(vf3(x), 2 * tc.backend.ones([30]), atol=1e-5)
100
-
101
- vf3_jit = tc.backend.jit(vf3)
102
- np.testing.assert_allclose(vf3_jit(x), 2 * tc.backend.ones([30]), atol=1e-5)
103
-
104
-
105
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
106
- def test_adaptive_vmap_mul_io(backend):
107
- def f(x, y, a):
108
- return x + y + a
109
-
110
- vf = experimental.adaptive_vmap(f, chunk_size=6, vectorized_argnums=(0, 1))
111
- x = tc.backend.ones([30, 2])
112
- a = tc.backend.ones([2])
113
- # jax vmap has some weird behavior in terms of keyword arguments...
114
- # TODO(@refraction-ray): further investigate jax vmap behavior with kwargs
115
- np.testing.assert_allclose(vf(x, x, a), 3 * tc.backend.ones([30, 2]), atol=1e-5)
116
-
117
-
118
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
119
- def test_qng(backend):
120
- n = 6
121
-
122
- def f(params):
123
- params = tc.backend.reshape(params, [4, n])
124
- c = tc.Circuit(n)
125
- c = tc.templates.blocks.example_block(c, params)
126
- return c.state()
127
-
128
- params = tc.backend.ones([4 * n])
129
- fim = experimental.qng(f)(params)
130
- assert tc.backend.shape_tuple(fim) == (4 * n, 4 * n)
131
- print(experimental.dynamics_matrix(f)(params))
132
-
133
-
134
- @pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
135
- def test_dynamic_rhs(backend):
136
- h1 = tc.array_to_tensor(tc.gates._z_matrix)
137
-
138
- def f(param):
139
- c = tc.Circuit(1)
140
- c.rx(0, theta=param)
141
- return c.state()
142
-
143
- rhsf = experimental.dynamics_rhs(f, h1)
144
- np.testing.assert_allclose(rhsf(tc.backend.ones([])), -np.sin(1.0) / 2, atol=1e-5)
145
-
146
- h2 = tc.backend.coo_sparse_matrix(
147
- indices=tc.array_to_tensor(np.array([[0, 0], [1, 1]]), dtype="int64"),
148
- values=tc.array_to_tensor(np.array([1, -1])),
149
- shape=[2, 2],
150
- )
151
-
152
- rhsf = experimental.dynamics_rhs(f, h2)
153
- np.testing.assert_allclose(rhsf(tc.backend.ones([])), -np.sin(1.0) / 2, atol=1e-5)
154
-
155
-
156
- @pytest.mark.parametrize("backend", ["tensorflow", "jax"])
157
- def test_two_qng_approaches(backend):
158
- n = 6
159
- nlayers = 2
160
- with tc.runtime_backend(backend) as K:
161
- with tc.runtime_dtype("complex128"):
162
-
163
- def state(params):
164
- params = K.reshape(params, [2 * nlayers, n])
165
- c = tc.Circuit(n)
166
- c = tc.templates.blocks.example_block(c, params, nlayers=nlayers)
167
- return c.state()
168
-
169
- params = K.ones([2 * nlayers * n])
170
- params = K.cast(params, "float32")
171
- n1 = experimental.qng(state)(params)
172
- n2 = experimental.qng2(state)(params)
173
- np.testing.assert_allclose(n1, n2, atol=1e-7)
174
-
175
-
176
- def test_arg_alias():
177
- @partial(tc.utils.arg_alias, alias_dict={"theta": ["alpha", "gamma"]})
178
- def f(theta: float, beta: float) -> float:
179
- """
180
- f doc
181
-
182
- :param theta: theta angle
183
- :type theta: float
184
- :param beta: beta angle
185
- :type beta: float
186
- :return: sum angle
187
- :rtype: float
188
- """
189
- return theta + beta
190
-
191
- np.testing.assert_allclose(f(beta=0.2, alpha=0.1), 0.3, atol=1e-5)
192
- print(f.__doc__)
193
- assert len(f.__doc__.strip().split("\n")) == 12
194
-
195
-
196
- def test_finite_difference_tf(tfb):
197
- def f(param1, param2):
198
- n = 4
199
- c = tc.Circuit(n)
200
- for i in range(n):
201
- c.rx(i, theta=param1[i])
202
- for i in range(n - 1):
203
- c.cx(i, i + 1)
204
- for i in range(n - 1):
205
- c.rzz(i, i + 1, theta=param2[i])
206
- r = [c.expectation_ps(z=[i]) for i in range(n)]
207
- return tc.backend.stack(r)
208
-
209
- def fsum(param1, param2):
210
- return tc.backend.mean(f(param1, param2))
211
-
212
- p1 = tf.ones([4])
213
- p2 = tf.ones([3])
214
- g1, g2 = tc.backend.value_and_grad(fsum)(p1, p2)
215
-
216
- f1 = experimental.finite_difference_differentiator(
217
- f, argnums=(0, 1), shifts=(np.pi / 2, 2)
218
- )
219
-
220
- def fsum1(param1, param2):
221
- return tc.backend.mean(f1(param1, param2))
222
-
223
- g3, g4 = tc.backend.value_and_grad(fsum1)(p1, p2)
224
-
225
- np.testing.assert_allclose(g1, g3, atol=1e-5)
226
- np.testing.assert_allclose(g2, g4, atol=1e-5)
227
-
228
-
229
- def test_evol(jaxb):
230
- def h_square(t, b):
231
- return (tc.backend.sign(t - 1.0) + 1) / 2 * b * tc.gates.x().tensor
232
-
233
- c = tc.Circuit(3)
234
- c.x(0)
235
- c.cx(0, 1)
236
- c.h(2)
237
- c = experimental.evol_local(
238
- c, [1], h_square, 2.0, tc.backend.convert_to_tensor(0.2)
239
- )
240
- c.rx(1, theta=np.pi - 0.4)
241
- np.testing.assert_allclose(c.expectation_ps(z=[1]), 1.0, atol=1e-5)
242
-
243
- ixi = tc.quantum.PauliStringSum2COO([[0, 1, 0]])
244
-
245
- def h_square_sparse(t, b):
246
- return (tc.backend.sign(t - 1.0) + 1) / 2 * b * ixi
247
-
248
- c = tc.Circuit(3)
249
- c.x(0)
250
- c.cx(0, 1)
251
- c.h(2)
252
- c = experimental.evol_global(
253
- c, h_square_sparse, 2.0, tc.backend.convert_to_tensor(0.2)
254
- )
255
- c.rx(1, theta=np.pi - 0.4)
256
- np.testing.assert_allclose(c.expectation_ps(z=[1]), 1.0, atol=1e-5)
257
-
258
-
259
- def test_energy_baseline():
260
- print(TFIM1Denergy(10))
261
- print(Heisenberg1Denergy(10))
262
-
263
-
264
- def test_jax_function_load(jaxb, tmp_path):
265
- K = tc.backend
266
-
267
- @K.jit
268
- def f(weights):
269
- c = tc.Circuit(3)
270
- c.rx(range(3), theta=weights)
271
- return K.real(c.expectation_ps(z=[0]))
272
-
273
- print(f(K.ones([3])))
274
-
275
- experimental.jax_jitted_function_save(
276
- os.path.join(tmp_path, "temp.bin"), f, K.ones([3])
277
- )
278
-
279
- f_load = tc.experimental.jax_jitted_function_load(
280
- os.path.join(tmp_path, "temp.bin")
281
- )
282
- np.testing.assert_allclose(f_load(K.ones([3])), 0.5403, atol=1e-4)
tests/test_mpscircuit.py DELETED
@@ -1,341 +0,0 @@
1
- # pylint: disable=unused-variable
2
- # pylint: disable=invalid-name
3
-
4
- from typing import Tuple, Any
5
- import sys
6
- import os
7
- import numpy as np
8
- import pytest
9
- from pytest_lazyfixture import lazy_fixture as lf
10
-
11
- Tensor = Any
12
-
13
- thisfile = os.path.abspath(__file__)
14
- modulepath = os.path.dirname(os.path.dirname(thisfile))
15
-
16
- sys.path.insert(0, modulepath)
17
- import tensorcircuit as tc
18
-
19
-
20
- N = 8
21
- D = 6
22
- split = tc.cons.split_rules(max_singular_values=D)
23
- type_test_circuits = Tuple[
24
- tc.Circuit, Tensor, tc.MPSCircuit, Tensor, tc.MPSCircuit, Tensor
25
- ]
26
-
27
-
28
- def reproducible_unitary(n, param):
29
- exp2n = 2**n
30
- A = tc.backend.cast(
31
- tc.backend.reshape(tc.backend.arange(exp2n**2), (exp2n, exp2n)), tc.dtypestr
32
- )
33
- A = A + tc.backend.sin(A) * param * 1j
34
- A = A - tc.backend.conj(tc.backend.transpose(A))
35
- return tc.backend.reshape(tc.backend.expm(A), (2,) * n * 2)
36
-
37
-
38
- def simulate(c, check=True, params=None):
39
- if params is None:
40
- params = tc.backend.ones((3,), dtype=tc.dtypestr)
41
- O1 = tc.gates.any(reproducible_unitary(1, params[0]))
42
- O2 = tc.gates.any(reproducible_unitary(2, params[1]))
43
- O3 = tc.gates.any(reproducible_unitary(3, params[2]))
44
-
45
- # Construct a complicated circuit by Circuit and MPSCircuit and compare
46
-
47
- c.H(0)
48
- # create as much correlation as possible
49
- for i in range(0, N - 1, 2):
50
- c.apply(O2.copy(), i, i + 1)
51
- c.apply(O1.copy(), i)
52
- c.apply(O3.copy(), int(N * 0.1), int(N * 0.5), int(N * 0.9))
53
- c.apply(O2.copy(), 1, N - 2)
54
- if check and isinstance(c, tc.MPSCircuit):
55
- np.testing.assert_allclose(np.abs(c._mps.check_canonical()), 0, atol=1e-12)
56
- c.cz(2, 3)
57
-
58
-
59
- def get_test_circuits() -> type_test_circuits:
60
- c = tc.Circuit(N)
61
- simulate(c)
62
- w_c = c.wavefunction()
63
-
64
- mps = tc.MPSCircuit(N, split=split)
65
- simulate(mps)
66
- do_test_norm(mps)
67
- mps.normalize()
68
- w_mps = mps.wavefunction()
69
-
70
- mps_exact = tc.MPSCircuit(N)
71
- simulate(mps_exact)
72
- w_mps_exact = mps_exact.wavefunction()
73
-
74
- return [c, w_c, mps, w_mps, mps_exact, w_mps_exact]
75
-
76
-
77
- def do_test_norm(mps: tc.MPSCircuit):
78
- norm1 = mps.get_norm()
79
- norm2 = tc.backend.norm(mps.wavefunction())
80
- np.testing.assert_allclose(norm1, norm2, atol=1e-12)
81
-
82
-
83
- def do_test_canonical(test_circuits: type_test_circuits):
84
- (
85
- c,
86
- w_c,
87
- mps,
88
- w_mps,
89
- mps_exact,
90
- w_mps_exact,
91
- ) = test_circuits
92
- np.testing.assert_allclose(np.abs(mps._mps.check_canonical()), 0, atol=1e-12)
93
- np.testing.assert_allclose(np.abs(mps_exact._mps.check_canonical()), 0, atol=1e-12)
94
-
95
-
96
- def do_test_wavefunction(test_circuits: type_test_circuits):
97
- (
98
- c,
99
- w_c,
100
- mps,
101
- w_mps,
102
- mps_exact,
103
- w_mps_exact,
104
- ) = test_circuits
105
- # the wavefuntion is exact if there's no truncation
106
- np.testing.assert_allclose(tc.backend.numpy(w_mps_exact), tc.backend.numpy(w_c))
107
-
108
-
109
- def do_test_truncation(
110
- test_circuits: type_test_circuits, real_fedility_ref, estimated_fedility_ref
111
- ):
112
- (
113
- c,
114
- w_c,
115
- mps,
116
- w_mps,
117
- mps_exact,
118
- w_mps_exact,
119
- ) = test_circuits
120
- # compare with a precalculated value
121
- real_fedility = (
122
- np.abs(tc.backend.numpy(w_mps).conj().dot(tc.backend.numpy(w_c))) ** 2
123
- )
124
- estimated_fedility = tc.backend.numpy(mps._fidelity)
125
- print(real_fedility, estimated_fedility)
126
- if real_fedility_ref is not None:
127
- np.testing.assert_allclose(real_fedility, real_fedility_ref, atol=1e-5)
128
- if estimated_fedility_ref is not None:
129
- np.testing.assert_allclose(
130
- estimated_fedility, estimated_fedility_ref, atol=1e-5
131
- )
132
-
133
-
134
- def do_test_amplitude(test_circuits: type_test_circuits):
135
- (
136
- c,
137
- w_c,
138
- mps,
139
- w_mps,
140
- mps_exact,
141
- w_mps_exact,
142
- ) = test_circuits
143
- # compare with wavefunction
144
- s = "01" * (N // 2)
145
- sint = int(s, 2) # binary to decimal
146
- err_amplitude = tc.backend.abs(mps.amplitude(s) - w_mps[sint])
147
- np.testing.assert_allclose(err_amplitude, 0, atol=1e-12)
148
-
149
-
150
- def do_test_expectation(test_circuits: type_test_circuits):
151
- (
152
- c,
153
- w_c,
154
- mps,
155
- w_mps,
156
- mps_exact,
157
- w_mps_exact,
158
- ) = test_circuits
159
-
160
- single_gate = (tc.gates.z(), [3])
161
- tensor = (np.sin(np.arange(16)) + np.cos(np.arange(16)) * 1j).reshape((2, 2, 2, 2))
162
- double_gate_nonunitary = (
163
- tc.gates.Gate(tc.backend.convert_to_tensor(tensor)),
164
- [2, 6],
165
- )
166
- double_gate = (tc.gates.cnot(), [2, 6])
167
- triple_gate = (tc.gates.toffoli(), [7, 1, 5])
168
- gates = [single_gate, double_gate_nonunitary, triple_gate]
169
-
170
- exp_mps = mps_exact.expectation(*gates)
171
- exp_c = c.expectation(*gates, reuse=False)
172
- np.testing.assert_allclose(exp_mps, exp_c, atol=1e-7)
173
-
174
- # ps
175
- x = [0, 2]
176
- y = [5, 3, 1]
177
- z = [6, 4]
178
- exp_mps = mps_exact.expectation_ps(x=x, y=y, z=z)
179
- exp_c = c.expectation_ps(x=x, y=y, z=z)
180
- np.testing.assert_allclose(exp_mps, exp_c, atol=1e-7)
181
-
182
-
183
- def external_wavefunction():
184
- # create a fixed wavefunction and create the corresponding MPS
185
- w_external = np.abs(np.sin(np.arange(2**N) % np.exp(1))).astype(
186
- tc.dtypestr
187
- ) # Just want to find a function that is so strange that the correlation is strong enough
188
- w_external /= np.linalg.norm(w_external)
189
- w_external = tc.backend.convert_to_tensor(w_external)
190
- mps_external = tc.MPSCircuit(N, wavefunction=w_external, split=split)
191
- mps_external_exact = tc.MPSCircuit(N, wavefunction=w_external)
192
- return w_external, mps_external, mps_external_exact
193
-
194
-
195
- def do_test_fromwavefunction(external_wavefunction, relative_err_ref):
196
- (
197
- w_external,
198
- mps_external,
199
- mps_external_exact,
200
- ) = external_wavefunction
201
- np.testing.assert_allclose(mps_external_exact.wavefunction(), w_external, atol=1e-7)
202
- # compare fidelity of truncation with theoretical limit obtained by SVD
203
- w_external = tc.backend.numpy(w_external)
204
- real_fedility = (
205
- np.abs(tc.backend.numpy(mps_external.wavefunction()).conj().dot(w_external))
206
- ** 2
207
- )
208
- s = np.linalg.svd(w_external.reshape((2 ** (N // 2), 2 ** (N // 2))))[1]
209
- theoretical_upper_limit = np.sum(s[0:D] ** 2)
210
- relative_err = np.log((1 - real_fedility) / (1 - theoretical_upper_limit))
211
- if relative_err_ref is not None:
212
- np.testing.assert_allclose(relative_err, relative_err_ref, atol=1e-4)
213
-
214
-
215
- def do_test_proj(test_circuits: type_test_circuits, external_wavefunction):
216
- (
217
- c,
218
- w_c,
219
- mps,
220
- w_mps,
221
- mps_exact,
222
- w_mps_exact,
223
- ) = test_circuits
224
- (
225
- w_external,
226
- mps_external,
227
- mps_external_exact,
228
- ) = external_wavefunction
229
- # compare projection value with wavefunction calculated results
230
- proj = mps.proj_with_mps(mps_external)
231
- proj_ref = (
232
- tc.backend.numpy(mps_external.wavefunction())
233
- .conj()
234
- .dot(tc.backend.numpy(w_mps))
235
- )
236
- np.testing.assert_allclose(proj, proj_ref, atol=1e-12)
237
-
238
-
239
- def do_test_tensor_input(test_circuits: type_test_circuits):
240
- (
241
- c,
242
- w_c,
243
- mps,
244
- w_mps,
245
- mps_exact,
246
- w_mps_exact,
247
- ) = test_circuits
248
- newmps = tc.MPSCircuit(
249
- mps._nqubits,
250
- tensors=mps.get_tensors(),
251
- center_position=mps.get_center_position(),
252
- )
253
- for t1, t2 in zip(newmps.get_tensors(), mps.get_tensors()):
254
- np.testing.assert_allclose(
255
- tc.backend.numpy(t1), tc.backend.numpy(t2), atol=1e-12
256
- )
257
-
258
-
259
- def do_test_measure(test_circuits: type_test_circuits):
260
- (
261
- c,
262
- w_c,
263
- mps,
264
- w_mps,
265
- mps_exact,
266
- w_mps_exact,
267
- ) = test_circuits
268
- index = [6, 5, 2, 1]
269
- status = tc.backend.convert_to_tensor([0.1, 0.3, 0.7, 0.9])
270
- result_c = c.measure(*index, with_prob=True, status=status)
271
- result_mps_exact = mps_exact.measure(*index, with_prob=True, status=status)
272
- np.testing.assert_allclose(result_mps_exact[0], result_c[0], atol=1e-8)
273
- np.testing.assert_allclose(result_mps_exact[1], result_c[1], atol=1e-8)
274
-
275
-
276
- def test_MPO_conversion(highp, tfb):
277
- O3 = reproducible_unitary(3, 1.0)
278
- I = tc.backend.eye(2, dtype=tc.dtypestr)
279
- gate = tc.gates.Gate(O3)
280
-
281
- MPO3, _ = tc.MPSCircuit.gate_to_MPO(gate, 2, 3, 4)
282
- tensor3 = tc.MPSCircuit.MPO_to_gate(MPO3).tensor
283
- tensor3 = tc.backend.numpy(tensor3)
284
- tensor3_ref = tc.backend.numpy(O3)
285
- np.testing.assert_allclose(tensor3, tensor3_ref, atol=1e-12)
286
-
287
- MPO4, _ = tc.MPSCircuit.gate_to_MPO(gate, 1, 3, 4)
288
- tensor4 = tc.MPSCircuit.MPO_to_gate(MPO4).tensor
289
- tensor4_ref = tc.backend.einsum("ijkabc,pq->ipjkaqbc", O3, I)
290
- tensor4 = tc.backend.numpy(tensor4)
291
- tensor4_ref = tc.backend.numpy(tensor4_ref)
292
- np.testing.assert_allclose(tensor4, tensor4_ref, atol=1e-12)
293
-
294
-
295
- @pytest.mark.parametrize(
296
- "backend, dtype", [(lf("tfb"), lf("highp")), (lf("jaxb"), lf("highp"))]
297
- )
298
- def test_circuits(backend, dtype):
299
- circuits = get_test_circuits()
300
- do_test_canonical(circuits)
301
- do_test_wavefunction(circuits)
302
- do_test_truncation(circuits, 0.902663090851, 0.910305380327)
303
- do_test_amplitude(circuits)
304
- do_test_expectation(circuits)
305
- external = external_wavefunction()
306
- do_test_fromwavefunction(external, 0.276089)
307
- do_test_proj(circuits, external)
308
- do_test_tensor_input(circuits)
309
- do_test_measure(circuits)
310
-
311
-
312
- @pytest.mark.parametrize("backend, dtype", [(lf("tfb"), lf("highp"))])
313
- def test_circuits_jit(backend, dtype):
314
- def expec(params):
315
- mps = tc.MPSCircuit(N, split=split)
316
- simulate(mps, check=False, params=params)
317
- x = [0, 2]
318
- y = [5, 3, 1]
319
- z = [6, 4]
320
- exp = mps.expectation_ps(x=x, y=y, z=z)
321
- return tc.backend.real(exp)
322
-
323
- params = tc.backend.ones((3,), dtype=tc.dtypestr)
324
- expec_vg = tc.backend.value_and_grad(expec)
325
- expec_vg_jit = tc.backend.jit(expec_vg)
326
- exp = expec(params)
327
- exp_jit, exp_grad_jit = expec_vg_jit(params)
328
- dir = tc.backend.convert_to_tensor(np.array([1.0, 2.0, 3.0], dtype=tc.dtypestr))
329
- epsilon = 1e-6
330
- exp_p = expec(params + dir * epsilon)
331
- exp_m = expec(params - dir * epsilon)
332
- exp_grad_dir_numerical = (exp_p - exp_m) / (epsilon * 2)
333
- exp_grad_dir_jit = tc.backend.real(tc.backend.sum(exp_grad_jit * dir))
334
- np.testing.assert_allclose(
335
- tc.backend.numpy(exp), tc.backend.numpy(exp_jit), atol=1e-10
336
- )
337
- np.testing.assert_allclose(
338
- tc.backend.numpy(exp_grad_dir_numerical),
339
- tc.backend.numpy(exp_grad_dir_jit),
340
- atol=1e-6,
341
- )