dymad.numerics.linalg¶
Functions
|
The cosine values between v1 and v2. |
|
Expecting U.H * M * V = I |
|
Approach like Exact DMD. |
|
Compute B_i = b @ exp(s_i * W) for i=1..m, in batch. |
|
Compute B_i = b @ exp(s_i * U V^T) for i=1..m, in batch. |
|
Given A = V U^T dt (n x n, rank r) with V, U (n x r), compute logm(A). |
|
Random (Ndim x Ndim) matrix of rank Nrnk, with randomized eigenvalues ranged in zrng and wrng. |
|
Split eigenvalues and modes according to the requested components. |
|
Two-pass randomized SVD for a matrix stored as row-blocks: |
|
Construct a real low-rank factorization V_real @ B @ U_real.T from (possibly complex) eigenpairs of a real matrix A = sum_i lam_i * v_i * u_i^H. |
|
Suppose A U = B U L, V^H A = L V^H B Ideally one should have double diagonalization (for non-degenerate case): V^H B U = I and V^H A U = L but by default each column of U and V is normalized by the length, and the double diagonalization is not satisfied. |
|
Truncation of scalar sequence. |
|
Solve the linear system AX = B by least squares. |
|
A vanilla interface for different types of truncation order. |
- dymad.numerics.linalg.check_direction(v1, v2)¶
The cosine values between v1 and v2.
- dymad.numerics.linalg.check_orthogonality(U, V, M=None)¶
Expecting U.H * M * V = I
- dymad.numerics.linalg.eig_low_rank(U, V)¶
Approach like Exact DMD.
Suppose the full matrix is A = U V^T, with U, V of shape (n, r).
We compute the eigendecomposition of the small matrix A_tilde = V^T U of shape (r, r)
A_tilde = W @ L @ W_inv
Then A = (U W) @ L @ (V W_inv)^H
Furthermore, we scale the left and right eigenvectors so that they are orthonormal.
- dymad.numerics.linalg.expm_full_rank(W, s, b)¶
Compute B_i = b @ exp(s_i * W) for i=1..m, in batch.
- Parameters:
W (
Tensor) – (n, n) full rank matrixs (
Tensor) – (m,) list/1D tensor of scalarsb (
Tensor) – (batch, n) rows are left-multipliers
- Returns:
(m, batch, n) where out[i] = b @ exp(s[i] * W)
- Return type:
out
- dymad.numerics.linalg.expm_low_rank(U, V, s, b)¶
Compute B_i = b @ exp(s_i * U V^T) for i=1..m, in batch.
Uses the identity: exp(sA) = I + U [s * phi_1(s S)] V^T, S = V^T U. So: b @ exp(sA) = b + (bU) [s * phi_1(s S)] V^T.
- Parameters:
U (
Tensor) – (n, r)V (
Tensor) – (n, r)s (
Tensor) – (m,) list/1D tensor of scalarsb (
Tensor) – (batch, n) rows are left-multipliers
- Returns:
(m, batch, n) where out[i] = b @ exp(s[i] * U V^T)
- Return type:
out
- dymad.numerics.linalg.logm_low_rank(V, U, dt=1.0)¶
Given A = V U^T dt (n x n, rank r) with V, U (n x r), compute logm(A).
Technically, this logarithm is ill-defined if A is not full rank, but here we compute the following:
Suppose A has the eigendecomposition A = W @ L @ R^H and we let logm(A) = W @ (log(L)/dt) @ R^H
For computational purpose, we return two real factors of logm(A), with the help of real_lowrank_from_eigpairs.
Notes
This approach does not work when A has negative real eigenvalues.
- Parameters:
V (
ndarray) – (n, r) real arrays Tall factors of A = V U^T. Columns need not be orthonormal.U (
ndarray) – (n, r) real arrays Tall factors of A = V U^T. Columns need not be orthonormal.
- Returns:
- (n, r) real arrays
Tall factors of logm(A).
- Return type:
V_out, U_out
- dymad.numerics.linalg.make_random_matrix(Ndim, Nrnk, zrng, wrng, dt=-1)¶
Random (Ndim x Ndim) matrix of rank Nrnk, with randomized eigenvalues ranged in zrng and wrng. If dt>0 is given, the eigenvalues will be mapped to discrete-time. The eigenpairs are always assumed to be conjugate.
- dymad.numerics.linalg.mode_split(l, U, comp='ri')¶
Split eigenvalues and modes according to the requested components.
Consider r pairs of eigenvalues and modes, modes in shape (r, n), this function splits them as (r, k) and (r, k, n), where k is the number of requested components.
For example, if comp=’ri’, then k=2, and the two components are the real and imaginary parts of the eigenvalues and modes.
- Parameters:
l (
ndarray) – (r,) eigenvaluesU (
ndarray) – (r, n) modescomp (
str) – ‘r’ - real, ‘i’ - imag, ‘a’ - amplitude, ‘p’ - phase, can be composed like ‘ri’, ‘ap’ etc.; default is ‘ri’.
- Returns:
(r, k) U_split: (r, k, n)
- Return type:
l_split
- dymad.numerics.linalg.randomized_svd(loader, N, k, oversample=10, n_iter=0, return_u=False, dtype=<class 'numpy.float64'>, seed=0)¶
Two-pass randomized SVD for a matrix stored as row-blocks:
A^T = [A_0^T, A_1^T, …, A_{N-1}^T]
where A_i shape (n_i, d), A shape (N=sum_i n_i, d)
Two passes estimate k singular values and right singular vectors. A third pass is needed if left singular vectors are requested.
- Parameters:
loader (callable) – A function that takes a block index and returns the corresponding block.
N (int) – Number of blocks
k (int) – Target rank (k > 0).
oversample (int, default 10) – Extra dimensions to improve spectral accuracy (total sketch dim l = k + oversample).
n_iter (int, default 0) – Number of power iterations (each adds two more passes).
return_u (bool, default False) – Whether to return left singular vectors.
dtype (numpy dtype, default np.float64) – Internal precision for computation.
seed (int or None, default 0) – RNG seed for the Gaussian sketch.
- Returns:
(N, k) ndarray, Left singular vectors (columns). S : (k,) ndarray, Singular values in descending order. Vt : (d, k) ndarray, Right singular vectors (columns).
- Return type:
U
- dymad.numerics.linalg.real_lowrank_from_eigpairs(lam, U, V, tol=1e-12)¶
Construct a real low-rank factorization V_real @ B @ U_real.T from (possibly complex) eigenpairs of a real matrix A = sum_i lam_i * v_i * u_i^H.
- Parameters:
lam (
ndarray) – (r,) eigenvaluesU (
ndarray) – (n, r) left eigenvectorsV (
ndarray) – (n, r) right eigenvectorstol (
float) – tolerance to identify real vs complex eigenvalues
- Returns:
(r_real, r_real) block-diagonal (1x1 for real, 2x2 for conjugate pairs) U_real: (m, r_real) V_real: (n, r_real)
- Return type:
B
- dymad.numerics.linalg.scaled_eig(A, B=None)¶
Suppose A U = B U L, V^H A = L V^H B Ideally one should have double diagonalization (for non-degenerate case): V^H B U = I and V^H A U = L but by default each column of U and V is normalized by the length, and the double diagonalization is not satisfied. Here we scale both U and V so that they are approximately orthonormal to each other (w.r.t. B); also the scaling is such that the norms of u_i and v_i are equal.
However, if one needs to project quantities to, e.g., U, use pseudo-inverse of U instead of V for numerical robustness.
- dymad.numerics.linalg.truncate_sequence(seq, order)¶
Truncation of scalar sequence.
Possible order parameters
Float: Max value to retain
Integer: Keep first N values
‘full’: Retain all pairs
- dymad.numerics.linalg.truncated_lstsq(A, B, tsvd=None)¶
Solve the linear system AX = B by least squares.
If truncated SVD is used, the function returns the two factors of X.
- Parameters:
A (np.ndarray) – Coefficient matrix.
B (np.ndarray) – Right-hand side matrix.
tsvd (int or float, optional) – If provided, use truncated SVD with this order.
- Returns:
Solution matrix X, or its two factors.
- Return type:
np.ndarray
- dymad.numerics.linalg.truncated_svd(X, order)¶
A vanilla interface for different types of truncation order.
Possible order parameters
Float, positive: Energy percentage
Float, negative: Optimal truncation by Gavish&Donoho.
Integer, positive: Keep first N pairs
Integer, negative: Remove last N pairs
‘full’: Retain all pairs