Skip to content

Commit e64c6d0

Browse files
committed
Introduce LAPACK.SingularException
throw and catch singular exceptions correctly cond now gives Inf instead of giving an error for ill-conditioned matrices Close #1862
1 parent 5ffb3b0 commit e64c6d0

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed

base/lapack.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ type LapackException <: Exception
1212
info::BlasInt
1313
end
1414

15+
type SingularException <: Exception
16+
info::BlasInt
17+
end
18+
1519
type LapackDimMisMatch <: Exception
1620
name::ASCIIString
1721
end

base/linalg.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ function scale!{T<:Number}(X::StridedArray{T}, s::Real)
88
return X
99
end
1010

11+
scale(X, s) = scale!(copy(X), s)
12+
1113
cross(a::Vector, b::Vector) =
1214
[a[2]*b[3]-a[3]*b[2], a[3]*b[1]-a[1]*b[3], a[1]*b[2]-a[2]*b[1]]
1315

@@ -102,7 +104,7 @@ function cond(a::AbstractMatrix, p)
102104
try
103105
return norm(a, p) * norm(inv(a), p)
104106
catch e
105-
isa(e,LapackException) ? (return Inf) : rethrow(e)
107+
isa(e,LAPACK.SingularException) ? (return Inf) : rethrow(e)
106108
end
107109
end
108110
end

base/linalg_dense.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -592,14 +592,14 @@ function det(A::Matrix)
592592
end
593593

594594
function (\){T<:BlasFloat}(lu::LUDense{T}, B::StridedVecOrMat{T})
595-
if lu.info > 0; error("Singular system"); end
595+
if lu.info > 0; throw(LAPACK.SingularException(info)); end
596596
LAPACK.getrs!('N', lu.lu, lu.ipiv, copy(B))
597597
end
598598

599599
function inv{T<:BlasFloat}(lu::LUDense{T})
600600
m, n = size(lu.lu)
601601
if m != n; error("inv only defined for square matrices"); end
602-
if lu.info > 0; return error("Singular system"); end
602+
if lu.info > 0; return throw(LAPACK.SingularException(info)); end
603603
LAPACK.getri!(copy(lu.lu), lu.ipiv)
604604
end
605605

@@ -638,7 +638,7 @@ Ac_mul_B{T<:BlasFloat}(A::QRDense{T}, B::StridedVecOrMat{T}) =
638638
function (\){T<:BlasFloat}(A::QRDense{T}, B::StridedVecOrMat{T})
639639
n = length(A.tau)
640640
ans, info = LAPACK.trtrs!('U','N','N',A.hh[1:n,:],(A'*B)[1:n,:])
641-
if info > 0; error("Singular system"); end
641+
if info > 0; throw(LAPACK.SingularException(info)); end
642642
return ans
643643
end
644644

@@ -679,7 +679,7 @@ qrp{T<:Real}(x::StridedMatrix{T}) = qrp(float64(x))
679679
function (\){T<:BlasFloat}(A::QRPDense{T}, B::StridedVecOrMat{T})
680680
n = length(A.tau)
681681
x, info = LAPACK.trtrs!('U','N','N',A.hh[1:n,:],(A'*B)[1:n,:])
682-
if info > 0; error("Singular system"); end
682+
if info > 0; throw(LAPACK.SingularException(info)); end
683683
isa(B, Vector) ? x[invperm(A.jpvt)] : x[:,invperm(A.jpvt)]
684684
end
685685

@@ -773,21 +773,21 @@ function (\){T<:BlasFloat}(A::StridedMatrix{T}, B::StridedVecOrMat{T})
773773
if m == n # Square
774774
if istriu(A)
775775
ans, info = LAPACK.trtrs!('U', 'N', 'N', Acopy, X)
776-
if info > 0; error("Singular system"); end
776+
if info > 0; throw(LAPACK.SingularException(info)); end
777777
return ans
778778
end
779779
if istril(A)
780780
ans, info = LAPACK.trtrs!('L', 'N', 'N', Acopy, X)
781-
if info > 0; error("Singular system"); end
781+
if info > 0; throw(LAPACK.SingularException(info)); end
782782
return ans
783783
end
784784
if ishermitian(A)
785785
ans, _, _, info = LAPACK.sysv!('U', Acopy, X)
786-
if info > 0; error("Singular system"); end
786+
if info > 0; throw(LAPACK.SingularException(info)); end
787787
return ans
788788
end
789789
ans, _, _, info = LAPACK.gesv!(Acopy, X)
790-
if info > 0; error("Singular system"); end
790+
if info > 0; throw(LAPACK.SingularException(info)); end
791791
return ans
792792
end
793793
LAPACK.gelsd!(Acopy, X)[1]

0 commit comments

Comments
 (0)