Trajectree 0.0.1__py3-none-any.whl → 0.0.2__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.
Files changed (122) hide show
  1. trajectree/__init__.py +0 -3
  2. trajectree/fock_optics/devices.py +1 -1
  3. trajectree/fock_optics/light_sources.py +2 -2
  4. trajectree/fock_optics/measurement.py +3 -3
  5. trajectree/fock_optics/utils.py +6 -6
  6. trajectree/trajectory.py +2 -2
  7. {trajectree-0.0.1.dist-info → trajectree-0.0.2.dist-info}/METADATA +2 -3
  8. trajectree-0.0.2.dist-info/RECORD +16 -0
  9. trajectree/quimb/docs/_pygments/_pygments_dark.py +0 -118
  10. trajectree/quimb/docs/_pygments/_pygments_light.py +0 -118
  11. trajectree/quimb/docs/conf.py +0 -158
  12. trajectree/quimb/docs/examples/ex_mpi_expm_evo.py +0 -62
  13. trajectree/quimb/quimb/__init__.py +0 -507
  14. trajectree/quimb/quimb/calc.py +0 -1491
  15. trajectree/quimb/quimb/core.py +0 -2279
  16. trajectree/quimb/quimb/evo.py +0 -712
  17. trajectree/quimb/quimb/experimental/__init__.py +0 -0
  18. trajectree/quimb/quimb/experimental/autojittn.py +0 -129
  19. trajectree/quimb/quimb/experimental/belief_propagation/__init__.py +0 -109
  20. trajectree/quimb/quimb/experimental/belief_propagation/bp_common.py +0 -397
  21. trajectree/quimb/quimb/experimental/belief_propagation/d1bp.py +0 -316
  22. trajectree/quimb/quimb/experimental/belief_propagation/d2bp.py +0 -653
  23. trajectree/quimb/quimb/experimental/belief_propagation/hd1bp.py +0 -571
  24. trajectree/quimb/quimb/experimental/belief_propagation/hv1bp.py +0 -775
  25. trajectree/quimb/quimb/experimental/belief_propagation/l1bp.py +0 -316
  26. trajectree/quimb/quimb/experimental/belief_propagation/l2bp.py +0 -537
  27. trajectree/quimb/quimb/experimental/belief_propagation/regions.py +0 -194
  28. trajectree/quimb/quimb/experimental/cluster_update.py +0 -286
  29. trajectree/quimb/quimb/experimental/merabuilder.py +0 -865
  30. trajectree/quimb/quimb/experimental/operatorbuilder/__init__.py +0 -15
  31. trajectree/quimb/quimb/experimental/operatorbuilder/operatorbuilder.py +0 -1631
  32. trajectree/quimb/quimb/experimental/schematic.py +0 -7
  33. trajectree/quimb/quimb/experimental/tn_marginals.py +0 -130
  34. trajectree/quimb/quimb/experimental/tnvmc.py +0 -1483
  35. trajectree/quimb/quimb/gates.py +0 -36
  36. trajectree/quimb/quimb/gen/__init__.py +0 -2
  37. trajectree/quimb/quimb/gen/operators.py +0 -1167
  38. trajectree/quimb/quimb/gen/rand.py +0 -713
  39. trajectree/quimb/quimb/gen/states.py +0 -479
  40. trajectree/quimb/quimb/linalg/__init__.py +0 -6
  41. trajectree/quimb/quimb/linalg/approx_spectral.py +0 -1109
  42. trajectree/quimb/quimb/linalg/autoblock.py +0 -258
  43. trajectree/quimb/quimb/linalg/base_linalg.py +0 -719
  44. trajectree/quimb/quimb/linalg/mpi_launcher.py +0 -397
  45. trajectree/quimb/quimb/linalg/numpy_linalg.py +0 -244
  46. trajectree/quimb/quimb/linalg/rand_linalg.py +0 -514
  47. trajectree/quimb/quimb/linalg/scipy_linalg.py +0 -293
  48. trajectree/quimb/quimb/linalg/slepc_linalg.py +0 -892
  49. trajectree/quimb/quimb/schematic.py +0 -1518
  50. trajectree/quimb/quimb/tensor/__init__.py +0 -401
  51. trajectree/quimb/quimb/tensor/array_ops.py +0 -610
  52. trajectree/quimb/quimb/tensor/circuit.py +0 -4824
  53. trajectree/quimb/quimb/tensor/circuit_gen.py +0 -411
  54. trajectree/quimb/quimb/tensor/contraction.py +0 -336
  55. trajectree/quimb/quimb/tensor/decomp.py +0 -1255
  56. trajectree/quimb/quimb/tensor/drawing.py +0 -1646
  57. trajectree/quimb/quimb/tensor/fitting.py +0 -385
  58. trajectree/quimb/quimb/tensor/geometry.py +0 -583
  59. trajectree/quimb/quimb/tensor/interface.py +0 -114
  60. trajectree/quimb/quimb/tensor/networking.py +0 -1058
  61. trajectree/quimb/quimb/tensor/optimize.py +0 -1818
  62. trajectree/quimb/quimb/tensor/tensor_1d.py +0 -4778
  63. trajectree/quimb/quimb/tensor/tensor_1d_compress.py +0 -1854
  64. trajectree/quimb/quimb/tensor/tensor_1d_tebd.py +0 -662
  65. trajectree/quimb/quimb/tensor/tensor_2d.py +0 -5954
  66. trajectree/quimb/quimb/tensor/tensor_2d_compress.py +0 -96
  67. trajectree/quimb/quimb/tensor/tensor_2d_tebd.py +0 -1230
  68. trajectree/quimb/quimb/tensor/tensor_3d.py +0 -2869
  69. trajectree/quimb/quimb/tensor/tensor_3d_tebd.py +0 -46
  70. trajectree/quimb/quimb/tensor/tensor_approx_spectral.py +0 -60
  71. trajectree/quimb/quimb/tensor/tensor_arbgeom.py +0 -3237
  72. trajectree/quimb/quimb/tensor/tensor_arbgeom_compress.py +0 -565
  73. trajectree/quimb/quimb/tensor/tensor_arbgeom_tebd.py +0 -1138
  74. trajectree/quimb/quimb/tensor/tensor_builder.py +0 -5411
  75. trajectree/quimb/quimb/tensor/tensor_core.py +0 -11179
  76. trajectree/quimb/quimb/tensor/tensor_dmrg.py +0 -1472
  77. trajectree/quimb/quimb/tensor/tensor_mera.py +0 -204
  78. trajectree/quimb/quimb/utils.py +0 -892
  79. trajectree/quimb/tests/__init__.py +0 -0
  80. trajectree/quimb/tests/test_accel.py +0 -501
  81. trajectree/quimb/tests/test_calc.py +0 -788
  82. trajectree/quimb/tests/test_core.py +0 -847
  83. trajectree/quimb/tests/test_evo.py +0 -565
  84. trajectree/quimb/tests/test_gen/__init__.py +0 -0
  85. trajectree/quimb/tests/test_gen/test_operators.py +0 -361
  86. trajectree/quimb/tests/test_gen/test_rand.py +0 -296
  87. trajectree/quimb/tests/test_gen/test_states.py +0 -261
  88. trajectree/quimb/tests/test_linalg/__init__.py +0 -0
  89. trajectree/quimb/tests/test_linalg/test_approx_spectral.py +0 -368
  90. trajectree/quimb/tests/test_linalg/test_base_linalg.py +0 -351
  91. trajectree/quimb/tests/test_linalg/test_mpi_linalg.py +0 -127
  92. trajectree/quimb/tests/test_linalg/test_numpy_linalg.py +0 -84
  93. trajectree/quimb/tests/test_linalg/test_rand_linalg.py +0 -134
  94. trajectree/quimb/tests/test_linalg/test_slepc_linalg.py +0 -283
  95. trajectree/quimb/tests/test_tensor/__init__.py +0 -0
  96. trajectree/quimb/tests/test_tensor/test_belief_propagation/__init__.py +0 -0
  97. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_d1bp.py +0 -39
  98. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_d2bp.py +0 -67
  99. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_hd1bp.py +0 -64
  100. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_hv1bp.py +0 -51
  101. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_l1bp.py +0 -142
  102. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_l2bp.py +0 -101
  103. trajectree/quimb/tests/test_tensor/test_circuit.py +0 -816
  104. trajectree/quimb/tests/test_tensor/test_contract.py +0 -67
  105. trajectree/quimb/tests/test_tensor/test_decomp.py +0 -40
  106. trajectree/quimb/tests/test_tensor/test_mera.py +0 -52
  107. trajectree/quimb/tests/test_tensor/test_optimizers.py +0 -488
  108. trajectree/quimb/tests/test_tensor/test_tensor_1d.py +0 -1171
  109. trajectree/quimb/tests/test_tensor/test_tensor_2d.py +0 -606
  110. trajectree/quimb/tests/test_tensor/test_tensor_2d_tebd.py +0 -144
  111. trajectree/quimb/tests/test_tensor/test_tensor_3d.py +0 -123
  112. trajectree/quimb/tests/test_tensor/test_tensor_arbgeom.py +0 -226
  113. trajectree/quimb/tests/test_tensor/test_tensor_builder.py +0 -441
  114. trajectree/quimb/tests/test_tensor/test_tensor_core.py +0 -2066
  115. trajectree/quimb/tests/test_tensor/test_tensor_dmrg.py +0 -388
  116. trajectree/quimb/tests/test_tensor/test_tensor_spectral_approx.py +0 -63
  117. trajectree/quimb/tests/test_tensor/test_tensor_tebd.py +0 -270
  118. trajectree/quimb/tests/test_utils.py +0 -85
  119. trajectree-0.0.1.dist-info/RECORD +0 -126
  120. {trajectree-0.0.1.dist-info → trajectree-0.0.2.dist-info}/WHEEL +0 -0
  121. {trajectree-0.0.1.dist-info → trajectree-0.0.2.dist-info}/licenses/LICENSE +0 -0
  122. {trajectree-0.0.1.dist-info → trajectree-0.0.2.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