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,388 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
from numpy.testing import assert_allclose
|
|
5
|
-
|
|
6
|
-
from quimb import (
|
|
7
|
-
ham_heis,
|
|
8
|
-
expec,
|
|
9
|
-
plus,
|
|
10
|
-
is_eigenvector,
|
|
11
|
-
eigh,
|
|
12
|
-
heisenberg_energy,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
from quimb.tensor import (
|
|
16
|
-
MPS_rand_state,
|
|
17
|
-
MPS_product_state,
|
|
18
|
-
MPS_computational_state,
|
|
19
|
-
MPO_ham_ising,
|
|
20
|
-
MPO_ham_XY,
|
|
21
|
-
MPO_ham_heis,
|
|
22
|
-
MPO_ham_mbl,
|
|
23
|
-
MovingEnvironment,
|
|
24
|
-
DMRG1,
|
|
25
|
-
DMRG2,
|
|
26
|
-
DMRGX,
|
|
27
|
-
SpinHam1D,
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
np.random.seed(42)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class TestMovingEnvironment:
|
|
35
|
-
def test_bsz1_start_left(self):
|
|
36
|
-
tn = MPS_rand_state(6, bond_dim=7)
|
|
37
|
-
env = MovingEnvironment(tn, begin="left", bsz=1)
|
|
38
|
-
assert env.pos == 0
|
|
39
|
-
assert len(env().tensors) == 3
|
|
40
|
-
env.move_right()
|
|
41
|
-
assert env.pos == 1
|
|
42
|
-
assert len(env().tensors) == 3
|
|
43
|
-
env.move_right()
|
|
44
|
-
assert env.pos == 2
|
|
45
|
-
assert len(env().tensors) == 3
|
|
46
|
-
env.move_to(5)
|
|
47
|
-
assert env.pos == 5
|
|
48
|
-
assert len(env().tensors) == 3
|
|
49
|
-
|
|
50
|
-
def test_bsz1_start_right(self):
|
|
51
|
-
tn = MPS_rand_state(6, bond_dim=7)
|
|
52
|
-
env = MovingEnvironment(tn, begin="right", bsz=1)
|
|
53
|
-
assert env.pos == 5
|
|
54
|
-
assert len(env().tensors) == 3
|
|
55
|
-
env.move_left()
|
|
56
|
-
assert env.pos == 4
|
|
57
|
-
assert len(env().tensors) == 3
|
|
58
|
-
env.move_left()
|
|
59
|
-
assert env.pos == 3
|
|
60
|
-
assert len(env().tensors) == 3
|
|
61
|
-
env.move_to(0)
|
|
62
|
-
assert env.pos == 0
|
|
63
|
-
assert len(env().tensors) == 3
|
|
64
|
-
|
|
65
|
-
def test_bsz2_start_left(self):
|
|
66
|
-
tn = MPS_rand_state(6, bond_dim=7)
|
|
67
|
-
env = MovingEnvironment(tn, begin="left", bsz=2)
|
|
68
|
-
assert len(env().tensors) == 4
|
|
69
|
-
env.move_right()
|
|
70
|
-
assert len(env().tensors) == 4
|
|
71
|
-
env.move_right()
|
|
72
|
-
assert len(env().tensors) == 4
|
|
73
|
-
with pytest.raises(ValueError):
|
|
74
|
-
env.move_to(5)
|
|
75
|
-
env.move_to(4)
|
|
76
|
-
assert env.pos == 4
|
|
77
|
-
assert len(env().tensors) == 4
|
|
78
|
-
|
|
79
|
-
def test_bsz2_start_right(self):
|
|
80
|
-
tn = MPS_rand_state(6, bond_dim=7)
|
|
81
|
-
env = MovingEnvironment(tn, begin="right", bsz=2)
|
|
82
|
-
assert env.pos == 4
|
|
83
|
-
assert len(env().tensors) == 4
|
|
84
|
-
env.move_left()
|
|
85
|
-
assert env.pos == 3
|
|
86
|
-
assert len(env().tensors) == 4
|
|
87
|
-
env.move_left()
|
|
88
|
-
assert env.pos == 2
|
|
89
|
-
assert len(env().tensors) == 4
|
|
90
|
-
with pytest.raises(ValueError):
|
|
91
|
-
env.move_to(-1)
|
|
92
|
-
env.move_to(0)
|
|
93
|
-
assert env.pos == 0
|
|
94
|
-
assert len(env().tensors) == 4
|
|
95
|
-
|
|
96
|
-
@pytest.mark.parametrize("n", [20, 19])
|
|
97
|
-
@pytest.mark.parametrize("bsz", [1, 2])
|
|
98
|
-
@pytest.mark.parametrize("ssz", [1 / 2, 1.0])
|
|
99
|
-
def test_cyclic_moving_env_init_left(self, n, bsz, ssz):
|
|
100
|
-
nenv = 2
|
|
101
|
-
p = MPS_rand_state(n, 4, cyclic=True)
|
|
102
|
-
norm = p.H & p
|
|
103
|
-
mes = MovingEnvironment(
|
|
104
|
-
norm, begin="left", bsz=bsz, cyclic=True, ssz=ssz
|
|
105
|
-
)
|
|
106
|
-
assert len(mes.envs) == n // 2 + n % 2
|
|
107
|
-
assert mes.pos == 0
|
|
108
|
-
assert len(mes.envs[0].tensors) == 2 * bsz + nenv
|
|
109
|
-
assert len(mes.envs[n // 2 - 1].tensors) == 2 * bsz + 1
|
|
110
|
-
assert n // 2 + n % 2 not in mes.envs
|
|
111
|
-
assert n - 1 not in mes.envs
|
|
112
|
-
|
|
113
|
-
for i in range(1, 2 * n):
|
|
114
|
-
mes.move_right()
|
|
115
|
-
assert mes.pos == i % n
|
|
116
|
-
cur_env = mes()
|
|
117
|
-
assert len(cur_env.tensors) == 2 * bsz + nenv
|
|
118
|
-
assert (cur_env ^ all) == pytest.approx(1.0)
|
|
119
|
-
|
|
120
|
-
@pytest.mark.parametrize("n", [20, 19])
|
|
121
|
-
@pytest.mark.parametrize("bsz", [1, 2])
|
|
122
|
-
@pytest.mark.parametrize("ssz", [1 / 2, 1.0])
|
|
123
|
-
def test_cyclic_moving_env_init_right(self, n, bsz, ssz):
|
|
124
|
-
p = MPS_rand_state(n, 4, cyclic=True)
|
|
125
|
-
norm = p.H | p
|
|
126
|
-
mes = MovingEnvironment(
|
|
127
|
-
norm, begin="right", bsz=bsz, cyclic=True, ssz=ssz
|
|
128
|
-
)
|
|
129
|
-
assert len(mes.envs) == n // 2 + n % 2
|
|
130
|
-
assert mes.pos == n - 1
|
|
131
|
-
assert len(mes.envs[n - 1].tensors) == 2 * bsz + 2
|
|
132
|
-
assert len(mes.envs[n - n // 2].tensors) == 2 * bsz + 1
|
|
133
|
-
assert 0 not in mes.envs
|
|
134
|
-
assert n // 2 - 1 not in mes.envs
|
|
135
|
-
|
|
136
|
-
for i in reversed(range(-n, n - 1)):
|
|
137
|
-
mes.move_left()
|
|
138
|
-
assert mes.pos == i % n
|
|
139
|
-
cur_env = mes()
|
|
140
|
-
assert len(cur_env.tensors) == 2 * bsz + 2
|
|
141
|
-
assert (cur_env ^ all) == pytest.approx(1.0)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
class TestDMRG1:
|
|
145
|
-
def test_single_explicit_sweep(self):
|
|
146
|
-
h = MPO_ham_heis(5)
|
|
147
|
-
dmrg = DMRG1(h, bond_dims=3)
|
|
148
|
-
assert dmrg._k[0].dtype == float
|
|
149
|
-
|
|
150
|
-
energy_tn = dmrg._b | dmrg.ham | dmrg._k
|
|
151
|
-
|
|
152
|
-
e0 = energy_tn ^ ...
|
|
153
|
-
assert abs(e0.imag) < 1e-13
|
|
154
|
-
|
|
155
|
-
de1 = dmrg.sweep_right()
|
|
156
|
-
e1 = energy_tn ^ ...
|
|
157
|
-
assert_allclose(de1, e1)
|
|
158
|
-
assert abs(e1.imag) < 1e-13
|
|
159
|
-
|
|
160
|
-
de2 = dmrg.sweep_right()
|
|
161
|
-
e2 = energy_tn ^ ...
|
|
162
|
-
assert_allclose(de2, e2)
|
|
163
|
-
assert abs(e2.imag) < 1e-13
|
|
164
|
-
|
|
165
|
-
# state is already left canonized after right sweep
|
|
166
|
-
de3 = dmrg.sweep_left(canonize=False)
|
|
167
|
-
e3 = energy_tn ^ ...
|
|
168
|
-
assert_allclose(de3, e3)
|
|
169
|
-
assert abs(e2.imag) < 1e-13
|
|
170
|
-
|
|
171
|
-
de4 = dmrg.sweep_left()
|
|
172
|
-
e4 = energy_tn ^ ...
|
|
173
|
-
assert_allclose(de4, e4)
|
|
174
|
-
assert abs(e2.imag) < 1e-13
|
|
175
|
-
|
|
176
|
-
# test still normalized
|
|
177
|
-
assert dmrg._k[0].dtype == float
|
|
178
|
-
dmrg._k.align_(dmrg._b)
|
|
179
|
-
assert_allclose(abs(dmrg._b @ dmrg._k), 1)
|
|
180
|
-
|
|
181
|
-
assert e1.real < e0.real
|
|
182
|
-
assert e2.real < e1.real
|
|
183
|
-
assert e3.real < e2.real
|
|
184
|
-
assert e4.real < e3.real
|
|
185
|
-
|
|
186
|
-
@pytest.mark.parametrize("dense", [False, True])
|
|
187
|
-
@pytest.mark.parametrize("MPO_ham", [MPO_ham_XY, MPO_ham_heis])
|
|
188
|
-
@pytest.mark.parametrize("cyclic", [False, True])
|
|
189
|
-
def test_ground_state_matches(self, dense, MPO_ham, cyclic):
|
|
190
|
-
n = 10
|
|
191
|
-
|
|
192
|
-
tol = 3e-2 if cyclic else 1e-4
|
|
193
|
-
|
|
194
|
-
h = MPO_ham(n, cyclic=cyclic)
|
|
195
|
-
dmrg = DMRG1(h, bond_dims=[4, 8, 12])
|
|
196
|
-
dmrg.opts["local_eig_ham_dense"] = dense
|
|
197
|
-
dmrg.opts["periodic_segment_size"] = 1.0
|
|
198
|
-
dmrg.opts["periodic_nullspace_fudge_factor"] = 1e-6
|
|
199
|
-
assert dmrg.solve(tol=tol / 10, verbosity=1)
|
|
200
|
-
assert dmrg.state.cyclic == cyclic
|
|
201
|
-
eff_e, mps_gs = dmrg.energy, dmrg.state
|
|
202
|
-
mps_gs_dense = mps_gs.to_qarray()
|
|
203
|
-
|
|
204
|
-
assert_allclose(mps_gs_dense.H @ mps_gs_dense, 1.0, rtol=tol)
|
|
205
|
-
|
|
206
|
-
h_dense = h.to_qarray()
|
|
207
|
-
|
|
208
|
-
# check against dense form
|
|
209
|
-
actual_e, gs = eigh(h_dense, k=1)
|
|
210
|
-
assert_allclose(actual_e, eff_e, rtol=tol)
|
|
211
|
-
assert_allclose(abs(expec(mps_gs_dense, gs)), 1.0, rtol=tol)
|
|
212
|
-
|
|
213
|
-
# check against actual MPO_ham
|
|
214
|
-
if MPO_ham is MPO_ham_XY:
|
|
215
|
-
ham_dense = ham_heis(
|
|
216
|
-
n, cyclic=cyclic, j=(1.0, 1.0, 0.0), sparse=True
|
|
217
|
-
)
|
|
218
|
-
elif MPO_ham is MPO_ham_heis:
|
|
219
|
-
ham_dense = ham_heis(n, cyclic=cyclic, sparse=True)
|
|
220
|
-
|
|
221
|
-
actual_e, gs = eigh(ham_dense, k=1)
|
|
222
|
-
assert_allclose(actual_e, eff_e, rtol=tol)
|
|
223
|
-
assert_allclose(abs(expec(mps_gs_dense, gs)), 1.0, rtol=tol)
|
|
224
|
-
|
|
225
|
-
def test_ising_and_MPS_product_state(self):
|
|
226
|
-
h = MPO_ham_ising(6, bx=2.0, j=0.1)
|
|
227
|
-
dmrg = DMRG1(h, bond_dims=8)
|
|
228
|
-
assert dmrg.solve(verbosity=1)
|
|
229
|
-
eff_e, mps_gs = dmrg.energy, dmrg.state
|
|
230
|
-
mps_gs_dense = mps_gs.to_qarray()
|
|
231
|
-
assert_allclose(mps_gs_dense.H @ mps_gs_dense, 1.0)
|
|
232
|
-
|
|
233
|
-
# check against dense
|
|
234
|
-
h_dense = h.to_qarray()
|
|
235
|
-
actual_e, gs = eigh(h_dense, k=1)
|
|
236
|
-
assert_allclose(actual_e, eff_e)
|
|
237
|
-
assert_allclose(abs(expec(mps_gs_dense, gs)), 1.0)
|
|
238
|
-
|
|
239
|
-
exp_gs = MPS_product_state([plus()] * 6)
|
|
240
|
-
assert_allclose(abs(exp_gs.H @ mps_gs), 1.0, rtol=1e-3)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
class TestDMRG2:
|
|
244
|
-
@pytest.mark.parametrize("dense", [False, True])
|
|
245
|
-
@pytest.mark.parametrize("MPO_ham", [MPO_ham_XY, MPO_ham_heis])
|
|
246
|
-
@pytest.mark.parametrize("cyclic", [False, True])
|
|
247
|
-
def test_matches_exact(self, dense, MPO_ham, cyclic):
|
|
248
|
-
n = 6
|
|
249
|
-
h = MPO_ham(n, cyclic=cyclic)
|
|
250
|
-
|
|
251
|
-
tol = 3e-2 if cyclic else 1e-4
|
|
252
|
-
|
|
253
|
-
dmrg = DMRG2(h, bond_dims=[4, 8, 12])
|
|
254
|
-
assert dmrg._k[0].dtype == float
|
|
255
|
-
dmrg.opts["local_eig_ham_dense"] = dense
|
|
256
|
-
dmrg.opts["periodic_segment_size"] = 1.0
|
|
257
|
-
dmrg.opts["periodic_nullspace_fudge_factor"] = 1e-6
|
|
258
|
-
|
|
259
|
-
assert dmrg.solve(tol=tol / 10, verbosity=1)
|
|
260
|
-
|
|
261
|
-
# XXX: need to dispatch SLEPc eigh on real input
|
|
262
|
-
# assert dmrg._k[0].dtype == float
|
|
263
|
-
|
|
264
|
-
eff_e, mps_gs = dmrg.energy, dmrg.state
|
|
265
|
-
mps_gs_dense = mps_gs.to_qarray()
|
|
266
|
-
|
|
267
|
-
assert_allclose(expec(mps_gs_dense, mps_gs_dense), 1.0, rtol=tol)
|
|
268
|
-
|
|
269
|
-
h_dense = h.to_qarray()
|
|
270
|
-
|
|
271
|
-
# check against dense form
|
|
272
|
-
actual_e, gs = eigh(h_dense, k=1)
|
|
273
|
-
assert_allclose(actual_e, eff_e, rtol=tol)
|
|
274
|
-
assert_allclose(abs(expec(mps_gs_dense, gs)), 1.0, rtol=tol)
|
|
275
|
-
|
|
276
|
-
# check against actual MPO_ham
|
|
277
|
-
if MPO_ham is MPO_ham_XY:
|
|
278
|
-
ham_dense = ham_heis(n, cyclic=cyclic, j=(1.0, 1.0, 0.0))
|
|
279
|
-
elif MPO_ham is MPO_ham_heis:
|
|
280
|
-
ham_dense = ham_heis(n, cyclic=cyclic)
|
|
281
|
-
|
|
282
|
-
actual_e, gs = eigh(ham_dense, k=1)
|
|
283
|
-
assert_allclose(actual_e, eff_e, rtol=tol)
|
|
284
|
-
assert_allclose(abs(expec(mps_gs_dense, gs)), 1.0, rtol=tol)
|
|
285
|
-
|
|
286
|
-
def test_cyclic_solve_big_with_segmenting(self):
|
|
287
|
-
n = 150
|
|
288
|
-
ham = MPO_ham_heis(n, cyclic=True)
|
|
289
|
-
dmrg = DMRG2(ham, bond_dims=range(10, 30, 2))
|
|
290
|
-
dmrg.opts["periodic_segment_size"] = 1 / 3
|
|
291
|
-
assert dmrg.solve(tol=1, verbosity=2)
|
|
292
|
-
assert dmrg.energy == pytest.approx(heisenberg_energy(n), 1e-3)
|
|
293
|
-
|
|
294
|
-
@pytest.mark.parametrize(
|
|
295
|
-
"dtype", [np.float32, np.float64, np.complex64, np.complex128]
|
|
296
|
-
)
|
|
297
|
-
def test_dtypes(self, dtype):
|
|
298
|
-
H = MPO_ham_heis(8).astype(dtype)
|
|
299
|
-
dmrg = DMRG2(H)
|
|
300
|
-
dmrg.opts["local_eig_backend"] = "scipy"
|
|
301
|
-
dmrg.solve(max_sweeps=3)
|
|
302
|
-
(res_dtype,) = {t.dtype for t in dmrg.state}
|
|
303
|
-
assert res_dtype == dtype
|
|
304
|
-
|
|
305
|
-
def test_total_size_2(self):
|
|
306
|
-
N = 2
|
|
307
|
-
builder = SpinHam1D(1 / 2)
|
|
308
|
-
for i in range(N - 1):
|
|
309
|
-
builder[i, i + 1] += 1.0, "Z", "Z"
|
|
310
|
-
|
|
311
|
-
H = builder.build_mpo(N)
|
|
312
|
-
dmrg = DMRG2(H)
|
|
313
|
-
dmrg.solve(verbosity=1)
|
|
314
|
-
assert dmrg.energy == pytest.approx(-1 / 4)
|
|
315
|
-
|
|
316
|
-
def test_variable_bond_ham(self):
|
|
317
|
-
import quimb as qu
|
|
318
|
-
|
|
319
|
-
HB = SpinHam1D(1 / 2)
|
|
320
|
-
HB[0, 1] += 0.6, "Z", "Z"
|
|
321
|
-
HB[1, 2] += 0.7, "Z", "Z"
|
|
322
|
-
HB[1, 2] += 0.8, "X", "X"
|
|
323
|
-
HB[2, 3] += 0.9, "Y", "Y"
|
|
324
|
-
|
|
325
|
-
H_mpo = HB.build_mpo(4)
|
|
326
|
-
H_sps = HB.build_sparse(4)
|
|
327
|
-
|
|
328
|
-
assert H_mpo.bond_sizes() == [3, 4, 3]
|
|
329
|
-
|
|
330
|
-
Sx, Sy, Sz = map(qu.spin_operator, "xyz")
|
|
331
|
-
H_explicit = (
|
|
332
|
-
qu.ikron(0.6 * Sz & Sz, [2, 2, 2, 2], [0, 1])
|
|
333
|
-
+ qu.ikron(0.7 * Sz & Sz, [2, 2, 2, 2], [1, 2])
|
|
334
|
-
+ qu.ikron(0.8 * Sx & Sx, [2, 2, 2, 2], [1, 2])
|
|
335
|
-
+ qu.ikron(0.9 * Sy & Sy, [2, 2, 2, 2], [2, 3])
|
|
336
|
-
)
|
|
337
|
-
|
|
338
|
-
assert_allclose(H_explicit, H_mpo.to_qarray())
|
|
339
|
-
assert_allclose(H_explicit, H_sps.toarray())
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
class TestDMRGX:
|
|
343
|
-
def test_explicit_sweeps(self):
|
|
344
|
-
n = 8
|
|
345
|
-
chi = 16
|
|
346
|
-
ham = MPO_ham_mbl(n, dh=4, seed=42)
|
|
347
|
-
p0 = MPS_rand_state(n, 2).expand_bond_dimension(chi)
|
|
348
|
-
|
|
349
|
-
b0 = p0.H
|
|
350
|
-
p0.align_(ham, b0)
|
|
351
|
-
en0 = (p0 & ham & b0) ^ ...
|
|
352
|
-
dmrgx = DMRGX(ham, p0, chi)
|
|
353
|
-
dmrgx.sweep_right()
|
|
354
|
-
en1 = dmrgx.sweep_left(canonize=False)
|
|
355
|
-
assert en0 != en1
|
|
356
|
-
|
|
357
|
-
dmrgx.sweep_right(canonize=False)
|
|
358
|
-
en = dmrgx.sweep_right(canonize=True)
|
|
359
|
-
|
|
360
|
-
# check normalized
|
|
361
|
-
assert_allclose(dmrgx._k.H @ dmrgx._k, 1.0)
|
|
362
|
-
|
|
363
|
-
k = dmrgx._k.to_qarray()
|
|
364
|
-
h = ham.to_qarray()
|
|
365
|
-
el, ev = eigh(h)
|
|
366
|
-
|
|
367
|
-
# check variance very low
|
|
368
|
-
assert np.abs((k.H @ h @ h @ k) - (k.H @ h @ k) ** 2) < 1e-12
|
|
369
|
-
|
|
370
|
-
# check exactly one eigenvalue matched well
|
|
371
|
-
assert np.sum(np.abs(el - en) < 1e-12) == 1
|
|
372
|
-
|
|
373
|
-
# check exactly one eigenvector is matched with high fidelity
|
|
374
|
-
ovlps = (ev.H @ k).toarray() ** 2
|
|
375
|
-
big_ovlps = ovlps[ovlps > 1e-12]
|
|
376
|
-
assert_allclose(big_ovlps, [1])
|
|
377
|
-
|
|
378
|
-
# check fully
|
|
379
|
-
assert is_eigenvector(k, h, tol=1e-10)
|
|
380
|
-
|
|
381
|
-
def test_solve_bigger(self):
|
|
382
|
-
n = 14
|
|
383
|
-
chi = 16
|
|
384
|
-
ham = MPO_ham_mbl(n, dh=8, seed=42)
|
|
385
|
-
p0 = MPS_computational_state("00110111000101")
|
|
386
|
-
dmrgx = DMRGX(ham, p0, chi)
|
|
387
|
-
assert dmrgx.solve(tol=1e-5, sweep_sequence="R")
|
|
388
|
-
assert dmrgx.state[0].dtype == float
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
from math import log2
|
|
2
|
-
import pytest
|
|
3
|
-
import numpy as np
|
|
4
|
-
from numpy.testing import assert_allclose
|
|
5
|
-
|
|
6
|
-
from quimb import (
|
|
7
|
-
seed_rand,
|
|
8
|
-
approx_spectral_function,
|
|
9
|
-
eigvalsh,
|
|
10
|
-
logneg_subsys,
|
|
11
|
-
)
|
|
12
|
-
from quimb.tensor import MPO_rand_herm, MPO_ham_heis, DMRG2
|
|
13
|
-
from quimb.tensor.tensor_approx_spectral import construct_lanczos_tridiag_MPO
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
np.random.seed(42)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# XXX: these all need improvement
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class TestMPOSpectralApprox:
|
|
23
|
-
def test_constructing_tridiag_works(self):
|
|
24
|
-
A = MPO_rand_herm(10, 7)
|
|
25
|
-
for _ in construct_lanczos_tridiag_MPO(A, 5):
|
|
26
|
-
pass
|
|
27
|
-
|
|
28
|
-
@pytest.mark.parametrize("fn", [abs, np.cos, lambda x: np.sin(x) ** 2])
|
|
29
|
-
def test_approx_fn(self, fn):
|
|
30
|
-
A = MPO_rand_herm(10, 7, normalize=True)
|
|
31
|
-
xe = sum(fn(eigvalsh(A.to_dense())))
|
|
32
|
-
xf = approx_spectral_function(A, fn, tol=0.1, verbosity=2)
|
|
33
|
-
assert_allclose(xe, xf, rtol=0.5)
|
|
34
|
-
|
|
35
|
-
def test_realistic(self):
|
|
36
|
-
seed_rand(42)
|
|
37
|
-
ham = MPO_ham_heis(20)
|
|
38
|
-
dmrg = DMRG2(ham, bond_dims=[2, 4])
|
|
39
|
-
dmrg.solve()
|
|
40
|
-
rho_ab = dmrg.state.partial_trace_to_mpo(range(6, 14))
|
|
41
|
-
xf = approx_spectral_function(
|
|
42
|
-
rho_ab, lambda x: x, tol=0.1, verbosity=2
|
|
43
|
-
)
|
|
44
|
-
assert_allclose(1.0, xf, rtol=0.6, atol=0.001)
|
|
45
|
-
|
|
46
|
-
def test_realistic_ent(self):
|
|
47
|
-
n = 12
|
|
48
|
-
sysa, sysb = range(3, 6), range(6, 8)
|
|
49
|
-
sysab = (*sysa, *sysb)
|
|
50
|
-
|
|
51
|
-
ham = MPO_ham_heis(n)
|
|
52
|
-
dmrg = DMRG2(ham, bond_dims=[10])
|
|
53
|
-
dmrg.solve()
|
|
54
|
-
|
|
55
|
-
psi0 = dmrg.state.to_dense()
|
|
56
|
-
lne = logneg_subsys(psi0, [2] * n, sysa=sysa, sysb=sysb)
|
|
57
|
-
|
|
58
|
-
rho_ab = dmrg.state.partial_trace_to_mpo(sysab, rescale_sites=True)
|
|
59
|
-
rho_ab_pt = rho_ab.partial_transpose(range(3))
|
|
60
|
-
lnx = log2(
|
|
61
|
-
approx_spectral_function(rho_ab_pt, abs, tol=0.1, verbosity=2)
|
|
62
|
-
)
|
|
63
|
-
assert_allclose(lne, lnx, rtol=0.6, atol=0.1)
|