DataDrivenDiffEq.jl icon indicating copy to clipboard operation
DataDrivenDiffEq.jl copied to clipboard

truncated_svd() is unable to handle complex matrices

Open clairevalva opened this issue 3 years ago • 3 comments

truncated_svd appears to be unable to handle complex matrices (both with the method of truncation by explicit rank or tolerance). The following code which uses truncated_svd() via DMDSVD() fails.

using DataDrivenDiffEq
freq1 = 2
freq2 = 3
freq3 = 11

dt = 0.1
t = 0:dt:30

x = exp.(1im*freq1*t);
y = exp.(1im*freq2*t);
z = exp.(1im*freq3*t);

X = hcat(x,y,z)';

problem = DiscreteDataDrivenProblem(X, t);
res = solve(problem, DMDSVD());

with errors:

 [1] min(x::Float64, y::ComplexF64)
   @ Base ./operators.jl:433
 [2] truncated_svd(A::Matrix{ComplexF64}, truncation::Float64)
   @ DataDrivenDiffEq ~/.julia/packages/DataDrivenDiffEq/s9jl3/src/koopman/algorithms.jl:3

clairevalva avatar Jul 06 '22 18:07 clairevalva

Currently, we assume(d) the input is Real.

A quick fix would be to compare the magnitude and truncation:

function truncated_svd(A::AbstractMatrix{T}, truncation::Real) where T <: Number
    truncation = min(norm(convert(T, truncation)), norm(one(T)))
    U, S, V = svd(A)
    r = vec(S .> truncation*maximum(S))
    U = U[:, r]
    S = S[r]
    V = V[:, r]
    return U, S, V
end

AlCap23 avatar Jul 07 '22 06:07 AlCap23

We should probably throw an error message much sooner then that makes it clear that complex isn't supported here.

ChrisRackauckas avatar Jul 07 '22 19:07 ChrisRackauckas

An error sooner would be nice :) (But at least for the case of DMDSVD, there is no particular reason intrinsic to the algorithm itself that requires real input.)

clairevalva avatar Jul 07 '22 19:07 clairevalva