Skip to content

Commit 8ef420c

Browse files
Merge pull request #11518 from JuliaLang/ksh/prettify
RFC: prettify single line throws/returns and add more descriptive errors for linalg
2 parents 0623698 + bbc47a8 commit 8ef420c

17 files changed

+590
-216
lines changed

base/linalg/arnoldi.jl

+28-8
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,25 @@ function eigs(A, B;
1818
isgeneral = B !== I
1919
sym = issym(A) && !iscmplx
2020
nevmax=sym ? n-1 : n-2
21-
nevmax > 0 || throw(ArgumentError("Input matrix A is too small. Use eigfact instead."))
21+
if nevmax <= 0
22+
throw(ArgumentError("Input matrix A is too small. Use eigfact instead."))
23+
end
2224
if nev > nevmax
2325
warn("Adjusting nev from $nev to $nevmax")
2426
nev = nevmax
2527
end
26-
nev > 0 || throw(ArgumentError("requested number of eigenvalues (nev) must be ≥ 1, got $nev"))
28+
if nev <= 0
29+
throw(ArgumentError("requested number of eigenvalues (nev) must be ≥ 1, got $nev"))
30+
end
2731
ncvmin = nev + (sym ? 1 : 2)
2832
if ncv < ncvmin
2933
warn("Adjusting ncv from $ncv to $ncvmin")
3034
ncv = ncvmin
3135
end
3236
ncv = blas_int(min(ncv, n))
33-
isgeneral && !isposdef(B) && throw(PosDefException(0))
37+
if isgeneral && !isposdef(B)
38+
throw(PosDefException(0))
39+
end
3440
bmat = isgeneral ? "G" : "I"
3541
isshift = sigma !== nothing
3642

@@ -42,7 +48,9 @@ function eigs(A, B;
4248
which != :LI && which != :SI && which != :BE)
4349
throw(ArgumentError("which must be :LM, :SM, :LR, :SR, :LI, :SI, or :BE, got $(repr(which))"))
4450
end
45-
which != :BE || sym || throw(ArgumentError("which=:BE only possible for real symmetric problem"))
51+
if which == :BE && !sym
52+
throw(ArgumentError("which=:BE only possible for real symmetric problem"))
53+
end
4654
isshift && which == :SM && warn("use of :SM in shift-and-invert mode is not recommended, use :LM to find eigenvalues closest to sigma")
4755

4856
if which==:SM && !isshift # transform into shift-and-invert method with sigma = 0
@@ -57,8 +65,12 @@ function eigs(A, B;
5765
sigma = isshift ? convert(T,sigma) : zero(T)
5866

5967
if !isempty(v0)
60-
length(v0)==n || throw(DimensionMismatch())
61-
eltype(v0)==T || throw(ArgumentError("starting vector must have element type $T, got $(eltype(v0))"))
68+
if length(v0) != n
69+
throw(DimensionMismatch())
70+
end
71+
if eltype(v0) != T
72+
throw(ArgumentError("starting vector must have element type $T, got $(eltype(v0))"))
73+
end
6274
end
6375

6476
whichstr = "LM"
@@ -72,10 +84,18 @@ function eigs(A, B;
7284
whichstr = (!sym ? "SR" : "SA")
7385
end
7486
if which == :LI
75-
whichstr = (!sym ? "LI" : throw(ArgumentError("largest imaginary is meaningless for symmetric eigenvalue problems")))
87+
if !sym
88+
whichstr = "LI"
89+
else
90+
throw(ArgumentError("largest imaginary is meaningless for symmetric eigenvalue problems"))
91+
end
7692
end
7793
if which == :SI
78-
whichstr = (!sym ? "SI" : throw(ArgumentError("smallest imaginary is meaningless for symmetric eigenvalue problems")))
94+
if !sym
95+
whichstr = "SI"
96+
else
97+
throw(ArgumentError("smallest imaginary is meaningless for symmetric eigenvalue problems"))
98+
end
7999
end
80100

81101
# Refer to ex-*.doc files in ARPACK/DOCUMENTS for calling sequence

base/linalg/bidiag.jl

+11-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ type Bidiagonal{T} <: AbstractMatrix{T}
66
ev::Vector{T} # sub/super diagonal
77
isupper::Bool # is upper bidiagonal (true) or lower (false)
88
function Bidiagonal{T}(dv::Vector{T}, ev::Vector{T}, isupper::Bool)
9-
length(ev)==length(dv)-1 ? new(dv, ev, isupper) : throw(DimensionMismatch())
9+
if length(ev)==length(dv)-1
10+
new(dv, ev, isupper)
11+
else
12+
throw(DimensionMismatch("Length of diagonal vector is $(length(dv)), length of off-diagonal vector is $(length(ev))"))
13+
end
1014
end
1115
end
1216
Bidiagonal{T}(dv::AbstractVector{T}, ev::AbstractVector{T}, isupper::Bool)=Bidiagonal{T}(copy(dv), copy(ev), isupper)
@@ -103,7 +107,7 @@ function diag{T}(M::Bidiagonal{T}, n::Integer=0)
103107
elseif -size(M,1)<n<size(M,1)
104108
return zeros(T, size(M,1)-abs(n))
105109
else
106-
throw(BoundsError())
110+
throw(BoundsError("Matrix size is $(size(M)), n is $n"))
107111
end
108112
end
109113

@@ -146,7 +150,7 @@ function A_ldiv_B!(A::Union(Bidiagonal, AbstractTriangular), B::AbstractMatrix)
146150
tmp = similar(B,size(B,1))
147151
n = size(B, 1)
148152
if nA != n
149-
throw(DimensionMismatch())
153+
throw(DimensionMismatch("Size of A is ($nA,$mA), corresponding dimension of B is $n"))
150154
end
151155
for i = 1:size(B,2)
152156
copy!(tmp, 1, B, (i - 1)*n + 1, n)
@@ -163,7 +167,7 @@ for func in (:Ac_ldiv_B!, :At_ldiv_B!)
163167
tmp = similar(B,size(B,1))
164168
n = size(B, 1)
165169
if mA != n
166-
throw(DimensionMismatch())
170+
throw(DimensionMismatch("Size of A' is ($mA,$nA), corresponding dimension of B is $n"))
167171
end
168172
for i = 1:size(B,2)
169173
copy!(tmp, 1, B, (i - 1)*n + 1, n)
@@ -179,8 +183,9 @@ At_ldiv_B(A::Union(Bidiagonal, AbstractTriangular), B::AbstractMatrix) = At_ldiv
179183
#Generic solver using naive substitution
180184
function naivesub!{T}(A::Bidiagonal{T}, b::AbstractVector, x::AbstractVector = b)
181185
N = size(A, 2)
182-
N == length(b) == length(x) || throw(DimensionMismatch())
183-
186+
if N != length(b) || N != length(x)
187+
throw(DimensionMismatch())
188+
end
184189
if !A.isupper #do forward substitution
185190
for j = 1:N
186191
x[j] = b[j]

base/linalg/blas.jl

+68-26
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,23 @@ for (fname, elty) in ((:cblas_zdotu_sub,:Complex128),
149149
end
150150
function dot{T<:BlasReal}(DX::Union(DenseArray{T},StridedVector{T}), DY::Union(DenseArray{T},StridedVector{T}))
151151
n = length(DX)
152-
n == length(DY) || throw(DimensionMismatch("dot product arguments have lengths $(length(DX)) and $(length(DY))"))
152+
if n != length(DY)
153+
throw(DimensionMismatch("dot product arguments have lengths $(length(DX)) and $(length(DY))"))
154+
end
153155
dot(n, pointer(DX), stride(DX, 1), pointer(DY), stride(DY, 1))
154156
end
155157
function dotc{T<:BlasComplex}(DX::Union(DenseArray{T},StridedVector{T}), DY::Union(DenseArray{T},StridedVector{T}))
156158
n = length(DX)
157-
n == length(DY) || throw(DimensionMismatch("dot product arguments have lengths $(length(DX)) and $(length(DY))"))
159+
if n != length(DY)
160+
throw(DimensionMismatch("dot product arguments have lengths $(length(DX)) and $(length(DY))"))
161+
end
158162
dotc(n, pointer(DX), stride(DX, 1), pointer(DY), stride(DY, 1))
159163
end
160164
function dotu{T<:BlasComplex}(DX::Union(DenseArray{T},StridedVector{T}), DY::Union(DenseArray{T},StridedVector{T}))
161165
n = length(DX)
162-
n == length(DY) || throw(DimensionMismatch("dot product arguments have lengths $(length(DX)) and $(length(DY))"))
166+
if n != length(DY)
167+
throw(DimensionMismatch("dot product arguments have lengths $(length(DX)) and $(length(DY))"))
168+
end
163169
dotu(n, pointer(DX), stride(DX, 1), pointer(DY), stride(DY, 1))
164170
end
165171

@@ -219,18 +225,24 @@ for (fname, elty) in ((:daxpy_,:Float64),
219225
end
220226
end
221227
function axpy!{T<:BlasFloat,Ta<:Number}(alpha::Ta, x::Union(DenseArray{T},StridedVector{T}), y::Union(DenseArray{T},StridedVector{T}))
222-
length(x) == length(y) || throw(DimensionMismatch("x has length $(length(x)), but y has length $(length(y))"))
228+
if length(x) != length(y)
229+
throw(DimensionMismatch("x has length $(length(x)), but y has length $(length(y))"))
230+
end
223231
axpy!(length(x), convert(T,alpha), pointer(x), stride(x, 1), pointer(y), stride(y, 1))
224232
y
225233
end
226234

227235
function axpy!{T<:BlasFloat,Ta<:Number,Ti<:Integer}(alpha::Ta, x::Array{T}, rx::Union(UnitRange{Ti},Range{Ti}),
228236
y::Array{T}, ry::Union(UnitRange{Ti},Range{Ti}))
229237

230-
length(rx)==length(ry) || throw(DimensionMismatch())
231-
232-
if minimum(rx) < 1 || maximum(rx) > length(x) || minimum(ry) < 1 || maximum(ry) > length(y)
233-
throw(BoundsError())
238+
if length(rx) != length(ry)
239+
throw(DimensionMismatch("Ranges of differing lengths"))
240+
end
241+
if minimum(rx) < 1 || maximum(rx) > length(x)
242+
throw(BoundsError("Range out of bounds for x, of length $(length(x))"))
243+
end
244+
if minimum(ry) < 1 || maximum(ry) > length(y)
245+
throw(BoundsError("Range out of bounds for y, of length $(length(y))"))
234246
end
235247
axpy!(length(rx), convert(T, alpha), pointer(x)+(first(rx)-1)*sizeof(T), step(rx), pointer(y)+(first(ry)-1)*sizeof(T), step(ry))
236248
y
@@ -269,7 +281,13 @@ for (fname, elty) in ((:dgemv_,:Float64),
269281
# DOUBLE PRECISION A(LDA,*),X(*),Y(*)
270282
function gemv!(trans::Char, alpha::($elty), A::StridedVecOrMat{$elty}, X::StridedVector{$elty}, beta::($elty), Y::StridedVector{$elty})
271283
m,n = size(A,1),size(A,2)
272-
length(X) == (trans == 'N' ? n : m) && length(Y) == (trans == 'N' ? m : n) || throw(DimensionMismatch())
284+
if trans == 'N' && (length(X) != n || length(Y) != m)
285+
throw(DimensionMismatch("A has dimensions $(size(A)), X has length $(length(X)) and Y has length $(length(Y))"))
286+
elseif trans == 'C' && (length(X) != m || length(Y) != n)
287+
throw(DimensionMismatch("A' has dimensions $n, $m, X has length $(length(X)) and Y has length $(length(Y))"))
288+
elseif trans == 'T' && (length(X) != m || length(Y) != n)
289+
throw(DimensionMismatch("A.' has dimensions $n, $m, X has length $(length(X)) and Y has length $(length(Y))"))
290+
end
273291
ccall(($(blasfunc(fname)), libblas), Void,
274292
(Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt}, Ref{$elty},
275293
Ptr{$elty}, Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt},
@@ -340,7 +358,9 @@ for (fname, elty) in ((:dsymv_,:Float64),
340358
function symv!(uplo::Char, alpha::($elty), A::StridedMatrix{$elty}, x::StridedVector{$elty},beta::($elty), y::StridedVector{$elty})
341359
m, n = size(A)
342360
if m != n throw(DimensionMismatch("Matrix A is $m by $n but must be square")) end
343-
if m != length(x) || m != length(y) throw(DimensionMismatch()) end
361+
if m != length(x) || m != length(y)
362+
throw(DimensionMismatch("A has size ($m,$n), x has length $(length(x)), y has length $(length(y))"))
363+
end
344364
ccall(($(blasfunc(fname)), libblas), Void,
345365
(Ref{UInt8}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty},
346366
Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt}, Ref{$elty},
@@ -365,8 +385,12 @@ for (fname, elty) in ((:zhemv_,:Complex128),
365385
@eval begin
366386
function hemv!(uplo::Char, α::$elty, A::StridedMatrix{$elty}, x::StridedVector{$elty}, β::$elty, y::StridedVector{$elty})
367387
n = size(A, 2)
368-
n == length(x) || throw(DimensionMismatch())
369-
size(A, 1) == length(y) || throw(DimensionMismatch())
388+
if n != length(x)
389+
throw(DimensionMismatch("A has size $(size(A)), and x has length $(length(x))"))
390+
end
391+
if size(A, 1) != length(y)
392+
throw(DimensionMismatch("A has size $(size(A)), and y has length $(length(x))"))
393+
end
370394
lda = max(1, stride(A, 2))
371395
incx = stride(x, 1)
372396
incy = stride(y, 1)
@@ -464,7 +488,9 @@ for (fname, elty) in ((:dtrsv_,:Float64),
464488
# DOUBLE PRECISION A(LDA,*),X(*)
465489
function trsv!(uplo::Char, trans::Char, diag::Char, A::StridedMatrix{$elty}, x::StridedVector{$elty})
466490
n = chksquare(A)
467-
n==length(x) || throw(DimensionMismatch("size of A is $n != length(x) = $(length(x))"))
491+
if n != length(x)
492+
throw(DimensionMismatch("size of A is $n != length(x) = $(length(x))"))
493+
end
468494
ccall(($(blasfunc(fname)), libblas), Void,
469495
(Ref{UInt8}, Ref{UInt8}, Ref{UInt8}, Ref{BlasInt},
470496
Ptr{$elty}, Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt}),
@@ -486,8 +512,9 @@ for (fname, elty) in ((:dger_,:Float64),
486512
@eval begin
487513
function ger!::$elty, x::StridedVector{$elty}, y::StridedVector{$elty}, A::StridedMatrix{$elty})
488514
m, n = size(A)
489-
m == length(x) || throw(DimensionMismatch())
490-
n == length(y) || throw(DimensionMismatch())
515+
if m != length(x) || n != length(y)
516+
throw(DimensionMismatch("A has size ($m,$n), x has length $(length(x)), y has length $(length(y))"))
517+
end
491518
ccall(($(blasfunc(fname)), libblas), Void,
492519
(Ref{BlasInt}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty},
493520
Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt}, Ptr{$elty},
@@ -508,7 +535,9 @@ for (fname, elty) in ((:dsyr_,:Float64),
508535
@eval begin
509536
function syr!(uplo::Char, α::$elty, x::StridedVector{$elty}, A::StridedMatrix{$elty})
510537
n = chksquare(A)
511-
length(x) == n || throw(DimensionMismatch("Length of vector must be the same as the matrix dimensions"))
538+
if length(x) != n
539+
throw(DimensionMismatch("A has size ($n,$n), x has length $(length(x))"))
540+
end
512541
ccall(($(blasfunc(fname)), libblas), Void,
513542
(Ref{UInt8}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty},
514543
Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt}),
@@ -525,7 +554,9 @@ for (fname, elty) in ((:zher_,:Complex128),
525554
@eval begin
526555
function her!(uplo::Char, α::$elty, x::StridedVector{$elty}, A::StridedMatrix{$elty})
527556
n = chksquare(A)
528-
length(x) == A || throw(DimensionMismatch("Length of vector must be the same as the matrix dimensions"))
557+
if length(x) != A
558+
throw(DimensionMismatch("A has size ($n,$n), x has length $(length(x))"))
559+
end
529560
ccall(($(blasfunc(fname)), libblas), Void,
530561
(Ref{UInt8}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty},
531562
Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt}),
@@ -559,7 +590,7 @@ for (gemm, elty) in
559590
k = size(A, transA == 'N' ? 2 : 1)
560591
n = size(B, transB == 'N' ? 2 : 1)
561592
if m != size(C,1) || n != size(C,2)
562-
throw(DimensionMismatch())
593+
throw(DimensionMismatch("A has size ($m,$k), B has size ($k,$n), C has size $(size(C))"))
563594
end
564595
ccall(($(blasfunc(gemm)), libblas), Void,
565596
(Ref{UInt8}, Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt},
@@ -667,7 +698,7 @@ for (fname, elty) in ((:dsyrk_,:Float64),
667698
beta::($elty), C::StridedMatrix{$elty})
668699
n = chksquare(C)
669700
nn = size(A, trans == 'N' ? 1 : 2)
670-
if nn != n throw(DimensionMismatch("syrk!")) end
701+
if nn != n throw(DimensionMismatch("C has size ($n,$n), corresponding dimension of A is $nn")) end
671702
k = size(A, trans == 'N' ? 2 : 1)
672703
ccall(($(blasfunc(fname)), libblas), Void,
673704
(Ref{UInt8}, Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt},
@@ -701,7 +732,10 @@ for (fname, elty, relty) in ((:zherk_, :Complex128, :Float64),
701732
function herk!(uplo::Char, trans::Char, α::$relty, A::StridedVecOrMat{$elty},
702733
β::$relty, C::StridedMatrix{$elty})
703734
n = chksquare(C)
704-
n == size(A, trans == 'N' ? 1 : 2) || throw(DimensionMismatch("the matrix to update has dimension $n but the implied dimension of the update is $(size(A, trans == 'N' ? 1 : 2))"))
735+
nn = size(A, trans == 'N' ? 1 : 2)
736+
if nn != n
737+
throw(DimensionMismatch("the matrix to update has dimension $n but the implied dimension of the update is $(size(A, trans == 'N' ? 1 : 2))"))
738+
end
705739
k = size(A, trans == 'N' ? 2 : 1)
706740
ccall(($(blasfunc(fname)), libblas), Void,
707741
(Ref{UInt8}, Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt},
@@ -740,7 +774,7 @@ for (fname, elty) in ((:dsyr2k_,:Float64),
740774
beta::($elty), C::StridedMatrix{$elty})
741775
n = chksquare(C)
742776
nn = size(A, trans == 'N' ? 1 : 2)
743-
if nn != n throw(DimensionMismatch("syr2k!")) end
777+
if nn != n throw(DimensionMismatch("C has size ($n,$n), corresponding dimension of A is $nn")) end
744778
k = size(A, trans == 'N' ? 2 : 1)
745779
ccall(($(blasfunc(fname)), libblas), Void,
746780
(Ref{UInt8}, Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt},
@@ -776,7 +810,8 @@ for (fname, elty1, elty2) in ((:zher2k_,:Complex128,:Float64), (:cher2k_,:Comple
776810
A::StridedVecOrMat{$elty1}, B::StridedVecOrMat{$elty1},
777811
beta::($elty2), C::StridedMatrix{$elty1})
778812
n = chksquare(C)
779-
n == size(A, trans == 'N' ? 1 : 2) || throw(DimensionMismatch("her2k!"))
813+
nn = size(A, trans == 'N' ? 1 : 2)
814+
if nn != n throw(DimensionMismatch("C has size ($n,$n), corresponding dimension of A is $nn")) end
780815
k = size(A, trans == 'N' ? 2 : 1)
781816
ccall(($(blasfunc(fname)), libblas), Void,
782817
(Ref{UInt8}, Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt},
@@ -836,7 +871,9 @@ for (mmname, smname, elty) in
836871
alpha::$elty, A::StridedMatrix{$elty}, B::StridedMatrix{$elty})
837872
m, n = size(B)
838873
k = chksquare(A)
839-
k==(side == 'L' ? m : n) || throw(DimensionMismatch("size of A is $n, size(B)=($m,$n) and transa='$transa'"))
874+
if k != (side == 'L' ? m : n)
875+
throw(DimensionMismatch("size of A is $n, size(B)=($m,$n) and transa='$transa'"))
876+
end
840877
ccall(($(blasfunc(smname)), libblas), Void,
841878
(Ref{UInt8}, Ref{UInt8}, Ref{UInt8}, Ref{UInt8},
842879
Ref{BlasInt}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty},
@@ -856,10 +893,15 @@ end # module
856893

857894
function copy!{T<:BlasFloat,Ti<:Integer}(dest::Array{T}, rdest::Union(UnitRange{Ti},Range{Ti}),
858895
src::Array{T}, rsrc::Union(UnitRange{Ti},Range{Ti}))
859-
if minimum(rdest) < 1 || maximum(rdest) > length(dest) || minimum(rsrc) < 1 || maximum(rsrc) > length(src)
860-
throw(BoundsError())
896+
if minimum(rdest) < 1 || maximum(rdest) > length(dest)
897+
throw(BoundsError("Range out of bounds for dest, of length $(length(dest))"))
898+
end
899+
if minimum(rsrc) < 1 || maximum(rsrc) > length(src)
900+
throw(BoundsError("Range out of bounds for src, of length $(length(src))"))
901+
end
902+
if length(rdest) != length(rsrc)
903+
throw(DimensionMismatch("Ranges must be of the same length"))
861904
end
862-
length(rdest)==length(rsrc) || throw(DimensionMismatch("Ranges must be of the same length"))
863905
BLAS.blascopy!(length(rsrc), pointer(src)+(first(rsrc)-1)*sizeof(T), step(rsrc),
864906
pointer(dest)+(first(rdest)-1)*sizeof(T), step(rdest))
865907
dest

base/linalg/bunchkaufman.jl

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ end
1414
BunchKaufman{T}(LD::AbstractMatrix{T}, ipiv::Vector{BlasInt}, uplo::Char, symmetric::Bool) = BunchKaufman{T,typeof(LD)}(LD, ipiv, uplo, symmetric)
1515

1616
function bkfact!{T<:BlasReal}(A::StridedMatrix{T}, uplo::Symbol=:U, symmetric::Bool=issym(A))
17-
symmetric || throw(ArgumentError("Bunch-Kaufman decomposition is only valid for symmetric matrices"))
17+
if !symmetric
18+
throw(ArgumentError("Bunch-Kaufman decomposition is only valid for symmetric matrices"))
19+
end
1820
LD, ipiv = LAPACK.sytrf!(char_uplo(uplo) , A)
1921
BunchKaufman(LD, ipiv, char_uplo(uplo), symmetric)
2022
end

base/linalg/cholesky.jl

+3-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ function chol{T}(A::AbstractMatrix{T}, uplo::Union(Type{Val{:L}}, Type{Val{:U}})
8585
end
8686
function chol!(x::Number, uplo)
8787
rx = real(x)
88-
rx == abs(x) || throw(DomainError())
88+
if rx != abs(x)
89+
throw(DomainError("x must be positive semidefinite"))
90+
end
8991
rxr = sqrt(rx)
9092
convert(promote_type(typeof(x), typeof(rxr)), rxr)
9193
end

0 commit comments

Comments
 (0)