Trajectree 0.0.1__py3-none-any.whl → 0.0.3__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.
- trajectree/__init__.py +0 -3
- trajectree/fock_optics/devices.py +1 -1
- trajectree/fock_optics/light_sources.py +2 -2
- trajectree/fock_optics/measurement.py +9 -9
- trajectree/fock_optics/outputs.py +10 -6
- trajectree/fock_optics/utils.py +9 -6
- trajectree/sequence/swap.py +5 -4
- trajectree/trajectory.py +5 -4
- {trajectree-0.0.1.dist-info → trajectree-0.0.3.dist-info}/METADATA +2 -3
- trajectree-0.0.3.dist-info/RECORD +16 -0
- trajectree/quimb/docs/_pygments/_pygments_dark.py +0 -118
- trajectree/quimb/docs/_pygments/_pygments_light.py +0 -118
- trajectree/quimb/docs/conf.py +0 -158
- trajectree/quimb/docs/examples/ex_mpi_expm_evo.py +0 -62
- trajectree/quimb/quimb/__init__.py +0 -507
- trajectree/quimb/quimb/calc.py +0 -1491
- trajectree/quimb/quimb/core.py +0 -2279
- trajectree/quimb/quimb/evo.py +0 -712
- trajectree/quimb/quimb/experimental/__init__.py +0 -0
- trajectree/quimb/quimb/experimental/autojittn.py +0 -129
- trajectree/quimb/quimb/experimental/belief_propagation/__init__.py +0 -109
- trajectree/quimb/quimb/experimental/belief_propagation/bp_common.py +0 -397
- trajectree/quimb/quimb/experimental/belief_propagation/d1bp.py +0 -316
- trajectree/quimb/quimb/experimental/belief_propagation/d2bp.py +0 -653
- trajectree/quimb/quimb/experimental/belief_propagation/hd1bp.py +0 -571
- trajectree/quimb/quimb/experimental/belief_propagation/hv1bp.py +0 -775
- trajectree/quimb/quimb/experimental/belief_propagation/l1bp.py +0 -316
- trajectree/quimb/quimb/experimental/belief_propagation/l2bp.py +0 -537
- trajectree/quimb/quimb/experimental/belief_propagation/regions.py +0 -194
- trajectree/quimb/quimb/experimental/cluster_update.py +0 -286
- trajectree/quimb/quimb/experimental/merabuilder.py +0 -865
- trajectree/quimb/quimb/experimental/operatorbuilder/__init__.py +0 -15
- trajectree/quimb/quimb/experimental/operatorbuilder/operatorbuilder.py +0 -1631
- trajectree/quimb/quimb/experimental/schematic.py +0 -7
- trajectree/quimb/quimb/experimental/tn_marginals.py +0 -130
- trajectree/quimb/quimb/experimental/tnvmc.py +0 -1483
- trajectree/quimb/quimb/gates.py +0 -36
- trajectree/quimb/quimb/gen/__init__.py +0 -2
- trajectree/quimb/quimb/gen/operators.py +0 -1167
- trajectree/quimb/quimb/gen/rand.py +0 -713
- trajectree/quimb/quimb/gen/states.py +0 -479
- trajectree/quimb/quimb/linalg/__init__.py +0 -6
- trajectree/quimb/quimb/linalg/approx_spectral.py +0 -1109
- trajectree/quimb/quimb/linalg/autoblock.py +0 -258
- trajectree/quimb/quimb/linalg/base_linalg.py +0 -719
- trajectree/quimb/quimb/linalg/mpi_launcher.py +0 -397
- trajectree/quimb/quimb/linalg/numpy_linalg.py +0 -244
- trajectree/quimb/quimb/linalg/rand_linalg.py +0 -514
- trajectree/quimb/quimb/linalg/scipy_linalg.py +0 -293
- trajectree/quimb/quimb/linalg/slepc_linalg.py +0 -892
- trajectree/quimb/quimb/schematic.py +0 -1518
- trajectree/quimb/quimb/tensor/__init__.py +0 -401
- trajectree/quimb/quimb/tensor/array_ops.py +0 -610
- trajectree/quimb/quimb/tensor/circuit.py +0 -4824
- trajectree/quimb/quimb/tensor/circuit_gen.py +0 -411
- trajectree/quimb/quimb/tensor/contraction.py +0 -336
- trajectree/quimb/quimb/tensor/decomp.py +0 -1255
- trajectree/quimb/quimb/tensor/drawing.py +0 -1646
- trajectree/quimb/quimb/tensor/fitting.py +0 -385
- trajectree/quimb/quimb/tensor/geometry.py +0 -583
- trajectree/quimb/quimb/tensor/interface.py +0 -114
- trajectree/quimb/quimb/tensor/networking.py +0 -1058
- trajectree/quimb/quimb/tensor/optimize.py +0 -1818
- trajectree/quimb/quimb/tensor/tensor_1d.py +0 -4778
- trajectree/quimb/quimb/tensor/tensor_1d_compress.py +0 -1854
- trajectree/quimb/quimb/tensor/tensor_1d_tebd.py +0 -662
- trajectree/quimb/quimb/tensor/tensor_2d.py +0 -5954
- trajectree/quimb/quimb/tensor/tensor_2d_compress.py +0 -96
- trajectree/quimb/quimb/tensor/tensor_2d_tebd.py +0 -1230
- trajectree/quimb/quimb/tensor/tensor_3d.py +0 -2869
- trajectree/quimb/quimb/tensor/tensor_3d_tebd.py +0 -46
- trajectree/quimb/quimb/tensor/tensor_approx_spectral.py +0 -60
- trajectree/quimb/quimb/tensor/tensor_arbgeom.py +0 -3237
- trajectree/quimb/quimb/tensor/tensor_arbgeom_compress.py +0 -565
- trajectree/quimb/quimb/tensor/tensor_arbgeom_tebd.py +0 -1138
- trajectree/quimb/quimb/tensor/tensor_builder.py +0 -5411
- trajectree/quimb/quimb/tensor/tensor_core.py +0 -11179
- trajectree/quimb/quimb/tensor/tensor_dmrg.py +0 -1472
- trajectree/quimb/quimb/tensor/tensor_mera.py +0 -204
- trajectree/quimb/quimb/utils.py +0 -892
- trajectree/quimb/tests/__init__.py +0 -0
- trajectree/quimb/tests/test_accel.py +0 -501
- trajectree/quimb/tests/test_calc.py +0 -788
- trajectree/quimb/tests/test_core.py +0 -847
- trajectree/quimb/tests/test_evo.py +0 -565
- trajectree/quimb/tests/test_gen/__init__.py +0 -0
- trajectree/quimb/tests/test_gen/test_operators.py +0 -361
- trajectree/quimb/tests/test_gen/test_rand.py +0 -296
- trajectree/quimb/tests/test_gen/test_states.py +0 -261
- trajectree/quimb/tests/test_linalg/__init__.py +0 -0
- trajectree/quimb/tests/test_linalg/test_approx_spectral.py +0 -368
- trajectree/quimb/tests/test_linalg/test_base_linalg.py +0 -351
- trajectree/quimb/tests/test_linalg/test_mpi_linalg.py +0 -127
- trajectree/quimb/tests/test_linalg/test_numpy_linalg.py +0 -84
- trajectree/quimb/tests/test_linalg/test_rand_linalg.py +0 -134
- trajectree/quimb/tests/test_linalg/test_slepc_linalg.py +0 -283
- trajectree/quimb/tests/test_tensor/__init__.py +0 -0
- trajectree/quimb/tests/test_tensor/test_belief_propagation/__init__.py +0 -0
- trajectree/quimb/tests/test_tensor/test_belief_propagation/test_d1bp.py +0 -39
- trajectree/quimb/tests/test_tensor/test_belief_propagation/test_d2bp.py +0 -67
- trajectree/quimb/tests/test_tensor/test_belief_propagation/test_hd1bp.py +0 -64
- trajectree/quimb/tests/test_tensor/test_belief_propagation/test_hv1bp.py +0 -51
- trajectree/quimb/tests/test_tensor/test_belief_propagation/test_l1bp.py +0 -142
- trajectree/quimb/tests/test_tensor/test_belief_propagation/test_l2bp.py +0 -101
- trajectree/quimb/tests/test_tensor/test_circuit.py +0 -816
- trajectree/quimb/tests/test_tensor/test_contract.py +0 -67
- trajectree/quimb/tests/test_tensor/test_decomp.py +0 -40
- trajectree/quimb/tests/test_tensor/test_mera.py +0 -52
- trajectree/quimb/tests/test_tensor/test_optimizers.py +0 -488
- trajectree/quimb/tests/test_tensor/test_tensor_1d.py +0 -1171
- trajectree/quimb/tests/test_tensor/test_tensor_2d.py +0 -606
- trajectree/quimb/tests/test_tensor/test_tensor_2d_tebd.py +0 -144
- trajectree/quimb/tests/test_tensor/test_tensor_3d.py +0 -123
- trajectree/quimb/tests/test_tensor/test_tensor_arbgeom.py +0 -226
- trajectree/quimb/tests/test_tensor/test_tensor_builder.py +0 -441
- trajectree/quimb/tests/test_tensor/test_tensor_core.py +0 -2066
- trajectree/quimb/tests/test_tensor/test_tensor_dmrg.py +0 -388
- trajectree/quimb/tests/test_tensor/test_tensor_spectral_approx.py +0 -63
- trajectree/quimb/tests/test_tensor/test_tensor_tebd.py +0 -270
- trajectree/quimb/tests/test_utils.py +0 -85
- trajectree-0.0.1.dist-info/RECORD +0 -126
- {trajectree-0.0.1.dist-info → trajectree-0.0.3.dist-info}/WHEEL +0 -0
- {trajectree-0.0.1.dist-info → trajectree-0.0.3.dist-info}/licenses/LICENSE +0 -0
- {trajectree-0.0.1.dist-info → trajectree-0.0.3.dist-info}/top_level.txt +0 -0
|
@@ -1,565 +0,0 @@
|
|
|
1
|
-
from pytest import fixture, mark, raises, skip
|
|
2
|
-
|
|
3
|
-
from math import pi, gcd, cos
|
|
4
|
-
from functools import reduce
|
|
5
|
-
|
|
6
|
-
import numpy as np
|
|
7
|
-
from numpy.testing import assert_allclose
|
|
8
|
-
|
|
9
|
-
import quimb as qu
|
|
10
|
-
from quimb.evo import (
|
|
11
|
-
schrodinger_eq_ket,
|
|
12
|
-
schrodinger_eq_dop,
|
|
13
|
-
schrodinger_eq_dop_vectorized,
|
|
14
|
-
lindblad_eq,
|
|
15
|
-
lindblad_eq_vectorized,
|
|
16
|
-
)
|
|
17
|
-
from .test_linalg.test_slepc_linalg import slepc4py_test
|
|
18
|
-
|
|
19
|
-
from quimb.linalg.base_linalg import eigs_scipy
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@fixture
|
|
23
|
-
def psi_dot():
|
|
24
|
-
psi = qu.rand_ket(3)
|
|
25
|
-
ham = 10 * qu.rand_herm(3)
|
|
26
|
-
psid = -1.0j * (ham @ psi)
|
|
27
|
-
return psi, ham, psid
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@fixture
|
|
31
|
-
def spsi_dot():
|
|
32
|
-
psi = qu.rand_ket(3)
|
|
33
|
-
ham = qu.rand_herm(3, sparse=True, density=0.5)
|
|
34
|
-
psid = -1.0j * (ham @ psi)
|
|
35
|
-
return psi, ham, psid
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@fixture
|
|
39
|
-
def rho_dot():
|
|
40
|
-
rho = qu.rand_rho(3)
|
|
41
|
-
ham = qu.rand_herm(3)
|
|
42
|
-
rhod = -1.0j * (ham @ rho - rho @ ham)
|
|
43
|
-
return rho, ham, rhod
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@fixture
|
|
47
|
-
def srho_dot():
|
|
48
|
-
rho = qu.rand_rho(3)
|
|
49
|
-
ham = qu.rand_herm(3, sparse=True, density=0.5)
|
|
50
|
-
rhod = -1.0j * (ham @ rho - rho @ ham)
|
|
51
|
-
return rho, ham, rhod
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
@fixture
|
|
55
|
-
def rho_dot_ls():
|
|
56
|
-
np.random.seed(1)
|
|
57
|
-
rho = qu.rand_rho(3)
|
|
58
|
-
ham = qu.rand_herm(3)
|
|
59
|
-
gamma = 0.7
|
|
60
|
-
ls = [qu.rand_matrix(3) for _ in range(3)]
|
|
61
|
-
rhodl = -1.0j * (ham @ rho - rho @ ham)
|
|
62
|
-
for l in ls:
|
|
63
|
-
rhodl += gamma * (l @ rho @ l.H)
|
|
64
|
-
rhodl -= gamma * 0.5 * (rho @ l.H @ l)
|
|
65
|
-
rhodl -= gamma * 0.5 * (l.H @ l @ rho)
|
|
66
|
-
return rho, ham, gamma, ls, rhodl
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@fixture
|
|
70
|
-
def srho_dot_ls():
|
|
71
|
-
rho = qu.rand_rho(3)
|
|
72
|
-
ham = qu.rand_herm(3, sparse=True, density=0.5)
|
|
73
|
-
gamma = 0.7
|
|
74
|
-
ls = [qu.rand_matrix(3, sparse=True, density=0.5) for _ in range(3)]
|
|
75
|
-
rhodl = -1.0j * (ham @ rho - rho @ ham)
|
|
76
|
-
for l in ls:
|
|
77
|
-
rhodl += gamma * (l @ rho @ l.H)
|
|
78
|
-
rhodl -= gamma * 0.5 * (rho @ l.H @ l)
|
|
79
|
-
rhodl -= gamma * 0.5 * (l.H @ l @ rho)
|
|
80
|
-
return rho, ham, gamma, ls, rhodl
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# --------------------------------------------------------------------------- #
|
|
84
|
-
# Evolution equation tests #
|
|
85
|
-
# --------------------------------------------------------------------------- #
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class TestSchrodingerEqKet:
|
|
89
|
-
def test_ket_matrix(self, psi_dot):
|
|
90
|
-
psi, ham, psid = psi_dot
|
|
91
|
-
foo = schrodinger_eq_ket(ham)
|
|
92
|
-
psid2 = foo(None, psi)
|
|
93
|
-
assert_allclose(psid, psid2)
|
|
94
|
-
|
|
95
|
-
def test_ket_1darray(self, psi_dot):
|
|
96
|
-
psi, ham, psid = psi_dot
|
|
97
|
-
foo = schrodinger_eq_ket(ham)
|
|
98
|
-
psid2 = foo(None, psi.toarray().reshape(-1)).reshape(-1, 1)
|
|
99
|
-
assert_allclose(psid, psid2)
|
|
100
|
-
|
|
101
|
-
def test_ket_matrix_sparse(self, spsi_dot):
|
|
102
|
-
psi, ham, psid = spsi_dot
|
|
103
|
-
foo = schrodinger_eq_ket(ham)
|
|
104
|
-
psid2 = foo(None, psi)
|
|
105
|
-
assert_allclose(psid, psid2)
|
|
106
|
-
|
|
107
|
-
def test_ket_1darray_sparse(self, spsi_dot):
|
|
108
|
-
psi, ham, psid = spsi_dot
|
|
109
|
-
foo = schrodinger_eq_ket(ham)
|
|
110
|
-
psid2 = foo(None, psi.toarray().reshape(-1)).reshape(-1, 1)
|
|
111
|
-
assert_allclose(psid, psid2)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
class TestSchrodingerEqDop:
|
|
115
|
-
def test_dop_matrix(self, rho_dot):
|
|
116
|
-
rho, ham, rhod = rho_dot
|
|
117
|
-
foo = schrodinger_eq_dop(ham)
|
|
118
|
-
rhod2 = foo(None, rho.toarray()).reshape(3, 3)
|
|
119
|
-
assert_allclose(rhod, rhod2)
|
|
120
|
-
|
|
121
|
-
def test_dop_1darray(self, rho_dot):
|
|
122
|
-
rho, ham, rhod = rho_dot
|
|
123
|
-
foo = schrodinger_eq_dop(ham)
|
|
124
|
-
rhod2 = foo(None, rho.toarray().reshape(-1)).reshape(3, 3)
|
|
125
|
-
assert_allclose(rhod, rhod2)
|
|
126
|
-
|
|
127
|
-
def test_dop_matrix_sparse(self, srho_dot):
|
|
128
|
-
rho, ham, rhod = srho_dot
|
|
129
|
-
foo = schrodinger_eq_dop(ham)
|
|
130
|
-
rhod2 = foo(None, rho.toarray()).reshape(3, 3)
|
|
131
|
-
assert_allclose(rhod, rhod2, atol=1e-12)
|
|
132
|
-
|
|
133
|
-
def test_dop_1darray_sparse(self, srho_dot):
|
|
134
|
-
rho, ham, rhod = srho_dot
|
|
135
|
-
foo = schrodinger_eq_dop(ham)
|
|
136
|
-
rhod2 = foo(None, rho.toarray().reshape(-1)).reshape(3, 3)
|
|
137
|
-
assert_allclose(rhod, rhod2, atol=1e-12)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
class TestSchrodingerEqDopVec:
|
|
141
|
-
def test_dop_1darray(self, rho_dot):
|
|
142
|
-
rho, ham, rhod = rho_dot
|
|
143
|
-
foo = schrodinger_eq_dop_vectorized(ham)
|
|
144
|
-
rhod2 = foo(None, rho.toarray().reshape(-1)).reshape(3, 3)
|
|
145
|
-
assert_allclose(rhod, rhod2)
|
|
146
|
-
|
|
147
|
-
def test_dop_1darray_sparse(self, srho_dot):
|
|
148
|
-
rho, ham, rhod = srho_dot
|
|
149
|
-
foo = schrodinger_eq_dop_vectorized(ham)
|
|
150
|
-
rhod2 = foo(None, rho.toarray().reshape(-1)).reshape(3, 3)
|
|
151
|
-
assert_allclose(rhod, rhod2, atol=1e-12)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
class TestLindbladEq:
|
|
155
|
-
def test_matrix(self, rho_dot_ls):
|
|
156
|
-
rho, ham, gamma, ls, rhod = rho_dot_ls
|
|
157
|
-
foo = lindblad_eq(ham, ls, gamma)
|
|
158
|
-
rhod2 = foo(None, rho).reshape(3, 3)
|
|
159
|
-
assert_allclose(rhod, rhod2)
|
|
160
|
-
|
|
161
|
-
def test_1darray(self, rho_dot_ls):
|
|
162
|
-
rho, ham, gamma, ls, rhod = rho_dot_ls
|
|
163
|
-
foo = lindblad_eq(ham, ls, gamma)
|
|
164
|
-
rhod2 = foo(None, rho.toarray().reshape(-1)).reshape(3, 3)
|
|
165
|
-
assert_allclose(rhod, rhod2)
|
|
166
|
-
|
|
167
|
-
def test_matrix_sparse(self, srho_dot_ls):
|
|
168
|
-
rho, ham, gamma, ls, rhod = srho_dot_ls
|
|
169
|
-
foo = lindblad_eq(ham, ls, gamma)
|
|
170
|
-
rhod2 = foo(None, rho).reshape(3, 3)
|
|
171
|
-
assert_allclose(rhod, rhod2)
|
|
172
|
-
|
|
173
|
-
def test_1darray_sparse(self, srho_dot_ls):
|
|
174
|
-
rho, ham, gamma, ls, rhod = srho_dot_ls
|
|
175
|
-
foo = lindblad_eq(ham, ls, gamma)
|
|
176
|
-
rhod2 = foo(None, rho.toarray().reshape(-1)).reshape(3, 3)
|
|
177
|
-
assert_allclose(rhod, rhod2)
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
class TestLindbladEqVec:
|
|
181
|
-
def test_1darray(self, rho_dot_ls):
|
|
182
|
-
rho, ham, gamma, ls, rhod = rho_dot_ls
|
|
183
|
-
foo = lindblad_eq_vectorized(ham, ls, gamma)
|
|
184
|
-
rhod2 = foo(None, rho.toarray().reshape(-1)).reshape(3, 3)
|
|
185
|
-
assert_allclose(rhod, rhod2)
|
|
186
|
-
|
|
187
|
-
def test_1darray_sparse(self, srho_dot_ls):
|
|
188
|
-
rho, ham, gamma, ls, rhod = srho_dot_ls
|
|
189
|
-
foo = lindblad_eq_vectorized(ham, ls, gamma)
|
|
190
|
-
rhod2 = foo(None, rho.toarray().reshape(-1)).reshape(3, 3)
|
|
191
|
-
assert_allclose(rhod, rhod2)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
# --------------------------------------------------------------------------- #
|
|
195
|
-
# Evolution class tests #
|
|
196
|
-
# --------------------------------------------------------------------------- #
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
@fixture
|
|
200
|
-
def ham_rcr_psi():
|
|
201
|
-
# Define a random hamiltonian with a known recurrence time
|
|
202
|
-
d = 3
|
|
203
|
-
np.random.seed(1)
|
|
204
|
-
ems = np.random.randint(1, 6, d)
|
|
205
|
-
ens = np.random.randint(1, 6, d) # eigenvalues as rational numbers
|
|
206
|
-
# numerator lowest common divisor
|
|
207
|
-
LCD = reduce(gcd, ems)
|
|
208
|
-
# denominator lowest common multiple
|
|
209
|
-
LCM = reduce(lambda a, b: a * b // gcd(a, b), ens)
|
|
210
|
-
trc = 2 * pi * LCM / LCD
|
|
211
|
-
evals = np.array(ems) / np.array(ens)
|
|
212
|
-
v = qu.rand_uni(d)
|
|
213
|
-
ham = v @ np.diag(evals) @ v.H
|
|
214
|
-
p0 = qu.rand_ket(d)
|
|
215
|
-
tm = 0.573 * trc
|
|
216
|
-
pm = v @ np.diag(np.exp(-1.0j * tm * evals)) @ v.H @ p0
|
|
217
|
-
return ham, trc, p0, tm, pm
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
class TestEvolution:
|
|
221
|
-
@mark.parametrize(
|
|
222
|
-
"sparse, presolve", [(False, False), (True, False), (False, True)]
|
|
223
|
-
)
|
|
224
|
-
def test_evo_ham_dense_ket_solve(self, ham_rcr_psi, sparse, presolve):
|
|
225
|
-
ham, trc, p0, tm, pm = ham_rcr_psi
|
|
226
|
-
ham = qu.qu(ham, sparse=sparse)
|
|
227
|
-
if presolve:
|
|
228
|
-
l, v = qu.eigh(ham)
|
|
229
|
-
sim = qu.Evolution(p0, (l, v))
|
|
230
|
-
assert isinstance(sim._ham, tuple) and len(sim._ham) == 2
|
|
231
|
-
else:
|
|
232
|
-
sim = qu.Evolution(p0, ham, method="solve")
|
|
233
|
-
sim.update_to(tm)
|
|
234
|
-
assert_allclose(sim.pt, pm)
|
|
235
|
-
assert qu.expec(sim.pt, p0) < 1.0
|
|
236
|
-
sim.update_to(trc)
|
|
237
|
-
assert_allclose(sim.pt, p0)
|
|
238
|
-
assert isinstance(sim.pt, qu.qarray)
|
|
239
|
-
assert sim.t == trc
|
|
240
|
-
|
|
241
|
-
@mark.parametrize("dop", [False, True])
|
|
242
|
-
@mark.parametrize("sparse", [False, True])
|
|
243
|
-
@mark.parametrize("method", ["solve", "integrate", "expm", "bad"])
|
|
244
|
-
@mark.parametrize("timedep", [False, True])
|
|
245
|
-
@mark.parametrize("linop", [False, True])
|
|
246
|
-
def test_evo_ham(self, ham_rcr_psi, sparse, dop, method, timedep, linop):
|
|
247
|
-
ham, trc, p0, tm, pm = ham_rcr_psi
|
|
248
|
-
if dop:
|
|
249
|
-
if method == "expm":
|
|
250
|
-
# XXX: not implemented
|
|
251
|
-
return
|
|
252
|
-
p0 = p0 @ p0.H
|
|
253
|
-
pm = pm @ pm.H
|
|
254
|
-
|
|
255
|
-
if method == "bad":
|
|
256
|
-
with raises(ValueError):
|
|
257
|
-
qu.Evolution(p0, ham, method=method)
|
|
258
|
-
return
|
|
259
|
-
|
|
260
|
-
ham = qu.qu(ham, sparse=sparse)
|
|
261
|
-
|
|
262
|
-
if linop:
|
|
263
|
-
import scipy.sparse.linalg as spla
|
|
264
|
-
|
|
265
|
-
ham = spla.aslinearoperator(ham)
|
|
266
|
-
|
|
267
|
-
if timedep:
|
|
268
|
-
# fake a time dependent ham by making it callable
|
|
269
|
-
ham_object, ham = ham, (lambda t: ham_object)
|
|
270
|
-
|
|
271
|
-
if linop and (method in ("expm", "solve")):
|
|
272
|
-
with raises(TypeError):
|
|
273
|
-
qu.Evolution(p0, ham, method=method)
|
|
274
|
-
return
|
|
275
|
-
|
|
276
|
-
if timedep and (method in ("expm", "solve")):
|
|
277
|
-
with raises(TypeError):
|
|
278
|
-
qu.Evolution(p0, ham, method=method)
|
|
279
|
-
return
|
|
280
|
-
|
|
281
|
-
sim = qu.Evolution(p0, ham, method=method)
|
|
282
|
-
sim.update_to(tm)
|
|
283
|
-
assert_allclose(sim.pt, pm, rtol=1e-4, atol=1e-6)
|
|
284
|
-
assert qu.expec(sim.pt, p0) < 1.0
|
|
285
|
-
sim.update_to(trc)
|
|
286
|
-
assert_allclose(sim.pt, p0, rtol=1e-4, atol=1e-6)
|
|
287
|
-
assert isinstance(sim.pt, qu.qarray)
|
|
288
|
-
assert sim.t == trc
|
|
289
|
-
|
|
290
|
-
@mark.parametrize("dop", [False, True])
|
|
291
|
-
@mark.parametrize("linop", [False, True])
|
|
292
|
-
@mark.parametrize("num_callbacks", [0, 1, 2])
|
|
293
|
-
@mark.parametrize("use_int_stop", [False, True])
|
|
294
|
-
def test_evo_timedep_adiabatic_with_callbacks(
|
|
295
|
-
self, dop, linop, num_callbacks, use_int_stop
|
|
296
|
-
):
|
|
297
|
-
# tests time dependent Evolution via an adiabatic sweep with:
|
|
298
|
-
# a) no callbacks
|
|
299
|
-
# b) 1 callback that accesses the time-dependent Hamiltonian
|
|
300
|
-
# c) 2 callbacks where one access the Hamiltonian and one doesn't
|
|
301
|
-
|
|
302
|
-
if num_callbacks > 0 and (dop or linop):
|
|
303
|
-
# should implement this at some point
|
|
304
|
-
return
|
|
305
|
-
|
|
306
|
-
L = 6
|
|
307
|
-
T = 20
|
|
308
|
-
|
|
309
|
-
H1 = qu.ham_mbl(L, dh=1.0, seed=4, sparse=True, cyclic=True)
|
|
310
|
-
gs1 = qu.groundstate(H1)
|
|
311
|
-
H2 = qu.ham_mbl(L, dh=1.0, seed=5, sparse=True, cyclic=True)
|
|
312
|
-
gs2 = qu.groundstate(H2)
|
|
313
|
-
|
|
314
|
-
if linop:
|
|
315
|
-
import scipy.sparse.linalg as spla
|
|
316
|
-
|
|
317
|
-
H1 = spla.aslinearoperator(H1)
|
|
318
|
-
H2 = spla.aslinearoperator(H2)
|
|
319
|
-
|
|
320
|
-
# make sure two ground states are different
|
|
321
|
-
assert qu.fidelity(gs1, gs2) < 0.5
|
|
322
|
-
|
|
323
|
-
# linearly interpolate from one ham to the other
|
|
324
|
-
def ham(t):
|
|
325
|
-
return (1 - t / T) * H1 + (t / T) * H2
|
|
326
|
-
|
|
327
|
-
if linop:
|
|
328
|
-
assert isinstance(ham(0.3), spla.LinearOperator)
|
|
329
|
-
|
|
330
|
-
if dop:
|
|
331
|
-
p0 = qu.dop(gs1)
|
|
332
|
-
else:
|
|
333
|
-
p0 = gs1
|
|
334
|
-
|
|
335
|
-
if use_int_stop:
|
|
336
|
-
|
|
337
|
-
def check_init_gs_overlap(t, pt):
|
|
338
|
-
val = qu.fidelity(pt, gs1)
|
|
339
|
-
return -1 if val <= 0.75 else 0
|
|
340
|
-
|
|
341
|
-
int_stop = check_init_gs_overlap
|
|
342
|
-
else:
|
|
343
|
-
int_stop = None
|
|
344
|
-
|
|
345
|
-
if num_callbacks == 0:
|
|
346
|
-
evo = qu.Evolution(
|
|
347
|
-
p0, ham, method="integrate", int_stop=int_stop, progbar=True
|
|
348
|
-
)
|
|
349
|
-
else:
|
|
350
|
-
|
|
351
|
-
def gs_overlap(t, pt, H):
|
|
352
|
-
evals, evecs = eigs_scipy(H(t), k=1, which="SA")
|
|
353
|
-
return np.abs(qu.dot(pt.T, qu.qu(evecs[:, 0]))) ** 2
|
|
354
|
-
|
|
355
|
-
if num_callbacks == 1:
|
|
356
|
-
compute = gs_overlap
|
|
357
|
-
if num_callbacks == 2:
|
|
358
|
-
|
|
359
|
-
def norm(t, pt):
|
|
360
|
-
return qu.dot(pt.T, pt)
|
|
361
|
-
|
|
362
|
-
compute = {"norm": norm, "gs_overlap": gs_overlap}
|
|
363
|
-
evo = qu.Evolution(
|
|
364
|
-
p0,
|
|
365
|
-
ham,
|
|
366
|
-
compute=compute,
|
|
367
|
-
int_stop=int_stop,
|
|
368
|
-
method="integrate",
|
|
369
|
-
progbar=True,
|
|
370
|
-
)
|
|
371
|
-
evo.update_to(T)
|
|
372
|
-
|
|
373
|
-
# final state should now overlap much more with second hamiltonian GS
|
|
374
|
-
if use_int_stop:
|
|
375
|
-
assert qu.fidelity(evo.pt, gs1) < 0.9
|
|
376
|
-
assert qu.fidelity(evo.pt, gs2) > 0.1
|
|
377
|
-
assert evo.t < 15
|
|
378
|
-
else:
|
|
379
|
-
assert qu.fidelity(evo.pt, gs1) < 0.5
|
|
380
|
-
assert qu.fidelity(evo.pt, gs2) > 0.99
|
|
381
|
-
assert evo.t == 20
|
|
382
|
-
|
|
383
|
-
if num_callbacks == 1:
|
|
384
|
-
gs_overlap_results = evo.results
|
|
385
|
-
# check that we stayed in the ground state the whole time
|
|
386
|
-
assert ((np.array(gs_overlap_results) - 1.0) < 1e-3).all()
|
|
387
|
-
|
|
388
|
-
if num_callbacks == 2:
|
|
389
|
-
norm_results = evo.results["norm"]
|
|
390
|
-
gs_overlap_results = evo.results["gs_overlap"]
|
|
391
|
-
# check that we stayed normalized the whole time
|
|
392
|
-
assert ((np.array(norm_results) - 1.0) < 1e-3).all()
|
|
393
|
-
# check that we stayed in the ground state the whole time
|
|
394
|
-
assert ((np.array(gs_overlap_results) - 1.0) < 1e-3).all()
|
|
395
|
-
|
|
396
|
-
def test_int_stop_calling_details(self, ham_rcr_psi):
|
|
397
|
-
import platform
|
|
398
|
-
|
|
399
|
-
if platform.system() == "Darwin":
|
|
400
|
-
skip("Skipping test on macOS")
|
|
401
|
-
|
|
402
|
-
# test some details about the way Evolution is called with int_stop:
|
|
403
|
-
# - Giving int_stop without any compute
|
|
404
|
-
# - Giving int_stop with (t, p) and with (t, p, H) call signatures
|
|
405
|
-
ham, trc, p0, tm, pm = ham_rcr_psi
|
|
406
|
-
|
|
407
|
-
# check that the int_stop argument doesn't get accepted in either form
|
|
408
|
-
with raises(ValueError):
|
|
409
|
-
qu.Evolution(p0, ham, method="solve", int_stop=(lambda t, p: -1))
|
|
410
|
-
with raises(ValueError):
|
|
411
|
-
qu.Evolution(
|
|
412
|
-
p0, ham, method="solve", int_stop=(lambda t, p, H: -1)
|
|
413
|
-
)
|
|
414
|
-
|
|
415
|
-
# check expected behaviour in case where int_stop takes t, p
|
|
416
|
-
sim = qu.Evolution(
|
|
417
|
-
p0, ham, method="integrate", int_stop=(lambda t, p: -1)
|
|
418
|
-
)
|
|
419
|
-
sim.update_to(trc)
|
|
420
|
-
assert sim.t < trc / 2 # make sure it stopped early
|
|
421
|
-
|
|
422
|
-
sim = qu.Evolution(
|
|
423
|
-
p0, ham, method="integrate", int_stop=(lambda t, p: 0)
|
|
424
|
-
)
|
|
425
|
-
sim.update_to(trc)
|
|
426
|
-
assert sim.t == trc # make sure it didn't stop early
|
|
427
|
-
|
|
428
|
-
sim = qu.Evolution(
|
|
429
|
-
p0, ham, method="integrate", int_stop=(lambda t, p, H: -1)
|
|
430
|
-
)
|
|
431
|
-
|
|
432
|
-
# check expected behaviour in case where int_stop takes t, p, H
|
|
433
|
-
sim.update_to(trc)
|
|
434
|
-
assert sim.t < trc / 2 # make sure it stopped early
|
|
435
|
-
|
|
436
|
-
sim = qu.Evolution(
|
|
437
|
-
p0, ham, method="integrate", int_stop=(lambda t, p, H: 0)
|
|
438
|
-
)
|
|
439
|
-
sim.update_to(trc)
|
|
440
|
-
assert sim.t == trc # make sure it didn't stop early
|
|
441
|
-
|
|
442
|
-
# check that TypeError not related to argument count gets properly
|
|
443
|
-
# raised
|
|
444
|
-
with raises(TypeError):
|
|
445
|
-
|
|
446
|
-
def int_step(t, p, H):
|
|
447
|
-
raise TypeError("Something else.")
|
|
448
|
-
|
|
449
|
-
sim = qu.Evolution(p0, ham, method="integrate", int_stop=int_step)
|
|
450
|
-
sim.update_to(trc)
|
|
451
|
-
|
|
452
|
-
def test_evo_at_times(self):
|
|
453
|
-
ham = qu.ham_heis(2, cyclic=False)
|
|
454
|
-
p0 = qu.up() & qu.down()
|
|
455
|
-
sim = qu.Evolution(p0, ham, method="solve")
|
|
456
|
-
ts = np.linspace(0, 10)
|
|
457
|
-
for t, pt in zip(ts, sim.at_times(ts)):
|
|
458
|
-
x = cos(t)
|
|
459
|
-
y = qu.expec(pt, qu.ikron(qu.pauli("z"), [2, 2], 0))
|
|
460
|
-
assert_allclose(x, y, atol=1e-15)
|
|
461
|
-
|
|
462
|
-
@mark.parametrize("qtype", ["ket", "dop"])
|
|
463
|
-
@mark.parametrize("method", ["solve", "integrate", "expm"])
|
|
464
|
-
def test_evo_compute_callback(self, qtype, method):
|
|
465
|
-
ham = qu.ham_heis(2, cyclic=False)
|
|
466
|
-
p0 = qu.qu(qu.up() & qu.down(), qtype=qtype)
|
|
467
|
-
|
|
468
|
-
def some_quantity(t, pt):
|
|
469
|
-
return t, qu.logneg(pt)
|
|
470
|
-
|
|
471
|
-
evo = qu.Evolution(p0, ham, method=method, compute=some_quantity)
|
|
472
|
-
manual_lns = []
|
|
473
|
-
for pt in evo.at_times(np.linspace(0, 1, 6)):
|
|
474
|
-
manual_lns.append(qu.logneg(pt))
|
|
475
|
-
ts, lns = zip(*evo.results)
|
|
476
|
-
assert len(lns) >= len(manual_lns)
|
|
477
|
-
# check a specific value of logneg at t=0.8 was computed automatically
|
|
478
|
-
checked = False
|
|
479
|
-
for t, ln in zip(ts, lns):
|
|
480
|
-
if abs(t - 0.8) < 1e-12:
|
|
481
|
-
assert abs(ln - manual_lns[4]) < 1e-12
|
|
482
|
-
checked = True
|
|
483
|
-
assert checked
|
|
484
|
-
|
|
485
|
-
@mark.parametrize("qtype", ["ket", "dop"])
|
|
486
|
-
@mark.parametrize("method", ["solve", "integrate", "expm"])
|
|
487
|
-
def test_evo_multi_compute(self, method, qtype):
|
|
488
|
-
ham = qu.ham_heis(2, cyclic=False)
|
|
489
|
-
p0 = qu.qu(qu.up() & qu.down(), qtype=qtype)
|
|
490
|
-
|
|
491
|
-
def some_quantity(t, _):
|
|
492
|
-
return t
|
|
493
|
-
|
|
494
|
-
def some_other_quantity(_, pt):
|
|
495
|
-
return qu.logneg(pt)
|
|
496
|
-
|
|
497
|
-
# check that hamiltonian gets accepted without error for all methods
|
|
498
|
-
def some_other_quantity_accepting_ham(t, pt, H):
|
|
499
|
-
return qu.logneg(pt)
|
|
500
|
-
|
|
501
|
-
compute = {
|
|
502
|
-
"t": some_quantity,
|
|
503
|
-
"logneg": some_other_quantity,
|
|
504
|
-
"logneg_ham": some_other_quantity_accepting_ham,
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
evo = qu.Evolution(p0, ham, method=method, compute=compute)
|
|
508
|
-
manual_lns = []
|
|
509
|
-
for pt in evo.at_times(np.linspace(0, 1, 6)):
|
|
510
|
-
manual_lns.append(qu.logneg(pt))
|
|
511
|
-
ts = evo.results["t"]
|
|
512
|
-
lns = evo.results["logneg"]
|
|
513
|
-
lns_ham = evo.results["logneg_ham"]
|
|
514
|
-
assert len(lns) >= len(manual_lns)
|
|
515
|
-
# check a specific value of logneg at t=0.8 was computed automatically
|
|
516
|
-
checked = False
|
|
517
|
-
for t, ln, ln_ham in zip(ts, lns, lns_ham):
|
|
518
|
-
if abs(t - 0.8) < 1e-12:
|
|
519
|
-
assert abs(ln - manual_lns[4]) < 1e-12
|
|
520
|
-
# check that accepting hamiltonian didn't mess it up
|
|
521
|
-
assert ln == ln_ham
|
|
522
|
-
checked = True
|
|
523
|
-
assert checked
|
|
524
|
-
|
|
525
|
-
@slepc4py_test
|
|
526
|
-
@mark.parametrize("expm_backend", ["slepc-krylov", "slepc-expokit"])
|
|
527
|
-
def test_expm_slepc(self, expm_backend):
|
|
528
|
-
ham = qu.ham_mbl(7, dh=0.5, sparse=True)
|
|
529
|
-
psi = qu.rand_ket(2**7)
|
|
530
|
-
evo_exact = qu.Evolution(psi, ham, method="solve")
|
|
531
|
-
evo_slepc = qu.Evolution(
|
|
532
|
-
psi, ham, method="expm", expm_backend=expm_backend
|
|
533
|
-
)
|
|
534
|
-
ts = np.linspace(0, 100, 6)
|
|
535
|
-
for p1, p2 in zip(evo_exact.at_times(ts), evo_slepc.at_times(ts)):
|
|
536
|
-
assert abs(qu.expec(p1, p2) - 1) < 1e-9
|
|
537
|
-
|
|
538
|
-
def test_progbar_update_to_integrate(self, capsys):
|
|
539
|
-
ham = qu.ham_heis(2, cyclic=False)
|
|
540
|
-
p0 = qu.up() & qu.down()
|
|
541
|
-
sim = qu.Evolution(p0, ham, method="integrate", progbar=True)
|
|
542
|
-
sim.update_to(100)
|
|
543
|
-
# check something as been printed
|
|
544
|
-
_, err = capsys.readouterr()
|
|
545
|
-
assert err and "%" in err
|
|
546
|
-
|
|
547
|
-
def test_progbar_at_times_solve(self, capsys):
|
|
548
|
-
ham = qu.ham_heis(2, cyclic=False)
|
|
549
|
-
p0 = qu.up() & qu.down()
|
|
550
|
-
sim = qu.Evolution(p0, ham, method="solve", progbar=True)
|
|
551
|
-
for _ in sim.at_times(np.linspace(0, 100, 11)):
|
|
552
|
-
pass
|
|
553
|
-
# check something as been printed
|
|
554
|
-
_, err = capsys.readouterr()
|
|
555
|
-
assert err and "%" in err
|
|
556
|
-
|
|
557
|
-
def test_progbar_at_times_expm(self, capsys):
|
|
558
|
-
ham = qu.ham_heis(2, cyclic=False)
|
|
559
|
-
p0 = qu.up() & qu.down()
|
|
560
|
-
sim = qu.Evolution(p0, ham, method="expm", progbar=True)
|
|
561
|
-
for _ in sim.at_times(np.linspace(0, 100, 11)):
|
|
562
|
-
pass
|
|
563
|
-
# check something as been printed
|
|
564
|
-
_, err = capsys.readouterr()
|
|
565
|
-
assert err and "%" in err
|
|
File without changes
|