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.
- tensorcircuit/__init__.py +5 -1
- tensorcircuit/abstractcircuit.py +4 -0
- tensorcircuit/analogcircuit.py +413 -0
- tensorcircuit/applications/layers.py +1 -1
- tensorcircuit/applications/van.py +1 -1
- tensorcircuit/backends/abstract_backend.py +312 -5
- tensorcircuit/backends/cupy_backend.py +3 -1
- tensorcircuit/backends/jax_backend.py +92 -3
- tensorcircuit/backends/jax_ops.py +108 -0
- tensorcircuit/backends/numpy_backend.py +49 -3
- tensorcircuit/backends/pytorch_backend.py +92 -3
- tensorcircuit/backends/tensorflow_backend.py +102 -3
- tensorcircuit/basecircuit.py +123 -82
- tensorcircuit/circuit.py +67 -57
- tensorcircuit/cloud/local.py +1 -1
- tensorcircuit/cloud/quafu_provider.py +1 -1
- tensorcircuit/cloud/tencent.py +1 -1
- tensorcircuit/compiler/simple_compiler.py +2 -2
- tensorcircuit/cons.py +1 -0
- tensorcircuit/densitymatrix.py +16 -11
- tensorcircuit/experimental.py +7 -152
- tensorcircuit/fgs.py +5 -6
- tensorcircuit/gates.py +66 -22
- tensorcircuit/keras.py +3 -3
- tensorcircuit/mpscircuit.py +109 -61
- tensorcircuit/quantum.py +697 -133
- tensorcircuit/quditcircuit.py +733 -0
- tensorcircuit/quditgates.py +618 -0
- tensorcircuit/results/counts.py +45 -31
- tensorcircuit/shadows.py +1 -1
- tensorcircuit/simplify.py +3 -1
- tensorcircuit/stabilizercircuit.py +4 -2
- tensorcircuit/templates/blocks.py +2 -2
- tensorcircuit/templates/hamiltonians.py +29 -8
- tensorcircuit/templates/lattice.py +676 -335
- tensorcircuit/timeevol.py +896 -0
- {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/METADATA +50 -25
- tensorcircuit_nightly-1.4.0.dev20251103.dist-info/RECORD +96 -0
- {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/top_level.txt +0 -1
- tensorcircuit_nightly-1.3.0.dev20250728.dist-info/RECORD +0 -122
- tests/__init__.py +0 -0
- tests/conftest.py +0 -67
- tests/test_backends.py +0 -1035
- tests/test_calibrating.py +0 -149
- tests/test_channels.py +0 -409
- tests/test_circuit.py +0 -1713
- tests/test_cloud.py +0 -219
- tests/test_compiler.py +0 -147
- tests/test_dmcircuit.py +0 -555
- tests/test_ensemble.py +0 -72
- tests/test_fgs.py +0 -318
- tests/test_gates.py +0 -156
- tests/test_hamiltonians.py +0 -159
- tests/test_interfaces.py +0 -557
- tests/test_keras.py +0 -160
- tests/test_lattice.py +0 -1666
- tests/test_miscs.py +0 -334
- tests/test_mpscircuit.py +0 -341
- tests/test_noisemodel.py +0 -156
- tests/test_qaoa.py +0 -86
- tests/test_qem.py +0 -152
- tests/test_quantum.py +0 -549
- tests/test_quantum_attr.py +0 -42
- tests/test_results.py +0 -379
- tests/test_shadows.py +0 -160
- tests/test_simplify.py +0 -46
- tests/test_stabilizer.py +0 -226
- tests/test_templates.py +0 -218
- tests/test_torchnn.py +0 -99
- tests/test_van.py +0 -102
- {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/WHEEL +0 -0
- {tensorcircuit_nightly-1.3.0.dev20250728.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/licenses/LICENSE +0 -0
tests/test_fgs.py
DELETED
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import pytest
|
|
3
|
-
from pytest_lazyfixture import lazy_fixture as lf
|
|
4
|
-
import tensorflow as tf
|
|
5
|
-
|
|
6
|
-
try:
|
|
7
|
-
import openfermion as _
|
|
8
|
-
except ModuleNotFoundError:
|
|
9
|
-
pytestmark = pytest.mark.skip("skip fgs test due to missing openfermion module")
|
|
10
|
-
|
|
11
|
-
import tensorcircuit as tc
|
|
12
|
-
|
|
13
|
-
F = tc.fgs.FGSSimulator
|
|
14
|
-
FT = tc.fgs.FGSTestSimulator
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
18
|
-
def test_cmatrix(backend, highp):
|
|
19
|
-
import openfermion
|
|
20
|
-
|
|
21
|
-
def asymmetric_hopping(J, gamma, i, j, L):
|
|
22
|
-
m0 = tc.fgs.onehot_matrix(i, j, 2 * L) - tc.fgs.onehot_matrix(
|
|
23
|
-
j + L, i + L, 2 * L
|
|
24
|
-
)
|
|
25
|
-
m = (J + gamma) * m0 + (J - gamma) * tc.backend.adjoint(m0)
|
|
26
|
-
return m / 2
|
|
27
|
-
|
|
28
|
-
def asymmetric_hopping_jw(J, gamma, i, j, L):
|
|
29
|
-
op = (J + gamma) * openfermion.FermionOperator(f"{str(i)}^ {str(j)}") + np.conj(
|
|
30
|
-
J - gamma
|
|
31
|
-
) * openfermion.FermionOperator(f"{str(j)}^ {str(i)}")
|
|
32
|
-
sop = openfermion.transforms.jordan_wigner(op)
|
|
33
|
-
m = openfermion.get_sparse_operator(sop, n_qubits=L).todense()
|
|
34
|
-
return m
|
|
35
|
-
|
|
36
|
-
c = tc.fgs.FGSSimulator(4, [0])
|
|
37
|
-
c1 = tc.fgs.FGSTestSimulator(4, [0])
|
|
38
|
-
c.evol_hp(0, 1, 1.2)
|
|
39
|
-
c1.evol_hp(0, 1, 1.2)
|
|
40
|
-
c.evol_icp(2, 0.5)
|
|
41
|
-
c1.evol_icp(2, 0.5)
|
|
42
|
-
c.evol_cp(0, -0.8)
|
|
43
|
-
c1.evol_cp(0, -0.8)
|
|
44
|
-
c.evol_sp(1, 0, 0.5)
|
|
45
|
-
c1.evol_sp(1, 0, 0.5)
|
|
46
|
-
c.evol_ghamiltonian(asymmetric_hopping(1, 0.5, 0, 2, 4))
|
|
47
|
-
c1.evol_ghamiltonian(np.array(asymmetric_hopping_jw(1, 0.5, 0, 2, 4)))
|
|
48
|
-
c.evol_sp(1, 2, 1.5)
|
|
49
|
-
c1.evol_sp(1, 2, 1.5)
|
|
50
|
-
c.evol_ihamiltonian(c.chemical_potential(1.0, 1, 4))
|
|
51
|
-
c1.evol_ihamiltonian(c1.chemical_potential_jw(1.0, 1, 4))
|
|
52
|
-
np.testing.assert_allclose(
|
|
53
|
-
c1.get_cmatrix_majorana(), c.get_cmatrix_majorana(), atol=1e-5
|
|
54
|
-
)
|
|
55
|
-
np.testing.assert_allclose(c1.get_cmatrix(), c.get_cmatrix(), atol=1e-5)
|
|
56
|
-
np.testing.assert_allclose(c1.entropy([0, 2]), c.entropy([0, 2]), atol=1e-5)
|
|
57
|
-
np.testing.assert_allclose(
|
|
58
|
-
c1.renyi_entropy(2, [1]), c.renyi_entropy(2, [1]), atol=1e-5
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def test_full_trace():
|
|
63
|
-
c = tc.FGSSimulator(4)
|
|
64
|
-
with pytest.raises(ValueError):
|
|
65
|
-
c.entropy([0, 1, 2, 3])
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
69
|
-
def test_otoc(backend, highp):
|
|
70
|
-
c = tc.FGSSimulator(4, [0, 1])
|
|
71
|
-
c1 = tc.fgs.FGSTestSimulator(4, [0, 1])
|
|
72
|
-
h = c.hopping(0.6, 1, 2, 4)
|
|
73
|
-
h += c.hopping(-0.8, 3, 2, 4)
|
|
74
|
-
h += c.chemical_potential(0.3, 2, 4)
|
|
75
|
-
h1 = c1.hopping_jw(0.6, 1, 2, 4)
|
|
76
|
-
h1 += c1.hopping_jw(-0.8, 3, 2, 4)
|
|
77
|
-
h1 += c1.chemical_potential_jw(0.3, 2, 4)
|
|
78
|
-
c.evol_hamiltonian(h)
|
|
79
|
-
m = c.get_cmatrix(now_i=True, now_j=False)
|
|
80
|
-
m0 = c1.get_ot_cmatrix(h1)
|
|
81
|
-
np.testing.assert_allclose(m, m0, atol=1e-5)
|
|
82
|
-
m = c.get_cmatrix(now_i=False, now_j=True)
|
|
83
|
-
m0 = c1.get_ot_cmatrix(h1, now_i=False)
|
|
84
|
-
np.testing.assert_allclose(m, m0, atol=1e-5)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
|
|
88
|
-
def test_fgs_ad(backend, highp):
|
|
89
|
-
import optax
|
|
90
|
-
|
|
91
|
-
N = 18
|
|
92
|
-
|
|
93
|
-
def f(chi):
|
|
94
|
-
c = tc.fgs.FGSSimulator(N, [0])
|
|
95
|
-
for i in range(N - 1):
|
|
96
|
-
c.evol_hp(i, i + 1, chi[i])
|
|
97
|
-
cm = c.get_cmatrix()
|
|
98
|
-
return -tc.backend.real(1 - cm[N, N])
|
|
99
|
-
|
|
100
|
-
chi_vg = tc.backend.jit(tc.backend.value_and_grad(f))
|
|
101
|
-
|
|
102
|
-
if tc.backend.name == "tensorflow":
|
|
103
|
-
opt = tc.backend.optimizer(tf.keras.optimizers.Adam(1e-2))
|
|
104
|
-
else:
|
|
105
|
-
opt = tc.backend.optimizer(optax.adam(1e-2))
|
|
106
|
-
|
|
107
|
-
param = tc.backend.ones([N - 1], dtype="float64")
|
|
108
|
-
for _ in range(300):
|
|
109
|
-
vs, gs = chi_vg(param)
|
|
110
|
-
param = opt.update(gs, param)
|
|
111
|
-
|
|
112
|
-
np.testing.assert_allclose(vs, -0.9986, atol=1e-2)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
116
|
-
def test_hamiltonian_generation(backend):
|
|
117
|
-
hc = F.chemical_potential(0.8, 0, 3)
|
|
118
|
-
h1 = FT.get_hmatrix(hc, 3) + 0.4 * tc.backend.eye(2**3)
|
|
119
|
-
# constant shift
|
|
120
|
-
h2 = FT.chemical_potential_jw(0.8, 0, 3)
|
|
121
|
-
np.testing.assert_allclose(h1, h2, atol=1e-5)
|
|
122
|
-
|
|
123
|
-
hc = F.hopping(0.8j, 0, 1, 3)
|
|
124
|
-
h1 = FT.get_hmatrix(hc, 3)
|
|
125
|
-
h2 = FT.hopping_jw(0.8j, 0, 1, 3)
|
|
126
|
-
np.testing.assert_allclose(h1, h2, atol=1e-5)
|
|
127
|
-
|
|
128
|
-
hc = F.sc_pairing(0.8, 1, 0, 3)
|
|
129
|
-
h1 = FT.get_hmatrix(hc, 3)
|
|
130
|
-
h2 = FT.sc_pairing_jw(0.8, 1, 0, 3)
|
|
131
|
-
np.testing.assert_allclose(h1, h2, atol=1e-5)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
135
|
-
def test_ground_state(backend, highp):
|
|
136
|
-
N = 3
|
|
137
|
-
hc = (
|
|
138
|
-
F.hopping(1.0, 0, 1, N)
|
|
139
|
-
+ F.hopping(1.0, 1, 2, N)
|
|
140
|
-
+ F.chemical_potential(0.4, 0, N)
|
|
141
|
-
- F.chemical_potential(0.4, 1, N)
|
|
142
|
-
+ F.sc_pairing(0.8, 0, 1, N)
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
c = F(N, hc=hc)
|
|
146
|
-
c1 = FT(N, hc=hc)
|
|
147
|
-
|
|
148
|
-
np.testing.assert_allclose(c.get_cmatrix(), c1.get_cmatrix(), atol=1e-6)
|
|
149
|
-
np.testing.assert_allclose(c1.entropy([0]), c.entropy([0]), atol=1e-5)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
153
|
-
def test_post_select(backend, highp):
|
|
154
|
-
for ind in [0, 1, 2]:
|
|
155
|
-
for keep in [0, 1]:
|
|
156
|
-
c = F(3, filled=[0, 2])
|
|
157
|
-
c.evol_hp(0, 1, 0.2)
|
|
158
|
-
c.evol_cp(0, 0.5)
|
|
159
|
-
c.evol_hp(1, 2, 0.3j)
|
|
160
|
-
c.evol_cp(1, -0.8)
|
|
161
|
-
c.evol_sp(0, 2, 0.3)
|
|
162
|
-
c.post_select(ind, keep)
|
|
163
|
-
c1 = FT(3, filled=[0, 2])
|
|
164
|
-
c1.evol_hp(0, 1, 0.2)
|
|
165
|
-
c1.evol_cp(0, 0.5)
|
|
166
|
-
c1.evol_hp(1, 2, 0.3j)
|
|
167
|
-
c1.evol_cp(1, -0.8)
|
|
168
|
-
c1.evol_sp(0, 2, 0.3)
|
|
169
|
-
c1.post_select(ind, keep)
|
|
170
|
-
np.testing.assert_allclose(c.get_cmatrix(), c1.get_cmatrix(), atol=1e-5)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
174
|
-
def test_post_select_cmatrix_refresh(backend, highp):
|
|
175
|
-
sim_post = tc.FGSSimulator(L=2, filled=[0])
|
|
176
|
-
sim_post.evol_hp(0, 1, np.pi / 4)
|
|
177
|
-
sim_post.post_select(0, keep=1)
|
|
178
|
-
np.testing.assert_allclose(1 - sim_post.get_cmatrix()[0, 0], 1, atol=1e-6)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
@pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
|
|
182
|
-
def test_jittable_measure(backend):
|
|
183
|
-
@tc.backend.jit
|
|
184
|
-
def get_cmatrix(status):
|
|
185
|
-
r = []
|
|
186
|
-
c = F(3, filled=[0])
|
|
187
|
-
c.evol_hp(0, 1, 0.2)
|
|
188
|
-
c.evol_cp(0, 0.5)
|
|
189
|
-
c.evol_hp(1, 2, 0.3j)
|
|
190
|
-
r.append(c.cond_measure(1, status[0]))
|
|
191
|
-
c.evol_cp(1, -0.8)
|
|
192
|
-
r.append(c.cond_measure(2, status[1]))
|
|
193
|
-
r.append(c.cond_measure(1, status[3]))
|
|
194
|
-
c.evol_sp(0, 2, 0.3)
|
|
195
|
-
c.evol_hp(2, 1, 0.2)
|
|
196
|
-
c.evol_hp(0, 1, 0.8)
|
|
197
|
-
return c.get_cmatrix(), tc.backend.stack(r)
|
|
198
|
-
|
|
199
|
-
def get_cmatrix_baseline(status):
|
|
200
|
-
r = []
|
|
201
|
-
c = FT(3, filled=[0])
|
|
202
|
-
c.evol_hp(0, 1, 0.2)
|
|
203
|
-
c.evol_cp(0, 0.5)
|
|
204
|
-
c.evol_hp(1, 2, 0.3j)
|
|
205
|
-
r.append(c.cond_measure(1, status[0]))
|
|
206
|
-
c.evol_cp(1, -0.8)
|
|
207
|
-
r.append(c.cond_measure(2, status[1]))
|
|
208
|
-
r.append(c.cond_measure(1, status[3]))
|
|
209
|
-
c.evol_sp(0, 2, 0.3)
|
|
210
|
-
c.evol_hp(2, 1, 0.2)
|
|
211
|
-
c.evol_hp(0, 1, 0.8)
|
|
212
|
-
return c.get_cmatrix(), np.array(r)
|
|
213
|
-
|
|
214
|
-
status = np.array([0.2, 0.83, 0.61, 0.07])
|
|
215
|
-
m, his = get_cmatrix(tc.backend.convert_to_tensor(status))
|
|
216
|
-
m1, his1 = get_cmatrix_baseline(status)
|
|
217
|
-
np.testing.assert_allclose(m, m1, atol=1e-5)
|
|
218
|
-
np.testing.assert_allclose(his, his1, atol=1e-5)
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
222
|
-
def test_exp_2body(backend):
|
|
223
|
-
c = F(3, filled=[1])
|
|
224
|
-
np.testing.assert_allclose(c.expectation_2body(4, 1), 1.0, atol=1e-5)
|
|
225
|
-
np.testing.assert_allclose(c.expectation_2body(5, 2), 0.0, atol=1e-5)
|
|
226
|
-
np.testing.assert_allclose(c.expectation_2body(1, 4), 0.0, atol=1e-5)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
230
|
-
def test_exp_4body(backend):
|
|
231
|
-
c = F(4, filled=[0, 2])
|
|
232
|
-
c.evol_hp(0, 1, 0.3)
|
|
233
|
-
c.evol_hp(2, 3, 0.3)
|
|
234
|
-
c.evol_sp(0, 3, 0.5)
|
|
235
|
-
c.evol_sp(0, 2, 0.9)
|
|
236
|
-
c.evol_cp(0, -0.4)
|
|
237
|
-
|
|
238
|
-
c1 = FT(4, filled=[0, 2])
|
|
239
|
-
c1.evol_hp(0, 1, 0.3)
|
|
240
|
-
c1.evol_hp(2, 3, 0.3)
|
|
241
|
-
c1.evol_sp(0, 3, 0.5)
|
|
242
|
-
c1.evol_sp(0, 2, 0.9)
|
|
243
|
-
c1.evol_cp(0, -0.4)
|
|
244
|
-
|
|
245
|
-
np.testing.assert_allclose(
|
|
246
|
-
c.expectation_4body(0, 4, 1, 5), c.expectation_4body(0, 4, 1, 5), atol=1e-5
|
|
247
|
-
)
|
|
248
|
-
np.testing.assert_allclose(
|
|
249
|
-
c.expectation_4body(0, 1, 4, 5), c.expectation_4body(0, 1, 4, 5), atol=1e-5
|
|
250
|
-
)
|
|
251
|
-
np.testing.assert_allclose(
|
|
252
|
-
c.expectation_4body(0, 4, 2, 6), c.expectation_4body(0, 4, 2, 6), atol=1e-5
|
|
253
|
-
)
|
|
254
|
-
np.testing.assert_allclose(
|
|
255
|
-
c.expectation_4body(0, 2, 3, 1), c.expectation_4body(0, 2, 3, 1), atol=1e-5
|
|
256
|
-
)
|
|
257
|
-
np.testing.assert_allclose(
|
|
258
|
-
c.expectation_4body(0, 1, 4, 6), c.expectation_4body(0, 1, 4, 6), atol=1e-5
|
|
259
|
-
)
|
|
260
|
-
np.testing.assert_allclose(
|
|
261
|
-
c.expectation_4body(1, 0, 6, 7), c.expectation_4body(1, 0, 6, 7), atol=1e-5
|
|
262
|
-
)
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
266
|
-
def test_overlap(backend):
|
|
267
|
-
def compute_overlap(FGScls):
|
|
268
|
-
c = FGScls(3, filled=[0, 2])
|
|
269
|
-
c.evol_hp(0, 1, 1.2)
|
|
270
|
-
c.evol_hp(1, 2, 0.3)
|
|
271
|
-
c.evol_cp(0, 0.5)
|
|
272
|
-
c.evol_sp(0, 2, 0.3)
|
|
273
|
-
c1 = FGScls(3, filled=[0, 2])
|
|
274
|
-
c1.evol_hp(0, 1, 0.2)
|
|
275
|
-
c1.evol_hp(1, 2, 0.6)
|
|
276
|
-
c1.evol_sp(1, 0, -1.1)
|
|
277
|
-
return tc.backend.abs(c.overlap(c1))
|
|
278
|
-
|
|
279
|
-
np.testing.assert_allclose(
|
|
280
|
-
compute_overlap(tc.FGSSimulator), compute_overlap(tc.fgs.FGSTestSimulator), 1e-5
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
285
|
-
def test_entanglement_asymmetry(backend, highp):
|
|
286
|
-
def discrete_c(c):
|
|
287
|
-
c.evol_sp(0, 1, 0.3)
|
|
288
|
-
c.evol_sp(1, 3, 1.1)
|
|
289
|
-
c.evol_hp(0, 1, -0.2)
|
|
290
|
-
c.evol_hp(2, 3, 1.4)
|
|
291
|
-
c.evol_hp(3, 4, -0.6)
|
|
292
|
-
c.evol_hp(4, 5, -0.8)
|
|
293
|
-
c.evol_sp(2, 6, 2.1)
|
|
294
|
-
return c
|
|
295
|
-
|
|
296
|
-
c = discrete_c(tc.fgs.FGSSimulator(7, filled=[0, 2, 4, 6]))
|
|
297
|
-
c1 = discrete_c(tc.fgs.FGSTestSimulator(7, filled=[0, 2, 4, 6]))
|
|
298
|
-
for k in [2, 3, 4]:
|
|
299
|
-
for traceout in [[1, 2, 4, 5], [2, 3, 5], [0, 3, 4, 5, 6]]:
|
|
300
|
-
print(k, traceout)
|
|
301
|
-
sa_ans = c1.renyi_entropy(k, traceout)
|
|
302
|
-
saq_ans = c1.renyi_entanglement_asymmetry(k, traceout)
|
|
303
|
-
np.testing.assert_allclose(
|
|
304
|
-
np.log(c.charge_moment([0 for _ in range(k)], k, traceout))
|
|
305
|
-
* 1
|
|
306
|
-
/ (1 - k),
|
|
307
|
-
sa_ans,
|
|
308
|
-
atol=2e-4,
|
|
309
|
-
)
|
|
310
|
-
saq, std = c.renyi_entanglement_asymmetry(
|
|
311
|
-
k, traceout, batch=400, with_std=True
|
|
312
|
-
)
|
|
313
|
-
np.testing.assert_allclose(
|
|
314
|
-
saq,
|
|
315
|
-
saq_ans,
|
|
316
|
-
atol=6 * std,
|
|
317
|
-
)
|
|
318
|
-
print(std)
|
tests/test_gates.py
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import os
|
|
3
|
-
import numpy as np
|
|
4
|
-
|
|
5
|
-
thisfile = os.path.abspath(__file__)
|
|
6
|
-
modulepath = os.path.dirname(os.path.dirname(thisfile))
|
|
7
|
-
|
|
8
|
-
sys.path.insert(0, modulepath)
|
|
9
|
-
import tensorcircuit as tc
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def test_rgate(highp):
|
|
13
|
-
np.testing.assert_almost_equal(
|
|
14
|
-
tc.gates.r_gate(1, 2, 3).tensor, tc.gates.rgate_theoretical(1, 2, 3).tensor
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def test_phase_gate():
|
|
19
|
-
c = tc.Circuit(1)
|
|
20
|
-
c.h(0)
|
|
21
|
-
c.phase(0, theta=np.pi / 2)
|
|
22
|
-
np.testing.assert_allclose(c.state()[1], 0.7071j, atol=1e-4)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def test_cu_gate():
|
|
26
|
-
c = tc.Circuit(2)
|
|
27
|
-
c.cu(0, 1, theta=np.pi / 2, phi=-np.pi / 4, lbd=np.pi / 4)
|
|
28
|
-
m = c.matrix()
|
|
29
|
-
print(m)
|
|
30
|
-
np.testing.assert_allclose(m[2:, 2:], tc.gates._wroot_matrix, atol=1e-5)
|
|
31
|
-
np.testing.assert_allclose(m[:2, :2], np.eye(2), atol=1e-5)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def test_get_u_parameter(highp):
|
|
35
|
-
for _ in range(6):
|
|
36
|
-
hermitian = np.random.uniform(size=[2, 2])
|
|
37
|
-
hermitian += np.conj(np.transpose(hermitian))
|
|
38
|
-
unitary = tc.backend.expm(hermitian * 1.0j)
|
|
39
|
-
params = tc.gates.get_u_parameter(unitary)
|
|
40
|
-
unitary2 = tc.gates.u_gate(theta=params[0], phi=params[1], lbd=params[2])
|
|
41
|
-
ans = unitary2.tensor
|
|
42
|
-
unitary = unitary / np.exp(1j * np.angle(unitary[0, 0]))
|
|
43
|
-
np.testing.assert_allclose(unitary, ans, atol=1e-3)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def test_ided_gate():
|
|
47
|
-
g = tc.gates.rx.ided()
|
|
48
|
-
np.testing.assert_allclose(
|
|
49
|
-
tc.backend.reshapem(g(theta=0.3).tensor),
|
|
50
|
-
np.kron(np.eye(2), tc.gates.rx(theta=0.3).tensor),
|
|
51
|
-
atol=1e-5,
|
|
52
|
-
)
|
|
53
|
-
g1 = tc.gates.rx.ided(before=False)
|
|
54
|
-
np.testing.assert_allclose(
|
|
55
|
-
tc.backend.reshapem(g1(theta=0.3).tensor),
|
|
56
|
-
np.kron(tc.gates.rx(theta=0.3).tensor, np.eye(2)),
|
|
57
|
-
atol=1e-5,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def test_fsim_gate():
|
|
62
|
-
theta = 0.2
|
|
63
|
-
phi = 0.3
|
|
64
|
-
c = tc.Circuit(2)
|
|
65
|
-
c.iswap(0, 1, theta=-theta)
|
|
66
|
-
c.cphase(0, 1, theta=-phi)
|
|
67
|
-
m = c.matrix()
|
|
68
|
-
ans = np.array(
|
|
69
|
-
[
|
|
70
|
-
[1.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j],
|
|
71
|
-
[0.0 + 0.0j, 0.95105654 + 0.0j, 0.0 - 0.309017j, 0.0 + 0.0j],
|
|
72
|
-
[0.0 + 0.0j, 0.0 - 0.309017j, 0.95105654 + 0.0j, 0.0 + 0.0j],
|
|
73
|
-
[0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j, 0.9553365 - 0.29552022j],
|
|
74
|
-
]
|
|
75
|
-
)
|
|
76
|
-
np.testing.assert_allclose(m, ans, atol=1e-5)
|
|
77
|
-
print(m)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def test_exp_gate():
|
|
81
|
-
c = tc.Circuit(2)
|
|
82
|
-
c.exp(
|
|
83
|
-
0,
|
|
84
|
-
1,
|
|
85
|
-
unitary=tc.gates.array_to_tensor(
|
|
86
|
-
np.array([[1.0, 0, 0, 0], [0, -1.0, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
|
|
87
|
-
),
|
|
88
|
-
theta=tc.gates.num_to_tensor(np.pi / 2),
|
|
89
|
-
)
|
|
90
|
-
np.testing.assert_allclose(c.wavefunction()[0], -1j)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def test_any_gate():
|
|
94
|
-
c = tc.Circuit(2)
|
|
95
|
-
c.any(0, unitary=np.eye(2))
|
|
96
|
-
np.testing.assert_allclose(c.expectation((tc.gates.z(), [0])), 1.0)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def test_iswap_gate():
|
|
100
|
-
t = tc.gates.iswap_gate().tensor
|
|
101
|
-
ans = np.array([[1.0, 0, 0, 0], [0, 0, 1j, 0], [0, 1j, 0, 0], [0, 0, 0, 1.0]])
|
|
102
|
-
np.testing.assert_allclose(t, ans.reshape([2, 2, 2, 2]), atol=1e-5)
|
|
103
|
-
t = tc.gates.iswap_gate(theta=0).tensor
|
|
104
|
-
np.testing.assert_allclose(t, np.eye(4).reshape([2, 2, 2, 2]), atol=1e-5)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def test_gate_list():
|
|
108
|
-
assert tc.Circuit.sgates == tc.abstractcircuit.sgates
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def test_controlled():
|
|
112
|
-
xgate = tc.gates.x
|
|
113
|
-
cxgate = xgate.controlled()
|
|
114
|
-
ccxgate = cxgate.controlled()
|
|
115
|
-
assert ccxgate.n == "ccx"
|
|
116
|
-
assert ccxgate.ctrl == [1, 1]
|
|
117
|
-
np.testing.assert_allclose(
|
|
118
|
-
ccxgate().tensor, tc.backend.reshape2(tc.gates._toffoli_matrix)
|
|
119
|
-
)
|
|
120
|
-
ocxgate = cxgate.ocontrolled()
|
|
121
|
-
c = tc.Circuit(3)
|
|
122
|
-
c.x(0)
|
|
123
|
-
c.any(1, 0, 2, unitary=ocxgate())
|
|
124
|
-
np.testing.assert_allclose(c.expectation([tc.gates.z(), [2]]), -1, atol=1e-5)
|
|
125
|
-
print(c.to_qir()[1])
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def test_variable_controlled():
|
|
129
|
-
crxgate = tc.gates.rx.controlled()
|
|
130
|
-
c = tc.Circuit(2)
|
|
131
|
-
c.x(0)
|
|
132
|
-
tc.Circuit.crx_my = tc.Circuit.apply_general_variable_gate_delayed(crxgate)
|
|
133
|
-
c.crx_my(0, 1, theta=0.3)
|
|
134
|
-
np.testing.assert_allclose(
|
|
135
|
-
c.expectation([tc.gates.z(), [1]]), 0.95533645, atol=1e-5
|
|
136
|
-
)
|
|
137
|
-
assert c.to_qir()[1]["name"] == "crx"
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
def test_adjoint_gate():
|
|
141
|
-
np.testing.assert_allclose(
|
|
142
|
-
tc.gates.sd().tensor, tc.backend.adjoint(tc.gates._s_matrix)
|
|
143
|
-
)
|
|
144
|
-
assert tc.gates.td.n == "td"
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def test_rxx_gate():
|
|
148
|
-
c1 = tc.Circuit(3)
|
|
149
|
-
c1.rxx(0, 1, theta=1.0)
|
|
150
|
-
c1.ryy(0, 2, theta=0.5)
|
|
151
|
-
c1.rzz(0, 1, theta=-0.5)
|
|
152
|
-
c2 = tc.Circuit(3)
|
|
153
|
-
c2.exp1(0, 1, theta=1.0 / 2, unitary=tc.gates._xx_matrix)
|
|
154
|
-
c2.exp1(0, 2, theta=0.5 / 2, unitary=tc.gates._yy_matrix)
|
|
155
|
-
c2.exp1(0, 1, theta=-0.5 / 2, unitary=tc.gates._zz_matrix)
|
|
156
|
-
np.testing.assert_allclose(c1.state(), c2.state(), atol=1e-5)
|
tests/test_hamiltonians.py
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
import numpy as np
|
|
3
|
-
from pytest_lazyfixture import lazy_fixture as lf
|
|
4
|
-
|
|
5
|
-
import tensorcircuit as tc
|
|
6
|
-
|
|
7
|
-
from tensorcircuit.templates.lattice import (
|
|
8
|
-
ChainLattice,
|
|
9
|
-
SquareLattice,
|
|
10
|
-
CustomizeLattice,
|
|
11
|
-
)
|
|
12
|
-
from tensorcircuit.templates.hamiltonians import (
|
|
13
|
-
heisenberg_hamiltonian,
|
|
14
|
-
rydberg_hamiltonian,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
PAULI_X = np.array([[0, 1], [1, 0]], dtype=complex)
|
|
18
|
-
PAULI_Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
|
|
19
|
-
PAULI_Z = np.array([[1, 0], [0, -1]], dtype=complex)
|
|
20
|
-
PAULI_I = np.eye(2, dtype=complex)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class TestHeisenbergHamiltonian:
|
|
24
|
-
"""
|
|
25
|
-
Test suite for the heisenberg_hamiltonian function.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
def test_empty_lattice(self):
|
|
29
|
-
"""
|
|
30
|
-
Test that an empty lattice produces a 0x0 matrix.
|
|
31
|
-
"""
|
|
32
|
-
empty_lattice = CustomizeLattice(
|
|
33
|
-
dimensionality=2, identifiers=[], coordinates=[]
|
|
34
|
-
)
|
|
35
|
-
h = heisenberg_hamiltonian(empty_lattice)
|
|
36
|
-
assert h.shape == (1, 1)
|
|
37
|
-
assert h.nnz == 0
|
|
38
|
-
|
|
39
|
-
def test_single_site(self):
|
|
40
|
-
"""
|
|
41
|
-
Test that a single-site lattice (no bonds) produces a 2x2 zero matrix.
|
|
42
|
-
"""
|
|
43
|
-
single_site_lattice = ChainLattice(size=(1,), pbc=False)
|
|
44
|
-
h = heisenberg_hamiltonian(single_site_lattice)
|
|
45
|
-
assert h.shape == (2, 2)
|
|
46
|
-
assert h.nnz == 0
|
|
47
|
-
|
|
48
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
49
|
-
def test_two_sites_chain(self, backend):
|
|
50
|
-
"""
|
|
51
|
-
Test a two-site chain against a manually calculated Hamiltonian.
|
|
52
|
-
This is the most critical test for scientific correctness.
|
|
53
|
-
"""
|
|
54
|
-
lattice = ChainLattice(size=(2,), pbc=False)
|
|
55
|
-
j_coupling = -1.5 # Test with a non-trivial coupling constant
|
|
56
|
-
h_generated = heisenberg_hamiltonian(lattice, j_coupling=j_coupling)
|
|
57
|
-
|
|
58
|
-
# Manually construct the expected Hamiltonian: H = J * (X_0X_1 + Y_0Y_1 + Z_0Z_1)
|
|
59
|
-
xx = np.kron(PAULI_X, PAULI_X)
|
|
60
|
-
yy = np.kron(PAULI_Y, PAULI_Y)
|
|
61
|
-
zz = np.kron(PAULI_Z, PAULI_Z)
|
|
62
|
-
h_expected = j_coupling * (xx + yy + zz)
|
|
63
|
-
|
|
64
|
-
assert h_generated.shape == (4, 4)
|
|
65
|
-
print(tc.backend.to_dense(h_generated))
|
|
66
|
-
assert np.allclose(tc.backend.to_dense(h_generated), h_expected, atol=1e-5)
|
|
67
|
-
|
|
68
|
-
def test_square_lattice_properties(self):
|
|
69
|
-
"""
|
|
70
|
-
Test properties of a larger lattice (2x2 square) without full matrix comparison.
|
|
71
|
-
"""
|
|
72
|
-
lattice = SquareLattice(size=(2, 2), pbc=True) # 4 sites, 8 bonds with PBC
|
|
73
|
-
h = heisenberg_hamiltonian(lattice, j_coupling=1.0)
|
|
74
|
-
|
|
75
|
-
assert h.shape == (16, 16)
|
|
76
|
-
assert h.nnz > 0
|
|
77
|
-
h_dense = tc.backend.to_dense(h)
|
|
78
|
-
assert np.allclose(h_dense, h_dense.conj().T)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class TestRydbergHamiltonian:
|
|
82
|
-
"""
|
|
83
|
-
Test suite for the rydberg_hamiltonian function.
|
|
84
|
-
"""
|
|
85
|
-
|
|
86
|
-
def test_single_site_rydberg(self):
|
|
87
|
-
"""
|
|
88
|
-
Test a single atom, which should only have driving and detuning terms.
|
|
89
|
-
"""
|
|
90
|
-
lattice = ChainLattice(size=(1,), pbc=False)
|
|
91
|
-
omega, delta, c6 = 2.0, 0.5, 100.0
|
|
92
|
-
h_generated = rydberg_hamiltonian(lattice, omega, delta, c6)
|
|
93
|
-
|
|
94
|
-
h_expected = (omega / 2.0) * PAULI_X + (delta / 2.0) * PAULI_Z
|
|
95
|
-
|
|
96
|
-
assert h_generated.shape == (2, 2)
|
|
97
|
-
assert np.allclose(tc.backend.to_dense(h_generated), h_expected)
|
|
98
|
-
|
|
99
|
-
def test_two_sites_rydberg(self):
|
|
100
|
-
"""
|
|
101
|
-
Test a two-site chain for Rydberg Hamiltonian, including interaction.
|
|
102
|
-
"""
|
|
103
|
-
lattice = ChainLattice(size=(2,), pbc=False, lattice_constant=1.5)
|
|
104
|
-
omega, delta, c6 = 1.0, -0.5, 10.0
|
|
105
|
-
h_generated = rydberg_hamiltonian(lattice, omega, delta, c6)
|
|
106
|
-
|
|
107
|
-
v_ij = c6 / (1.5**6)
|
|
108
|
-
|
|
109
|
-
h1 = (omega / 2.0) * (np.kron(PAULI_X, PAULI_I) + np.kron(PAULI_I, PAULI_X))
|
|
110
|
-
z0_coeff = delta / 2.0 - v_ij / 4.0
|
|
111
|
-
z1_coeff = delta / 2.0 - v_ij / 4.0
|
|
112
|
-
h2 = z0_coeff * np.kron(PAULI_Z, PAULI_I) + z1_coeff * np.kron(PAULI_I, PAULI_Z)
|
|
113
|
-
h3 = (v_ij / 4.0) * np.kron(PAULI_Z, PAULI_Z)
|
|
114
|
-
|
|
115
|
-
h_expected = h1 + h2 + h3
|
|
116
|
-
|
|
117
|
-
assert h_generated.shape == (4, 4)
|
|
118
|
-
h_generated_dense = tc.backend.to_dense(h_generated)
|
|
119
|
-
|
|
120
|
-
assert np.allclose(h_generated_dense, h_expected)
|
|
121
|
-
|
|
122
|
-
def test_zero_distance_robustness(self):
|
|
123
|
-
"""
|
|
124
|
-
Test that the function does not crash when two atoms have zero distance.
|
|
125
|
-
"""
|
|
126
|
-
lattice = CustomizeLattice(
|
|
127
|
-
dimensionality=2,
|
|
128
|
-
identifiers=[0, 1],
|
|
129
|
-
coordinates=[[0.0, 0.0], [0.0, 0.0]],
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
try:
|
|
133
|
-
h = rydberg_hamiltonian(lattice, omega=1.0, delta=1.0, c6=1.0)
|
|
134
|
-
# The X terms contribute 8 non-zero elements.
|
|
135
|
-
# The Z terms (Z0+Z1) have diagonal elements that cancel out,
|
|
136
|
-
# resulting in only 2 non-zero elements. Total nnz = 8 + 2 = 10.
|
|
137
|
-
assert h.nnz == 10
|
|
138
|
-
except ZeroDivisionError:
|
|
139
|
-
pytest.fail("The function failed to handle zero distance between sites.")
|
|
140
|
-
|
|
141
|
-
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
142
|
-
def test_anisotropic_heisenberg(self, backend):
|
|
143
|
-
"""
|
|
144
|
-
Test the anisotropic Heisenberg model with different Jx, Jy, Jz.
|
|
145
|
-
"""
|
|
146
|
-
lattice = ChainLattice(size=(2,), pbc=False)
|
|
147
|
-
j_coupling = [-1.0, 0.5, 2.0] # Jx, Jy, Jz
|
|
148
|
-
h_generated = heisenberg_hamiltonian(lattice, j_coupling=j_coupling)
|
|
149
|
-
|
|
150
|
-
# Manually construct the expected Hamiltonian
|
|
151
|
-
jx, jy, jz = j_coupling
|
|
152
|
-
xx = np.kron(PAULI_X, PAULI_X)
|
|
153
|
-
yy = np.kron(PAULI_Y, PAULI_Y)
|
|
154
|
-
zz = np.kron(PAULI_Z, PAULI_Z)
|
|
155
|
-
h_expected = jx * xx + jy * yy + jz * zz
|
|
156
|
-
|
|
157
|
-
h_generated_dense = tc.backend.to_dense(h_generated)
|
|
158
|
-
assert h_generated_dense.shape == (4, 4)
|
|
159
|
-
assert np.allclose(h_generated_dense, h_expected)
|