Trajectree 0.0.0__py3-none-any.whl → 0.0.1__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 +3 -0
  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/quimb/docs/_pygments/_pygments_dark.py +118 -0
  7. trajectree/quimb/docs/_pygments/_pygments_light.py +118 -0
  8. trajectree/quimb/docs/conf.py +158 -0
  9. trajectree/quimb/docs/examples/ex_mpi_expm_evo.py +62 -0
  10. trajectree/quimb/quimb/__init__.py +507 -0
  11. trajectree/quimb/quimb/calc.py +1491 -0
  12. trajectree/quimb/quimb/core.py +2279 -0
  13. trajectree/quimb/quimb/evo.py +712 -0
  14. trajectree/quimb/quimb/experimental/__init__.py +0 -0
  15. trajectree/quimb/quimb/experimental/autojittn.py +129 -0
  16. trajectree/quimb/quimb/experimental/belief_propagation/__init__.py +109 -0
  17. trajectree/quimb/quimb/experimental/belief_propagation/bp_common.py +397 -0
  18. trajectree/quimb/quimb/experimental/belief_propagation/d1bp.py +316 -0
  19. trajectree/quimb/quimb/experimental/belief_propagation/d2bp.py +653 -0
  20. trajectree/quimb/quimb/experimental/belief_propagation/hd1bp.py +571 -0
  21. trajectree/quimb/quimb/experimental/belief_propagation/hv1bp.py +775 -0
  22. trajectree/quimb/quimb/experimental/belief_propagation/l1bp.py +316 -0
  23. trajectree/quimb/quimb/experimental/belief_propagation/l2bp.py +537 -0
  24. trajectree/quimb/quimb/experimental/belief_propagation/regions.py +194 -0
  25. trajectree/quimb/quimb/experimental/cluster_update.py +286 -0
  26. trajectree/quimb/quimb/experimental/merabuilder.py +865 -0
  27. trajectree/quimb/quimb/experimental/operatorbuilder/__init__.py +15 -0
  28. trajectree/quimb/quimb/experimental/operatorbuilder/operatorbuilder.py +1631 -0
  29. trajectree/quimb/quimb/experimental/schematic.py +7 -0
  30. trajectree/quimb/quimb/experimental/tn_marginals.py +130 -0
  31. trajectree/quimb/quimb/experimental/tnvmc.py +1483 -0
  32. trajectree/quimb/quimb/gates.py +36 -0
  33. trajectree/quimb/quimb/gen/__init__.py +2 -0
  34. trajectree/quimb/quimb/gen/operators.py +1167 -0
  35. trajectree/quimb/quimb/gen/rand.py +713 -0
  36. trajectree/quimb/quimb/gen/states.py +479 -0
  37. trajectree/quimb/quimb/linalg/__init__.py +6 -0
  38. trajectree/quimb/quimb/linalg/approx_spectral.py +1109 -0
  39. trajectree/quimb/quimb/linalg/autoblock.py +258 -0
  40. trajectree/quimb/quimb/linalg/base_linalg.py +719 -0
  41. trajectree/quimb/quimb/linalg/mpi_launcher.py +397 -0
  42. trajectree/quimb/quimb/linalg/numpy_linalg.py +244 -0
  43. trajectree/quimb/quimb/linalg/rand_linalg.py +514 -0
  44. trajectree/quimb/quimb/linalg/scipy_linalg.py +293 -0
  45. trajectree/quimb/quimb/linalg/slepc_linalg.py +892 -0
  46. trajectree/quimb/quimb/schematic.py +1518 -0
  47. trajectree/quimb/quimb/tensor/__init__.py +401 -0
  48. trajectree/quimb/quimb/tensor/array_ops.py +610 -0
  49. trajectree/quimb/quimb/tensor/circuit.py +4824 -0
  50. trajectree/quimb/quimb/tensor/circuit_gen.py +411 -0
  51. trajectree/quimb/quimb/tensor/contraction.py +336 -0
  52. trajectree/quimb/quimb/tensor/decomp.py +1255 -0
  53. trajectree/quimb/quimb/tensor/drawing.py +1646 -0
  54. trajectree/quimb/quimb/tensor/fitting.py +385 -0
  55. trajectree/quimb/quimb/tensor/geometry.py +583 -0
  56. trajectree/quimb/quimb/tensor/interface.py +114 -0
  57. trajectree/quimb/quimb/tensor/networking.py +1058 -0
  58. trajectree/quimb/quimb/tensor/optimize.py +1818 -0
  59. trajectree/quimb/quimb/tensor/tensor_1d.py +4778 -0
  60. trajectree/quimb/quimb/tensor/tensor_1d_compress.py +1854 -0
  61. trajectree/quimb/quimb/tensor/tensor_1d_tebd.py +662 -0
  62. trajectree/quimb/quimb/tensor/tensor_2d.py +5954 -0
  63. trajectree/quimb/quimb/tensor/tensor_2d_compress.py +96 -0
  64. trajectree/quimb/quimb/tensor/tensor_2d_tebd.py +1230 -0
  65. trajectree/quimb/quimb/tensor/tensor_3d.py +2869 -0
  66. trajectree/quimb/quimb/tensor/tensor_3d_tebd.py +46 -0
  67. trajectree/quimb/quimb/tensor/tensor_approx_spectral.py +60 -0
  68. trajectree/quimb/quimb/tensor/tensor_arbgeom.py +3237 -0
  69. trajectree/quimb/quimb/tensor/tensor_arbgeom_compress.py +565 -0
  70. trajectree/quimb/quimb/tensor/tensor_arbgeom_tebd.py +1138 -0
  71. trajectree/quimb/quimb/tensor/tensor_builder.py +5411 -0
  72. trajectree/quimb/quimb/tensor/tensor_core.py +11179 -0
  73. trajectree/quimb/quimb/tensor/tensor_dmrg.py +1472 -0
  74. trajectree/quimb/quimb/tensor/tensor_mera.py +204 -0
  75. trajectree/quimb/quimb/utils.py +892 -0
  76. trajectree/quimb/tests/__init__.py +0 -0
  77. trajectree/quimb/tests/test_accel.py +501 -0
  78. trajectree/quimb/tests/test_calc.py +788 -0
  79. trajectree/quimb/tests/test_core.py +847 -0
  80. trajectree/quimb/tests/test_evo.py +565 -0
  81. trajectree/quimb/tests/test_gen/__init__.py +0 -0
  82. trajectree/quimb/tests/test_gen/test_operators.py +361 -0
  83. trajectree/quimb/tests/test_gen/test_rand.py +296 -0
  84. trajectree/quimb/tests/test_gen/test_states.py +261 -0
  85. trajectree/quimb/tests/test_linalg/__init__.py +0 -0
  86. trajectree/quimb/tests/test_linalg/test_approx_spectral.py +368 -0
  87. trajectree/quimb/tests/test_linalg/test_base_linalg.py +351 -0
  88. trajectree/quimb/tests/test_linalg/test_mpi_linalg.py +127 -0
  89. trajectree/quimb/tests/test_linalg/test_numpy_linalg.py +84 -0
  90. trajectree/quimb/tests/test_linalg/test_rand_linalg.py +134 -0
  91. trajectree/quimb/tests/test_linalg/test_slepc_linalg.py +283 -0
  92. trajectree/quimb/tests/test_tensor/__init__.py +0 -0
  93. trajectree/quimb/tests/test_tensor/test_belief_propagation/__init__.py +0 -0
  94. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_d1bp.py +39 -0
  95. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_d2bp.py +67 -0
  96. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_hd1bp.py +64 -0
  97. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_hv1bp.py +51 -0
  98. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_l1bp.py +142 -0
  99. trajectree/quimb/tests/test_tensor/test_belief_propagation/test_l2bp.py +101 -0
  100. trajectree/quimb/tests/test_tensor/test_circuit.py +816 -0
  101. trajectree/quimb/tests/test_tensor/test_contract.py +67 -0
  102. trajectree/quimb/tests/test_tensor/test_decomp.py +40 -0
  103. trajectree/quimb/tests/test_tensor/test_mera.py +52 -0
  104. trajectree/quimb/tests/test_tensor/test_optimizers.py +488 -0
  105. trajectree/quimb/tests/test_tensor/test_tensor_1d.py +1171 -0
  106. trajectree/quimb/tests/test_tensor/test_tensor_2d.py +606 -0
  107. trajectree/quimb/tests/test_tensor/test_tensor_2d_tebd.py +144 -0
  108. trajectree/quimb/tests/test_tensor/test_tensor_3d.py +123 -0
  109. trajectree/quimb/tests/test_tensor/test_tensor_arbgeom.py +226 -0
  110. trajectree/quimb/tests/test_tensor/test_tensor_builder.py +441 -0
  111. trajectree/quimb/tests/test_tensor/test_tensor_core.py +2066 -0
  112. trajectree/quimb/tests/test_tensor/test_tensor_dmrg.py +388 -0
  113. trajectree/quimb/tests/test_tensor/test_tensor_spectral_approx.py +63 -0
  114. trajectree/quimb/tests/test_tensor/test_tensor_tebd.py +270 -0
  115. trajectree/quimb/tests/test_utils.py +85 -0
  116. trajectree/trajectory.py +2 -2
  117. {trajectree-0.0.0.dist-info → trajectree-0.0.1.dist-info}/METADATA +2 -2
  118. trajectree-0.0.1.dist-info/RECORD +126 -0
  119. trajectree-0.0.0.dist-info/RECORD +0 -16
  120. {trajectree-0.0.0.dist-info → trajectree-0.0.1.dist-info}/WHEEL +0 -0
  121. {trajectree-0.0.0.dist-info → trajectree-0.0.1.dist-info}/licenses/LICENSE +0 -0
  122. {trajectree-0.0.0.dist-info → trajectree-0.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,411 @@
1
+ """Functions for generating specific, e.g. ansatz, circuits."""
2
+
3
+ import math
4
+ import random
5
+ import itertools
6
+
7
+ from .. import rand, seed_rand
8
+
9
+
10
+ def inject_u3s(
11
+ ent_gates,
12
+ gate2="cz",
13
+ avoid_doubling=False,
14
+ seed=None,
15
+ ):
16
+ r"""Take a sequence of pairs denoting qubits to entangle and interleave one
17
+ single qubit gate inbetween every leg. For example:
18
+
19
+ ent_gates = [(0, 1), (2, 3), (1, 2)]
20
+
21
+ Would go get made into a circuit like::
22
+
23
+ | | | | | | | |
24
+ | | | | | u u |
25
+ | | | | | | | |
26
+ | o++o | u o++o u
27
+ | | | | | | | |
28
+ | | | | --> | u u |
29
+ | | | | | | | |
30
+ o++o o++o o++o o++o
31
+ | | | | | | | |
32
+ | | | | u u u u
33
+ | | | | | | | |
34
+
35
+ Technically, this generates a bipartite graph between single qubit and two
36
+ qubit tensors, and should be the most expressive circuit possible for that
37
+ 'budget' of entangling gates.
38
+
39
+ Parameters
40
+ ----------
41
+ ent_gates : sequence[tuple[int]]
42
+ A 'stack' of entangling gate pairs to apply.
43
+ gate2 : {'cx', 'cy', 'cz', 'iswap', ..., str}, optional
44
+ The gate to use for the entanling pairs.
45
+ avoid_doubling : bool, optional
46
+ Whether to avoid placing an entangling gate directly above the same
47
+ entangling gate (there will still be single qubit gates interleaved).
48
+
49
+ Returns
50
+ -------
51
+ Circuit
52
+ """
53
+ if seed is not None:
54
+ seed_rand(seed)
55
+
56
+ # keep track of where not to apply another entangling gate
57
+ just_entangled = set()
58
+
59
+ # keep track of where its worth putting a U3
60
+ n = max(itertools.chain.from_iterable(ent_gates)) + 1
61
+ needs_u3 = [True] * n
62
+
63
+ # create the circuit!
64
+ gates = []
65
+ # consume list of pairs to entangle
66
+ while ent_gates:
67
+ # break up entanling gates with U3s where necesary
68
+ for i in range(n):
69
+ if needs_u3[i]:
70
+ gates.append(("U3", *rand(3, scale=2 * math.pi), i))
71
+ needs_u3[i] = False
72
+
73
+ # try and get the next entanling gate which is not 'doubled'
74
+ for k, pair in enumerate(ent_gates):
75
+ # (just_entangled will never be populated if avoid_doubling=False)
76
+ if pair not in just_entangled:
77
+ break
78
+
79
+ i, j = ent_gates.pop(k)
80
+ gates.append((gate2, i, j))
81
+
82
+ # 1 2 3 4
83
+ # ^ ^ ^ ^
84
+ # | | | |
85
+ # o++o o++o
86
+ # | | | |
87
+ # | o++o | <- if we have just placed (2, 3), disable it in next
88
+ # | | | | round but enable (1, 2) and (3, 4) etc
89
+ # ^ ^ ^ ^
90
+ if avoid_doubling:
91
+ just_entangled = {
92
+ ij for ij in just_entangled if (i not in ij) and (j not in ij)
93
+ }
94
+ just_entangled.add((i, j))
95
+
96
+ # update the register of where to place U3s
97
+ needs_u3[i] = needs_u3[j] = True
98
+
99
+ # place the final layer of U3s
100
+ for i in range(n):
101
+ if needs_u3[i]:
102
+ gates.append(("U3", *rand(3, scale=2 * math.pi), i))
103
+
104
+ return gates
105
+
106
+
107
+ def gates_to_param_circuit(gates, n, parametrize="U3", **circuit_opts):
108
+ """Turn the sequence ``gates`` into a ``Circuit`` of ``n`` qubits, with any
109
+ gates that appear in ``parametrize`` being... parametrized.
110
+
111
+ Parameters
112
+ ----------
113
+ gates : sequence[tuple[str, float, int]]
114
+ The gates describing the circuit.
115
+ n : int
116
+ The number of qubits to make the circuit act one.
117
+ parametrize : str or sequence[str], optional
118
+ Which gates to parametrize.
119
+ circuit_opts
120
+ Supplied to :class:`~quimb.tensor.circuit.Circuit`.
121
+
122
+ Returns
123
+ -------
124
+ Circuit
125
+ """
126
+ from .circuit import Circuit
127
+
128
+ if isinstance(parametrize, str):
129
+ parametrize = (parametrize,)
130
+
131
+ circ = Circuit(n, **circuit_opts)
132
+ for g in gates:
133
+ circ.apply_gate(*g, parametrize=g[0] in parametrize)
134
+
135
+ return circ
136
+
137
+
138
+ def circ_ansatz_1D_zigzag(n, depth, gate2="cz", seed=None, **circuit_opts):
139
+ r"""A 1D circuit ansatz with forward and backward layers of entangling
140
+ gates interleaved with U3 single qubit unitaries::
141
+
142
+ | | | |
143
+ u u | |
144
+ o++o u |
145
+ | | | u
146
+ | o++o |
147
+ | | u |
148
+ | | o++o
149
+ u u u u
150
+ | | o++o
151
+ | | u |
152
+ | o++o |
153
+ | u | u
154
+ o++o u |
155
+ u u | |
156
+ | | | |
157
+
158
+ Parameters
159
+ ----------
160
+ n : int
161
+ The number of qubits.
162
+ depth : int
163
+ The number of entangling gates per pair.
164
+ gate2 : {'cx', 'cy', 'cz', 'iswap', ..., str}, optional
165
+ The gate to use for the entanling pairs.
166
+ seed : int, optional
167
+ Random seed for parameters.
168
+ opts
169
+ Supplied to :func:`~quimb.tensor.circuit_gen.gates_to_param_circuit`.
170
+
171
+ Returns
172
+ -------
173
+ Circuit
174
+
175
+ See Also
176
+ --------
177
+ circ_ansatz_1D_rand, circ_ansatz_1D_brickwork
178
+ """
179
+ ent_gates = []
180
+ forward_layer = [(i, i + 1) for i in range(n - 1)]
181
+ backward_layer = [(i + 1, i) for i in range(n - 2, -1, -1)]
182
+
183
+ for d in range(depth):
184
+ if d % 2 == 0:
185
+ ent_gates.extend(forward_layer)
186
+ else:
187
+ ent_gates.extend(backward_layer)
188
+
189
+ # inject U3 gates!
190
+ gates = inject_u3s(ent_gates, gate2=gate2, seed=seed)
191
+ circ = gates_to_param_circuit(gates, n, **circuit_opts)
192
+
193
+ return circ
194
+
195
+
196
+ def circ_ansatz_1D_brickwork(
197
+ n, depth, cyclic=False, gate2="cz", seed=None, **circuit_opts
198
+ ):
199
+ r"""A 1D circuit ansatz with odd and even layers of entangling
200
+ gates interleaved with U3 single qubit unitaries::
201
+
202
+ | | | | |
203
+ | u u u u
204
+ u o++o o++o
205
+ | u u u |
206
+ o++o o++o u
207
+ | u u u |
208
+ u o++o o++o
209
+ | u u u |
210
+ o++o o++o u
211
+ | u u u u
212
+ u o++o o++o
213
+ | u u u |
214
+ o++o o++o u
215
+ u u u u |
216
+ | | | | |
217
+
218
+ Parameters
219
+ ----------
220
+ n : int
221
+ The number of qubits.
222
+ depth : int
223
+ The number of entangling gates per pair.
224
+ cyclic : bool, optional
225
+ Whether to add entangling gates between qubits 0 and n - 1.
226
+ gate2 : {'cx', 'cy', 'cz', 'iswap', ..., str}, optional
227
+ The gate to use for the entanling pairs.
228
+ seed : int, optional
229
+ Random seed for parameters.
230
+ opts
231
+ Supplied to :func:`~quimb.tensor.circuit_gen.gates_to_param_circuit`.
232
+
233
+
234
+ Returns
235
+ -------
236
+ Circuit
237
+
238
+ See Also
239
+ --------
240
+ circ_ansatz_1D_zigzag, circ_ansatz_1D_rand
241
+ """
242
+ ent_gates = []
243
+ for d in range(depth):
244
+ # the even pairs layer
245
+ ent_gates.extend((i, i + 1) for i in range(0, n - 1, 2))
246
+ if cyclic and (n % 2 == 1):
247
+ ent_gates.append((n - 1, 0))
248
+
249
+ # the odd pairs layer
250
+ ent_gates.extend((i, i + 1) for i in range(1, n - 1, 2))
251
+ if cyclic and (n % 2 == 0):
252
+ ent_gates.append((n - 1, 0))
253
+
254
+ # inject U3 gates!
255
+ gates = inject_u3s(ent_gates, gate2=gate2, seed=seed)
256
+ circ = gates_to_param_circuit(gates, n, **circuit_opts)
257
+
258
+ return circ
259
+
260
+
261
+ def circ_ansatz_1D_rand(
262
+ n,
263
+ depth,
264
+ seed=None,
265
+ cyclic=False,
266
+ gate2="cz",
267
+ avoid_doubling=True,
268
+ **circuit_opts,
269
+ ):
270
+ """A 1D circuit ansatz with randomly place entangling gates interleaved
271
+ with U3 single qubit unitaries.
272
+
273
+ Parameters
274
+ ----------
275
+ n : int
276
+ The number of qubits.
277
+ depth : int
278
+ The number of entangling gates per pair.
279
+ seed : int, optional
280
+ Random seed.
281
+ cyclic : bool, optional
282
+ Whether to add entangling gates between qubits 0 and n - 1.
283
+ gate2 : {'cx', 'cy', 'cz', 'iswap', ..., str}, optional
284
+ The gate to use for the entanling pairs.
285
+ avoid_doubling : bool, optional
286
+ Whether to avoid placing an entangling gate directly above the same
287
+ entangling gate (there will still be single qubit gates interleaved).
288
+ opts
289
+ Supplied to :func:`~quimb.tensor.circuit_gen.gates_to_param_circuit`.
290
+
291
+ Returns
292
+ -------
293
+ Circuit
294
+
295
+ See Also
296
+ --------
297
+ circ_ansatz_1D_zigzag, circ_ansatz_1D_brickwork
298
+ """
299
+ if seed is not None:
300
+ random.seed(seed)
301
+
302
+ # the set number of entangling pairs to distribute randomly
303
+ ent_gates = [(i, i + 1) for i in range(n - 1) for _ in range(depth)]
304
+ if cyclic:
305
+ ent_gates.extend((n - 1, 0) for _ in range(depth))
306
+
307
+ # randomly permute the order
308
+ random.shuffle(ent_gates)
309
+
310
+ # inject U3 gates!
311
+ gates = inject_u3s(
312
+ ent_gates, avoid_doubling=avoid_doubling, gate2=gate2, seed=seed
313
+ )
314
+ circ = gates_to_param_circuit(gates, n, **circuit_opts)
315
+
316
+ return circ
317
+
318
+
319
+ def circ_a2a_rand(
320
+ n,
321
+ depth,
322
+ seed=None,
323
+ gate2="cz",
324
+ ):
325
+ if not isinstance(seed, random.Random):
326
+ rng = random.Random(seed)
327
+
328
+ qubits = list(range(n))
329
+
330
+ ent_gates = []
331
+ for _ in range(depth):
332
+ rng.shuffle(qubits)
333
+ for i, j in zip(qubits[::2], qubits[1::2]):
334
+ ent_gates.append((i, j))
335
+
336
+ gates = inject_u3s(ent_gates, gate2=gate2, seed=seed)
337
+ circ = gates_to_param_circuit(gates, n)
338
+
339
+ return circ
340
+
341
+
342
+ def circ_qaoa(
343
+ terms,
344
+ depth,
345
+ gammas,
346
+ betas,
347
+ **circuit_opts,
348
+ ):
349
+ r"""Generate the QAOA circuit for weighted graph described by ``terms``.
350
+
351
+ .. math::
352
+
353
+ |{\bar{\gamma}, \bar{\beta}}\rangle = U_B (\beta _p)
354
+ U_C (\gamma _p) \cdots U_B (\beta _1) U_C (\gamma _1) |{+}\rangle
355
+
356
+ with
357
+
358
+ .. math::
359
+
360
+ U_C (\gamma) = e^{-i \gamma \mathcal{C}} = \prod \limits_{i, j
361
+ \in E(G)} e^{-i \gamma w_{i j} Z_i Z_j}
362
+
363
+ and
364
+
365
+ .. math::
366
+
367
+ U_B (\beta) = \prod \limits_{i \in G} e^{-i \beta X_i}
368
+
369
+
370
+ Parameters
371
+ ----------
372
+ terms : dict[tuple[int], float]
373
+ The mapping of integer pair keys ``(i, j)`` to the edge weight values,
374
+ ``wij``. The integers should be a contiguous range enumerated from
375
+ zero, with the total number of qubits being inferred from this.
376
+ depth : int
377
+ The number of layers of gates to apply, ``p`` above.
378
+ gammas : iterable of float
379
+ The interaction angles for each layer.
380
+ betas : iterable of float
381
+ The rotation angles for each layer.
382
+ circuit_opts
383
+ Supplied to :class:`~quimb.tensor.circuit.Circuit`. Note
384
+ ``gate_opts={'contract': False}`` is set by default (it can be
385
+ overridden) since the RZZ gate, even though it has a rank-2
386
+ decomposition, is also diagonal.
387
+ """
388
+ from .circuit import Circuit
389
+
390
+ circuit_opts.setdefault("gate_opts", {})
391
+ circuit_opts["gate_opts"].setdefault("contract", False)
392
+
393
+ n = max(itertools.chain.from_iterable(terms)) + 1
394
+
395
+ gates = []
396
+
397
+ # layer of hadamards to get into plus state
398
+ for i in range(n):
399
+ gates.append((0, "h", i))
400
+
401
+ for d in range(depth):
402
+ for (i, j), wij in terms.items():
403
+ gates.append((d, "rzz", wij * gammas[d], i, j))
404
+
405
+ for i in range(n):
406
+ gates.append((d, "rx", -betas[d] * 2, i))
407
+
408
+ circ = Circuit(n, **circuit_opts)
409
+ circ.apply_gates(gates)
410
+
411
+ return circ