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,514 +0,0 @@
1
- """Randomized iterative methods for decompositions.
2
- """
3
- from numbers import Integral
4
-
5
- import numpy as np
6
- import scipy.linalg as sla
7
-
8
- from ..gen.rand import randn
9
- from ..core import dag, dot, njit
10
- from ..utils import identity
11
-
12
-
13
- def lu_orthog(X):
14
- return sla.lu(X, permute_l=True, overwrite_a=True, check_finite=False)[0]
15
-
16
-
17
- def qr_orthog(X):
18
- return sla.qr(X, mode="economic", overwrite_a=True, check_finite=False)[0]
19
-
20
-
21
- def orthog(X, lu=False):
22
- if lu:
23
- return lu_orthog(X)
24
- return qr_orthog(X)
25
-
26
-
27
- def QB_to_svd(Q, B, compute_uv=True):
28
- UsV = sla.svd(
29
- B,
30
- full_matrices=False,
31
- compute_uv=compute_uv,
32
- overwrite_a=True,
33
- check_finite=False,
34
- )
35
-
36
- if not compute_uv:
37
- return UsV
38
-
39
- U, s, V = UsV
40
- return dot(Q, U), s, V
41
-
42
-
43
- def trim(arrays, k):
44
- if isinstance(arrays, tuple) and len(arrays) == 3:
45
- U, s, VH = arrays
46
- U, s, VH = U[:, :k], s[:k], VH[:k, :]
47
- return U, s, VH
48
- if isinstance(arrays, tuple) and len(arrays) == 2:
49
- # Q, B factors
50
- Q, B = arrays
51
- return Q[:, :k], B[:k, :]
52
- else:
53
- # just singular values
54
- return arrays[:k]
55
-
56
-
57
- def possibly_extend_randn(G, k, p, A):
58
- # make sure we are using block of the right size by removing or adding
59
- kG = G.shape[1]
60
- if kG > k + p:
61
- # have too many columns
62
- G = G[:, : k + p]
63
- elif kG < k + p:
64
- # have too few columns
65
- G_extra = randn((A.shape[1], k + p - kG), dtype=A.dtype)
66
- G = np.concatenate((G, G_extra), axis=1)
67
- return G
68
-
69
-
70
- def isstring(x, s):
71
- if not isinstance(x, str):
72
- return False
73
- return x == s
74
-
75
-
76
- def rsvd_qb(A, k, q, p, state, AH=None):
77
- if AH is None:
78
- AH = dag(A)
79
-
80
- # generate first block
81
- if isstring(state, "begin-qb"):
82
- G = randn((A.shape[1], k + p), dtype=A.dtype)
83
- # block already supplied
84
- elif len(state) == 1:
85
- (G,) = state
86
- # mid-way through adaptive algorithm in QB mode
87
- if len(state) == 3:
88
- Q, B, G = state
89
- else:
90
- Q = np.empty((A.shape[0], 0), dtype=A.dtype)
91
- B = np.empty((0, A.shape[1]), dtype=A.dtype)
92
-
93
- QH, BH = dag(Q), dag(B)
94
- G = possibly_extend_randn(G, k, p, A)
95
-
96
- Qi = orthog(dot(A, G) - dot(Q, dot(B, G)), lu=q > 0)
97
-
98
- for i in range(1, q + 1):
99
- Qi = orthog(dot(AH, Qi) - dot(BH, dot(QH, Qi)), lu=True)
100
- Qi = orthog(dot(A, Qi) - dot(Q, dot(B, Qi)), lu=i != q)
101
-
102
- Qi = orthog(Qi - dot(Q, dot(QH, Qi)))
103
- Bi = dag(dot(AH, Qi)) - dot(dot(dag(Qi), Q), B)
104
-
105
- if p > 0:
106
- Qi, Bi = trim((Qi, Bi), k)
107
-
108
- Q = np.concatenate((Q, Qi), axis=1)
109
- B = np.concatenate((B, Bi), axis=0)
110
-
111
- return Q, B, G
112
-
113
-
114
- def rsvd_core(A, k, compute_uv=True, q=2, p=0, state=None, AH=None):
115
- """Core R3SVD algorithm.
116
-
117
- Parameters
118
- ----------
119
- A : linear operator, shape (m, n)
120
- Operator to decompose, assumed m >= n.
121
- k : int
122
- Number of singular values to find.
123
- compute_uv : bool, optional
124
- Return the left and right singular vectors.
125
- q : int, optional
126
- Number of power iterations.
127
- p : int, optional
128
- Over sampling factor.
129
- state : {None, array_like, (), (G0,), (U0, s0, VH0, G0)}, optional
130
- Iterate based on these previous results:
131
-
132
- - None: basic mode.
133
- - array_like: use this as the initial subspace.
134
- - 'begin-svd': begin block iterations, return U, s, VH, G
135
- - (G0,) : begin block iterations with this subspace
136
- - (U0, s0, VH0, G0): continue block iterations, return G
137
-
138
- """
139
- iterating = isinstance(state, (tuple, str))
140
- maybe_project_left = maybe_project_right = identity
141
-
142
- if AH is None:
143
- AH = dag(A)
144
-
145
- # generate first block
146
- if state is None or isstring(state, "begin-svd"):
147
- G = randn((A.shape[1], k + p), dtype=A.dtype)
148
- # initial block supplied
149
- elif hasattr(state, "shape"):
150
- G = state
151
- elif len(state) == 1:
152
- (G,) = state
153
- # mid-way through adaptive algorithm in SVD mode
154
- elif len(state) == 4:
155
- U0, s0, VH0, G = state
156
- UH0, V0 = dag(U0), dag(VH0)
157
-
158
- def maybe_project_left(X):
159
- X -= dot(U0, dot(UH0, X))
160
- return X
161
-
162
- def maybe_project_right(X):
163
- X -= dot(V0, dot(VH0, X))
164
- return X
165
-
166
- G = possibly_extend_randn(G, k, p, A)
167
- G = maybe_project_right(G)
168
-
169
- Q = dot(A, G)
170
- Q = maybe_project_left(Q)
171
- Q = orthog(Q, lu=q > 0)
172
-
173
- # power iterations with stabilization
174
- for i in range(1, q + 1):
175
- Q = dot(AH, Q)
176
- Q = maybe_project_right(Q)
177
- Q = orthog(Q, lu=True)
178
-
179
- Q = dot(A, Q)
180
- Q = maybe_project_left(Q)
181
- Q = orthog(Q, lu=i < q)
182
-
183
- B = dag(dot(AH, Q))
184
- UsVH = QB_to_svd(Q, B, compute_uv=compute_uv or iterating)
185
- if p > 0:
186
- UsVH = trim(UsVH, k)
187
-
188
- if not iterating:
189
- return UsVH
190
-
191
- U, s, VH = UsVH
192
-
193
- if isstring(state, "begin-svd") or len(state) == 1:
194
- # first run -> don't need to project or concatenate anything
195
- return U, s, VH, G
196
-
197
- U = orthog(maybe_project_left(U))
198
- VH = dag(orthog(maybe_project_right(dag(VH))))
199
-
200
- U = np.concatenate((U0, U), axis=1)
201
- s = np.concatenate((s0, s))
202
- VH = np.concatenate((VH0, VH), axis=0)
203
-
204
- return U, s, VH, G
205
-
206
-
207
- @njit
208
- def is_sorted(x): # pragma: no cover
209
- for i in range(x.size - 1):
210
- if x[i + 1] < x[i]:
211
- return False
212
- return True
213
-
214
-
215
- def gen_k_steps(start, incr=1.4):
216
- yield start
217
- step = start
218
- while True:
219
- yield step
220
- step = round(incr * step)
221
-
222
-
223
- def rsvd_iterate(
224
- A,
225
- eps,
226
- compute_uv=True,
227
- q=2,
228
- p=0,
229
- G0=None,
230
- k_max=None,
231
- k_start=2,
232
- k_incr=1.4,
233
- AH=None,
234
- use_qb=20,
235
- ):
236
- """Handle rank-adaptively calling ``rsvd_core``."""
237
-
238
- if AH is None:
239
- AH = dag(A)
240
-
241
- # perform first iteration and set initial rank
242
- k_steps = gen_k_steps(k_start, k_incr)
243
- rank = next(k_steps)
244
-
245
- if use_qb:
246
- Q, B, G = rsvd_qb(
247
- A, rank, q=q, p=p, AH=AH, state="begin-qb" if G0 is None else (G0,)
248
- )
249
- U, s, VH = QB_to_svd(Q, B)
250
- G -= dot(dag(VH), dot(VH, G))
251
- else:
252
- U, s, VH, G = rsvd_core(
253
- A,
254
- rank,
255
- q=q,
256
- p=p,
257
- AH=AH,
258
- state="begin-svd" if G0 is None else (G0,),
259
- )
260
-
261
- # perform randomized SVD in small blocks
262
- while (s[-1] > eps * s[0]) and (rank < k_max):
263
- # only step k as far as k_max
264
- new_k = min(next(k_steps), k_max - rank)
265
- rank += new_k
266
-
267
- if (rank < use_qb) or (use_qb is True):
268
- Q, B, G = rsvd_qb(A, new_k, q=q, p=p, state=(Q, B, G), AH=AH)
269
- U, s, VH = QB_to_svd(Q, B)
270
- G -= dot(dag(VH), dot(VH, G))
271
- else:
272
- # concatenate new U, s, VH orthogonal to current U, s, VH
273
- U, s, VH, G = rsvd_core(
274
- A, new_k, q=q, p=p, state=(U, s, VH, G), AH=AH
275
- )
276
-
277
- # make sure singular values always sorted in decreasing order
278
- if not is_sorted(s):
279
- so = np.argsort(s)[::-1]
280
- U, s, VH = U[:, so], s[so], VH[so, :]
281
-
282
- return U, s, VH if compute_uv else s
283
-
284
-
285
- @njit
286
- def count_svdvals_needed(s, eps): # pragma: no cover
287
- n = s.size
288
- thresh = eps * s[0]
289
- for i in range(n - 1, 0, -1):
290
- if s[i - 1] < thresh:
291
- n -= 1
292
- else:
293
- break
294
- return n
295
-
296
-
297
- def isdouble(dtype):
298
- """Check if ``dtype`` is double precision."""
299
- return dtype in ("float64", "complex128")
300
-
301
-
302
- def estimate_rank(
303
- A,
304
- eps,
305
- k_max=None,
306
- use_sli=True,
307
- k_start=2,
308
- k_incr=1.4,
309
- q=0,
310
- p=0,
311
- get_vectors=False,
312
- G0=None,
313
- AH=None,
314
- use_qb=20,
315
- ):
316
- """Estimate the rank of an linear operator. Uses a low quality random
317
- SVD with a resolution of ~ 10.
318
-
319
- Parameters
320
- ----------
321
- A : linear operator
322
- The operator to find rank of.
323
- eps : float
324
- Find rank to this relative (compared to largest singular value)
325
- precision.
326
- k_max : int, optional
327
- The maximum rank to find.
328
- use_sli : bool, optional
329
- Whether to use :func:`scipy.linalg.interpolative.estimate_rank` if
330
- possible (double precision and no ``k_max`` set).
331
- k_start : int, optional
332
- Begin the adaptive SVD with a block of this size.
333
- k_incr : float, optional
334
- Adaptive rank increment factor. Increase the k-step (from k_start) by
335
- this factor each time. Set to 1 to use a constant step.
336
- q : int, optional
337
- Number of power iterations.
338
- get_vectors : bool, optional
339
- Return the right singular vectors found in the pass.
340
- G0 : , optional
341
-
342
- Returns
343
- -------
344
- rank : int
345
- The rank.
346
- VH : array
347
- The (adjoint) right singular vectors if ``get_vectors=True``.
348
- """
349
- if k_max is None:
350
- k_max = min(A.shape)
351
- if eps <= 0.0:
352
- return k_max
353
-
354
- use_sli = (
355
- use_sli
356
- and (k_max == min(A.shape))
357
- and isdouble(A.dtype)
358
- and not get_vectors
359
- )
360
- if use_sli:
361
- return sla.interpolative.estimate_rank(A, eps)
362
-
363
- if A.shape[0] < A.shape[1]:
364
- A = A.T
365
- if get_vectors:
366
- raise ValueError
367
- if AH is None:
368
- AH = dag(A)
369
-
370
- _, s, VH = rsvd_iterate(
371
- A,
372
- eps,
373
- q=q,
374
- p=p,
375
- G0=G0,
376
- AH=AH,
377
- use_qb=use_qb,
378
- k_start=k_start,
379
- k_max=k_max,
380
- k_incr=k_incr,
381
- )
382
-
383
- rank = count_svdvals_needed(s, eps)
384
-
385
- if get_vectors:
386
- return rank, VH[:rank, :]
387
- return rank
388
-
389
-
390
- def maybe_flip(UsV, flipped):
391
- # if only singular values or only tranposing do nothing
392
- if not (isinstance(UsV, tuple) and flipped):
393
- return UsV
394
- U, s, V = UsV
395
- return V.T, s, U.T
396
-
397
-
398
- def rsvd(
399
- A,
400
- eps_or_k,
401
- compute_uv=True,
402
- mode="adapt+block",
403
- use_qb=20,
404
- q=2,
405
- p=0,
406
- k_max=None,
407
- k_start=2,
408
- k_incr=1.4,
409
- G0=None,
410
- AH=None,
411
- ):
412
- """Fast, randomized, iterative SVD. Adaptive variant of method due
413
- originally to Halko. This scales as ``log(k)`` rather than ``k`` so can be
414
- more efficient.
415
-
416
- Parameters
417
- ----------
418
- A : operator, shape (m, n)
419
- The operator to decompose.
420
- eps_or_k : float or int
421
- Either the relative precision or the number of singular values to
422
- target. If precision, this is relative to the largest singular value.
423
- compute_uv : bool, optional
424
- Whether to return the left and right singular vectors.
425
- mode : {'adapt+block', 'adapt', 'block'}, optional
426
- How to perform the randomized SVD. If ``eps_or_k`` is an integer then
427
- this is implicitly 'block' and ignored. Else:
428
-
429
- - 'adapt+block', perform an initial low quality pass to estimate
430
- the rank of ``A``, then use the subspace and rank from that to
431
- perform an accurate fully blocked RSVD.
432
- - 'adapt', just perform the adaptive randomized SVD.
433
-
434
- q : int, optional
435
- The number of power iterations, increase for accuracy at the expense
436
- of runtime.
437
- p : int, optional
438
- Oversampling factor. Perform projections with this many extra columns
439
- and then throw then away.
440
- k_max : int, optional
441
- Maximum adaptive rank. Default: ``min(A.shape)``.
442
- k_start : int, optional
443
- Initial k when increasing rank adaptively.
444
- k_incr : float, optional
445
- Adaptive rank increment factor. Increase the k-step (from k_start) by
446
- this factor each time. Set to 1 to use a constant step.
447
- G0 : array_like, shape (n, k), optional
448
- Initial subspace to start iterating on. If not given a random one will
449
- be generated.
450
-
451
- Returns
452
- -------
453
- U, array, shape (m, k)
454
- Left singular vectors, if ``compute_uv=True``.
455
- s, array, shape (k,)
456
- Singular values.
457
- V, array, shape (k, n)
458
- Right singular vectors, if ``compute_uv=True``.
459
- """
460
-
461
- flipped = A.shape[0] < A.shape[1]
462
- if flipped:
463
- A = A.T
464
-
465
- # 'block' mode -> just perform single pass random SVD
466
- if isinstance(eps_or_k, Integral):
467
- UsV = rsvd_core(A, eps_or_k, q=q, p=p, state=G0, compute_uv=compute_uv)
468
- return maybe_flip(UsV, flipped)
469
-
470
- if k_max is None:
471
- k_max = min(A.shape)
472
- k_max = min(max(1, k_max), min(A.shape))
473
-
474
- if AH is None:
475
- AH = dag(A)
476
-
477
- adaptive_opts = {
478
- "k_start": k_start,
479
- "k_max": k_max,
480
- "k_incr": k_incr,
481
- "use_qb": use_qb,
482
- "AH": AH,
483
- "G0": G0,
484
- }
485
-
486
- # 'adapt' mode -> rank adaptively perform SVD to low accuracy
487
- if mode == "adapt":
488
- UsV = rsvd_iterate(
489
- A, eps_or_k, q=q, p=p, compute_uv=compute_uv, **adaptive_opts
490
- )
491
-
492
- # 'adapt+block' mode -> use first pass to find rank, then use blocking mode
493
- elif mode == "adapt+block":
494
- # estimate both rank and get approximate spanning vectors
495
- k, VH = estimate_rank(A, eps_or_k, get_vectors=True, **adaptive_opts)
496
-
497
- # reuse vectors to effectively boost number of power iterations by one
498
- UsV = rsvd_core(
499
- A,
500
- k,
501
- q=max(q - 1, 0),
502
- p=p,
503
- AH=AH,
504
- state=dag(VH),
505
- compute_uv=compute_uv,
506
- )
507
-
508
- else:
509
- raise ValueError(
510
- "``mode`` must be one of {'adapt+block', 'adapt'} or"
511
- " ``k`` should be a integer to use 'block' mode."
512
- )
513
-
514
- return maybe_flip(UsV, flipped)