-
-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cond(A,1) fails to produce Inf for A exactly singular #664
Comments
Thanks for reporting this. We'd have to disable exception throwing from the factorization and return |
I am afraid I will be not able to do a PR (actually I never did one).
Just a comment: I am facing a similar case when estimating the reciprocal condition number of a singular linear operator (e.g., encountered when solving Sylvester and Lyapunov matrix equations, see https://github.com/andreasvarga/MatrixEquations.jl ). Since my solution is far from a perfect one, my hope is to learn how the exact singularity aspect can be handled in the Linear Algebra package of Julia. I hope there exists an elegant way which could serve as paradigm for similar problems (the Sylvester equation solver LAPACK.trsyl! also exits with an error in the singular case). I implemented a wrapper to the LAPACK routine DLACON to estimate 1-norm of an operator. My solution is to force DLACON to produce a large value for the estimated norm by providing large input vectors, when the solution process fails (I used a “try and catch” scheme for detecting singularity errors). The problem is that ANY error is caught in this way. A way to label errors (as done in MATLAB) would be a way for a more specific error control.
Many thanks for your time,
Andreas Varga
Von: Andreas Noack [mailto:[email protected]]
Gesendet: Dienstag, 17. September 2019 13:01
An: JuliaLang/julia
Cc: andreasvarga; Author
Betreff: Re: [JuliaLang/julia] cond(A,1) fails to produce Inf for A exactly singular (#33297)
Thanks for reporting this. We'd have to disable exception throwing from the factorization and return Inf if exactly singular. Would you be able to prepare a PR?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#664?email_source=notifications&email_token=ALJDHEF3ZAVIPIQZTR3I4CDQKC2H3A5CNFSM4IXOC2XKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD64EUEI#issuecomment-532171281> , or mute the thread <https://github.com/notifications/unsubscribe-auth/ALJDHECCERXWAQBSEJSFWLLQKC2H3ANCNFSM4IXOC2XA> . <https://github.com/notifications/beacon/ALJDHEBLI5HRNO5HHYGFCFDQKC2H3A5CNFSM4IXOC2XKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD64EUEI.gif>
[ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "#664?email_source=notifications\u0026email_token=ALJDHEF3ZAVIPIQZTR3I4CDQKC2H3A5CNFSM4IXOC2XKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD64EUEI#issuecomment-532171281", "url": "#664?email_source=notifications\u0026email_token=ALJDHEF3ZAVIPIQZTR3I4CDQKC2H3A5CNFSM4IXOC2XKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD64EUEI#issuecomment-532171281", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } } ]
|
Your choice of course, but doing this kind of small fixes is a great way to contribute, and lowers the bar for future PR (to this project or others). https://www.digitalocean.com/community/tutorials/how-to-create-a-pull-request-on-github is a good tutorial on how to create a PR if you're already familiar with git; for this kind of small PR you can even do the whole thing online by just going into a file on the github web interface and clicking the edit button on top. The offending line here is |
Thanks for the hint. The fix for this bug is easy. Replace the offending line _cond1Inf(A::StridedMatrix{<:BlasFloat}, p::Real) = _cond1Inf(lu(A), p, opnorm(A, p)) in stdlib/LinearAlgebra/dense.jl, with _cond1Inf(A::StridedMatrix{<:BlasFloat}, p::Real) = _cond1Inf(lu(A;check=false), p, opnorm(A, p)) Not so easy is to fix the error in the next line _cond1Inf(A::AbstractMatrix, p::Real) = opnorm(A, p)*opnorm(inv(A), p) where inv(A) fails for singular A with ERROR: LAPACKException(2). This failure can be generated with a = [1 1; 0 0] |
Digging a little bit more, the following errors came up: a = [1 1;0 0] but it works for cond(UpperTriangular(float(a)),1) Similar errors come up for LowerTriangular and Diagonal matrices. Apparently all these errors are related to the attempt to compute the inverses of singular matrices. |
Two possibilities here: computing the inverse using an explicit function _cond1Inf(A::AbstractMatrix, p::Real)
fac = lu(A, check=true)
issuccess(fac) || return convert(real(eltype(A)), Inf)
opnorm(A, p)*opnorm(inv(fac), p)
end or using a |
The lu-based method seems to be the right way, because you have the full control in detecting exact singularity. The solution with try and catch can be unreliable, because there are many ways to produce errors or overlook them (for example, inv(rand(2,1)) or inv(0.)). Many thanks for your help in addressing this issue. |
A small correction: I think the right code is:
Still the warning "Failed factorization of type LU{Float64,Array{Float64,2}}" in the case of singularity is disturbing! |
There is a problem with introducing lu(Diagonal(ones(3,3))) currently fails. cond(Diagonal(ones(3,3)), 1) would fail instead of resulting in julia> cond(Diagonal(ones(3,3)), 1)
1.0 So what can we do here? Should we first make sure that |
What about a |
It's not only the |
Maybe we can add a small helper function around the place where we call |
The following error occurs with Julia V1.1:
A = [1. 1.; 0. 0.]
cond(A,1)
ERROR: SingularException(2)
Stacktrace:
[1] checknonsingular at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\LinearAlgebra\src\factorization.jl:12 [inlined]
[2] #lu!#103(::Bool, ::Function, ::Array{Float64,2}, ::Val{true}) at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\LinearAlgebra\src\lu.jl:41
[3] #lu#107 at .\none:0 [inlined]
[4] lu at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\LinearAlgebra\src\lu.jl:142 [inlined] (repeats 2 times)
[5] _cond1Inf(::Array{Float64,2}, ::Int64) at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\LinearAlgebra\src\dense.jl:1390
[6] cond(::Array{Float64,2}, ::Int64) at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\LinearAlgebra\src\dense.jl:1386
[7] top-level scope at none:0
The result should be Inf, as correctly computed by cond(A,2).
The text was updated successfully, but these errors were encountered: