-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Improve linalg error messages and coverage reports, round 2 #12434
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
Changes from 8 commits
0893131
6053820
98c5867
ae0e81d
628a511
12402e3
72ece1c
69de1fd
90e23e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,8 +9,11 @@ arithtype(::Type{Bool}) = Int | |
function scale!(C::AbstractMatrix, A::AbstractMatrix, b::AbstractVector) | ||
m, n = size(A) | ||
p, q = size(C) | ||
if n != length(b) || p != m || q != n | ||
throw(DimensionMismatch()) | ||
if size(A) != size(C) | ||
throw(DimensionMismatch("size of A, $(size(A)), does not match size of C, $(size(C))")) | ||
end | ||
if n != length(b) | ||
throw(DimensionMismatch("second dimension of A, $n, does not match length of b, $(length(b))")) | ||
end | ||
@inbounds for j = 1:n | ||
bj = b[j] | ||
|
@@ -24,8 +27,11 @@ end | |
function scale!(C::AbstractMatrix, b::AbstractVector, A::AbstractMatrix) | ||
m, n = size(A) | ||
p, q = size(C) | ||
if m != length(b) || p != m || q != n | ||
throw(DimensionMismatch()) | ||
if size(A) != size(C) | ||
throw(DimensionMismatch("size of A, $(size(A)), does not match size of C, $(size(C))")) | ||
end | ||
if m != length(b) | ||
throw(DimensionMismatch("first dimension of A, $m, does not match length of b, $(length(b))")) | ||
end | ||
@inbounds for j = 1:n, i = 1:m | ||
C[i,j] = A[i,j]*b[i] | ||
|
@@ -40,14 +46,18 @@ scale(b::Vector, A::Matrix) = scale!(similar(b, promote_type(eltype(A),eltype(b) | |
vecdot{T<:BlasReal}(x::Union{DenseArray{T},StridedVector{T}}, y::Union{DenseArray{T},StridedVector{T}}) = BLAS.dot(x, y) | ||
vecdot{T<:BlasComplex}(x::Union{DenseArray{T},StridedVector{T}}, y::Union{DenseArray{T},StridedVector{T}}) = BLAS.dotc(x, y) | ||
function dot{T<:BlasReal, TI<:Integer}(x::Vector{T}, rx::Union{UnitRange{TI},Range{TI}}, y::Vector{T}, ry::Union{UnitRange{TI},Range{TI}}) | ||
length(rx)==length(ry) || throw(DimensionMismatch()) | ||
if length(rx) != length(ry) | ||
throw(DimensionMismatch("length of rx, $(length(rx)), does not equal length of ry, $(length(ry))")) | ||
end | ||
if minimum(rx) < 1 || maximum(rx) > length(x) || minimum(ry) < 1 || maximum(ry) > length(y) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one still has no information in the |
||
throw(BoundsError()) | ||
end | ||
BLAS.dot(length(rx), pointer(x)+(first(rx)-1)*sizeof(T), step(rx), pointer(y)+(first(ry)-1)*sizeof(T), step(ry)) | ||
end | ||
function dot{T<:BlasComplex, TI<:Integer}(x::Vector{T}, rx::Union{UnitRange{TI},Range{TI}}, y::Vector{T}, ry::Union{UnitRange{TI},Range{TI}}) | ||
length(rx)==length(ry) || throw(DimensionMismatch()) | ||
if length(rx) != length(ry) | ||
throw(DimensionMismatch("length of rx, $(length(rx)), does not equal length of ry, $(length(ry))")) | ||
end | ||
if minimum(rx) < 1 || maximum(rx) > length(x) || minimum(ry) < 1 || maximum(ry) > length(y) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, no info in |
||
throw(BoundsError()) | ||
end | ||
|
@@ -202,10 +212,10 @@ end | |
function gemv!{T<:BlasFloat}(y::StridedVector{T}, tA::Char, A::StridedVecOrMat{T}, x::StridedVector{T}) | ||
mA, nA = lapack_size(tA, A) | ||
if nA != length(x) | ||
throw(DimensionMismatch()) | ||
throw(DimensionMismatch("second dimension of A, $nA, does not match length of x, $(length(x))")) | ||
end | ||
if mA != length(y) | ||
throw(DimensionMismatch()) | ||
throw(DimensionMismatch("first dimension of A, $mA, does not match length of y, $(length(y))")) | ||
end | ||
if mA == 0 | ||
return y | ||
|
@@ -348,10 +358,10 @@ function generic_matvecmul!{T,S,R}(C::AbstractVector{R}, tA, A::AbstractVecOrMat | |
mB = length(B) | ||
mA, nA = lapack_size(tA, A) | ||
if mB != nA | ||
throw(DimensionMismatch("Matrix A has dimensions ($mA,$nA), vector B has length $mB")) | ||
throw(DimensionMismatch("matrix A has dimensions ($mA,$nA), vector B has length $mB")) | ||
end | ||
if mA != length(C) | ||
throw(DimensionMismatch("Result C has length $(length(C)), needs length $mA")) | ||
throw(DimensionMismatch("result C has length $(length(C)), needs length $mA")) | ||
end | ||
z = zero(R) | ||
|
||
|
@@ -404,10 +414,10 @@ function generic_matmatmul!{T,S,R}(C::AbstractVecOrMat{R}, tA, tB, A::AbstractVe | |
mA, nA = lapack_size(tA, A) | ||
mB, nB = lapack_size(tB, B) | ||
if mB != nA | ||
throw(DimensionMismatch("Matrix A has dimensions ($mA, $nB), matrix B has dimensions ($mB, $nB)")) | ||
throw(DimensionMismatch("matrix A has dimensions ($mA, $nB), matrix B has dimensions ($mB, $nB)")) | ||
end | ||
if size(C,1) != mA || size(C,2) != nB | ||
throw(DimensionMismatch("Result C has dimensions $(size(C)), needs ($mA, $nB)")) | ||
throw(DimensionMismatch("result C has dimensions $(size(C)), needs ($mA, $nB)")) | ||
end | ||
|
||
if mA == nA == nB == 2 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,51 +13,67 @@ convert(::Type{UpperTriangular}, A::Bidiagonal) = A.isupper ? UpperTriangular(fu | |
convert(::Type{Matrix}, D::Diagonal) = diagm(D.diag) | ||
|
||
function convert(::Type{UnitUpperTriangular}, A::Diagonal) | ||
all(A.diag .== one(eltype(A))) || throw(ArgumentError("Matrix cannot be represented as UnitUpperTriangular")) | ||
if !all(A.diag .== one(eltype(A))) | ||
throw(ArgumentError("matrix cannot be represented as UnitUpperTriangular")) | ||
end | ||
UnitUpperTriangular(full(A)) | ||
end | ||
|
||
function convert(::Type{UnitLowerTriangular}, A::Diagonal) | ||
all(A.diag .== one(eltype(A))) || throw(ArgumentError("Matrix cannot be represented as UnitLowerTriangular")) | ||
if !all(A.diag .== one(eltype(A))) | ||
throw(ArgumentError("matrix cannot be represented as UnitLowerTriangular")) | ||
end | ||
UnitLowerTriangular(full(A)) | ||
end | ||
|
||
function convert(::Type{Diagonal}, A::Union{Bidiagonal, SymTridiagonal}) | ||
all(A.ev .== 0) || throw(ArgumentError("Matrix cannot be represented as Diagonal")) | ||
if !all(A.ev .== 0) | ||
throw(ArgumentError("matrix cannot be represented as Diagonal")) | ||
end | ||
Diagonal(A.dv) | ||
end | ||
|
||
function convert(::Type{SymTridiagonal}, A::Bidiagonal) | ||
all(A.ev .== 0) || throw(ArgumentError("Matrix cannot be represented as SymTridiagonal")) | ||
if !all(A.ev .== 0) | ||
throw(ArgumentError("matrix cannot be represented as SymTridiagonal")) | ||
end | ||
SymTridiagonal(A.dv, A.ev) | ||
end | ||
|
||
convert{T}(::Type{Tridiagonal}, A::Bidiagonal{T})=Tridiagonal(A.isupper?zeros(T, size(A.dv,1)-1):A.ev, A.dv, A.isupper?A.ev:zeros(T, size(A.dv,1)-1)) | ||
|
||
function convert(::Type{Bidiagonal}, A::SymTridiagonal) | ||
all(A.ev .== 0) || throw(ArgumentError("Matrix cannot be represented as Bidiagonal")) | ||
if !all(A.ev .== 0) | ||
throw(ArgumentError("matrix cannot be represented as Bidiagonal")) | ||
end | ||
Bidiagonal(A.dv, A.ev, true) | ||
end | ||
|
||
function convert(::Type{Diagonal}, A::Tridiagonal) | ||
all(A.dl .== 0) && all(A.du .== 0) || throw(ArgumentError("Matrix cannot be represented as Diagonal")) | ||
if !(all(A.dl .== 0) && all(A.du .== 0)) | ||
throw(ArgumentError("matrix cannot be represented as Diagonal")) | ||
end | ||
Diagonal(A.d) | ||
end | ||
|
||
function convert(::Type{Bidiagonal}, A::Tridiagonal) | ||
if all(A.dl .== 0) return Bidiagonal(A.d, A.du, true) | ||
elseif all(A.du .== 0) return Bidiagonal(A.d, A.dl, false) | ||
else throw(ArgumentError("Matrix cannot be represented as Bidiagonal")) | ||
else throw(ArgumentError("matrix cannot be represented as Bidiagonal")) | ||
end | ||
end | ||
|
||
function convert(::Type{SymTridiagonal}, A::Tridiagonal) | ||
all(A.dl .== A.du) || throw(ArgumentError("Matrix cannot be represented as SymTridiagonal")) | ||
if !all(A.dl .== A.du) | ||
throw(ArgumentError("matrix cannot be represented as SymTridiagonal")) | ||
end | ||
SymTridiagonal(A.d, A.dl) | ||
end | ||
|
||
function convert(::Type{Diagonal}, A::AbstractTriangular) | ||
full(A) == diagm(diag(A)) || throw(ArgumentError("Matrix cannot be represented as Diagonal")) | ||
if full(A) != diagm(diag(A)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @andreasnoack it seems terribly inefficient to do a full conversion here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. That is bananas. Allocating three arrays for an operation that doesn't require a single is not efficient. I'll prepare a fix when this is merged. |
||
throw(ArgumentError("matrix cannot be represented as Diagonal")) | ||
end | ||
Diagonal(diag(A)) | ||
end | ||
|
||
|
@@ -68,7 +84,7 @@ function convert(::Type{Bidiagonal}, A::AbstractTriangular) | |
elseif fA == diagm(diag(A)) + diagm(diag(fA, -1), -1) | ||
return Bidiagonal(diag(A), diag(fA,-1), false) | ||
else | ||
throw(ArgumentError("Matrix cannot be represented as Bidiagonal")) | ||
throw(ArgumentError("matrix cannot be represented as Bidiagonal")) | ||
end | ||
end | ||
|
||
|
@@ -79,7 +95,7 @@ function convert(::Type{Tridiagonal}, A::AbstractTriangular) | |
if fA == diagm(diag(A)) + diagm(diag(fA, 1), 1) + diagm(diag(fA, -1), -1) | ||
return Tridiagonal(diag(fA, -1), diag(A), diag(fA,1)) | ||
else | ||
throw(ArgumentError("Matrix cannot be represented as Tridiagonal")) | ||
throw(ArgumentError("matrix cannot be represented as Tridiagonal")) | ||
end | ||
end | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be split out, and have information in the BoundsError(s)