On Julia 1.1:
julia> using LinearAlgebra
julia> inv(svd(rand(ComplexF64,2,2)))
2脳2 Array{Complex{Float64},2}:
-1.03305+2.82321im -1.07298-3.37716im
0.623141-1.89883im 0.946827+1.23427im
On Julia 1.3:
julia> using LinearAlgebra
julia> inv(svd(rand(ComplexF64,2,2)))
ERROR: MethodError: no method matching eps(::Type{Complex{Float64}})
Closest candidates are:
eps(::Dates.Time) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\Dates\src\types.jl:387
eps(::Dates.Date) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\Dates\src\types.jl:386
eps(::Dates.DateTime) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\Dates\src\types.jl:385
...
Stacktrace:
[1] inv(::SVD{Complex{Float64},Float64,Array{Complex{Float64},2}}) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\LinearAlgebra\src\svd.jl:284
[2] top-level scope at REPL[2]:1
The relevant eps(T) call is here.
I guess I'm to blame for this, because it seems this was introduced in https://github.com/JuliaLang/julia/pull/32126. Sorry 馃う鈥嶁檪
Goes without saying that I'll prepare a PR to fix this :)
Can't you quickly fix it by replacing eps(T)*F.S[1] by eps(abs(F.S[1]))*one(T)?
I was thinking eps(real(T))*F.S[1].
Isn't it better to take the eps of F.S[1] instead of multiplying?
Well, strictly speaking, this would be a slightly different truncation. I chose eps(real(T))*F.S[1] to match what we do in ldiv!.
Personally, I don't mind if we'd drop the truncation altogether. But in any case, I think truncation changes should be discussed in https://github.com/JuliaLang/julia/issues/32880.
On an unrelated note, shouldn't this issue get a bug label (or similar)?
But isn't eps(real(T))*F.S[1] == eps(F.S[1]) just without multiplication? In my suggestion, I forgot that singular values are real, so away goes the abs and the *one(T).
Maybe I'm misunderstanding - which might well be the case when talking about floating point numbers - but why would the two be equivalent? Wouldn't it depend on the value of F.S[1]?
julia> s = rand()
0.9013815392525062
julia> eps(real(typeof(s)))*s == eps(s)
false
julia> eps(real(typeof(s)))*s - eps(s)
8.912460530752368e-17
This value is smaller than eps(s) but in a comparison the difference would still matter, wouldn't it?
But if you divide the difference by s, you get 9.887556093220253e-17, so the _relative_ error of the two epss is below eps(Float64).
This I get. But isn't it the absolute value that matters here? Eventually, in searchsortedlast, we are comparing the elements of F.S to our eps in absolute terms, aren't we?
Sorry for perhaps asking the obvious :)
Most helpful comment
Goes without saying that I'll prepare a PR to fix this :)