Skip to content
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

Use Matrix for similar(SpecialMatrix, shape) instead of throwing #15198

Merged
merged 1 commit into from
Feb 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ end
## Constructors ##

# default arguments to similar()
similar{T}(a::AbstractArray{T}) = similar(a, T, size(a))
similar{T}(a::AbstractArray{T}) = similar(a, T)
similar( a::AbstractArray, T::Type) = similar(a, T, size(a))
similar{T}(a::AbstractArray{T}, dims::DimsInteger) = similar(a, T, dims)
similar{T}(a::AbstractArray{T}, dims::Integer...) = similar(a, T, dims)
Expand Down
4 changes: 3 additions & 1 deletion base/linalg/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type Bidiagonal{T} <: AbstractMatrix{T}
dv::Vector{T} # diagonal
ev::Vector{T} # sub/super diagonal
isupper::Bool # is upper bidiagonal (true) or lower (false)
function Bidiagonal{T}(dv::Vector{T}, ev::Vector{T}, isupper::Bool)
function Bidiagonal(dv::Vector{T}, ev::Vector{T}, isupper::Bool)
if length(ev) != length(dv)-1
throw(DimensionMismatch("length of diagonal vector is $(length(dv)), length of off-diagonal vector is $(length(ev))"))
end
Expand Down Expand Up @@ -101,6 +101,8 @@ convert{Tnew,Told}(::Type{AbstractMatrix{Tnew}}, A::Bidiagonal{Told}) = convert(

big(B::Bidiagonal) = Bidiagonal(big(B.dv), big(B.ev), B.isupper)

similar{T}(B::Bidiagonal, ::Type{T}) = Bidiagonal{T}(similar(B.dv, T), similar(B.ev, T), B.isupper)

###################
# LAPACK routines #
###################
Expand Down
7 changes: 2 additions & 5 deletions base/linalg/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ convert{T}(::Type{AbstractMatrix{T}}, D::Diagonal) = convert(Diagonal{T}, D)
convert{T}(::Type{UpperTriangular}, A::Diagonal{T}) = UpperTriangular(A)
convert{T}(::Type{LowerTriangular}, A::Diagonal{T}) = LowerTriangular(A)

function similar{T}(D::Diagonal, ::Type{T}, d::Tuple{Int,Int})
if d[1] != d[2]
throw(ArgumentError("diagonal matrix must be square"))
end
return Diagonal{T}(Array(T,d[1]))
function similar{T}(D::Diagonal, ::Type{T})
return Diagonal{T}(similar(D.diag, T))
end

copy!(D1::Diagonal, D2::Diagonal) = (copy!(D1.diag, D2.diag); D1)
Expand Down
12 changes: 12 additions & 0 deletions base/linalg/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ end
@inbounds r = (A.uplo == 'U') == (i < j) ? A.data[i, j] : conj(A.data[j, i])
r
end

similar{T}(A::Symmetric, ::Type{T}) = Symmetric(similar(A.data, T))
# Hermitian version can be simplified when check for imaginary part of
# diagonal in Hermitian has been removed
function similar{T}(A::Hermitian, ::Type{T})
B = similar(A.data, T)
for i = 1:size(A,1)
B[i,i] = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

real(B[i,i]) ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value shouldn't really matter here.

end
return Hermitian(B)
end

full(A::Symmetric) = copytri!(copy(A.data), A.uplo)
full(A::Hermitian) = copytri!(copy(A.data), A.uplo, true)
parent(A::HermOrSym) = A.data
Expand Down
10 changes: 2 additions & 8 deletions base/linalg/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,8 @@ for t in (:LowerTriangular, :UnitLowerTriangular, :UpperTriangular,
convert{Tnew,Told,S}(::Type{AbstractMatrix{Tnew}}, A::$t{Told,S}) = convert($t{Tnew}, A)
convert{T,S}(::Type{Matrix}, A::$t{T,S}) = convert(Matrix{T}, A)

function similar{T,S,Tnew}(A::$t{T,S}, ::Type{Tnew}, dims::Dims)
if length(dims) != 2
throw(ArgumentError("Triangular matrix must have two dimensions"))
end
if dims[1] != dims[2]
throw(ArgumentError("Triangular matrix must be square"))
end
B = similar(A.data, Tnew, dims)
function similar{T,S,Tnew}(A::$t{T,S}, ::Type{Tnew})
B = similar(A.data, Tnew)
return $t(B)
end

Expand Down
9 changes: 4 additions & 5 deletions base/linalg/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ function size(A::SymTridiagonal, d::Integer)
end
end

similar{T}(S::SymTridiagonal, ::Type{T}) = SymTridiagonal{T}(similar(S.dv, T), similar(S.ev, T))

#Elementary operations
for func in (:conj, :copy, :round, :trunc, :floor, :ceil, :abs, :real, :imag)
@eval ($func)(M::SymTridiagonal) = SymTridiagonal(($func)(M.dv), ($func)(M.ev))
Expand Down Expand Up @@ -361,11 +363,8 @@ function convert{T}(::Type{Matrix{T}}, M::Tridiagonal{T})
A
end
convert{T}(::Type{Matrix}, M::Tridiagonal{T}) = convert(Matrix{T}, M)
function similar(M::Tridiagonal, T, dims::Dims)
if length(dims) != 2 || dims[1] != dims[2]
throw(DimensionMismatch("Tridiagonal matrices must be square"))
end
Tridiagonal{T}(similar(M.dl), similar(M.d), similar(M.du), similar(M.du2))
function similar{T}(M::Tridiagonal, ::Type{T})
Tridiagonal{T}(similar(M.dl, T), similar(M.d, T), similar(M.du, T), similar(M.du2, T))
end

# Operations on Tridiagonal matrices
Expand Down
5 changes: 4 additions & 1 deletion test/linalg/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ for relty in (Int, Float32, Float64, BigFloat), elty in (relty, Complex{relty})
@test_throws DimensionMismatch Bidiagonal(dv,ones(elty,n),true)
@test_throws ArgumentError Bidiagonal(dv,ev)

debug && println("getindex, setindex!, and size")
debug && println("getindex, setindex!, size, and similar")
BD = Bidiagonal(dv, ev, true)
@test_throws BoundsError BD[n+1,1]
@test BD[2,2] == dv[2]
Expand All @@ -44,6 +44,9 @@ for relty in (Int, Float32, Float64, BigFloat), elty in (relty, Complex{relty})
@test BD == cBD
@test_throws ArgumentError size(BD,0)
@test size(BD,3) == 1
@test isa(similar(BD), Bidiagonal{elty})
@test isa(similar(BD, Int), Bidiagonal{Int})
@test isa(similar(BD, Int, (3,2)), Matrix{Int})

debug && println("show")
dstring = sprint(Base.print_matrix,BD.dv')
Expand Down
6 changes: 4 additions & 2 deletions test/linalg/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,10 @@ for relty in (Float32, Float64, BigFloat), elty in (relty, Complex{relty})
end

#similar
@test_throws ArgumentError similar(D, eltype(D), (n,n+1))
@test length(diag(similar(D, eltype(D), (n,n)))) == n
@test isa(similar(D), Diagonal{elty})
@test isa(similar(D, Int), Diagonal{Int})
@test isa(similar(D, (3,2)), Matrix{elty})
@test isa(similar(D, Int, (3,2)), Matrix{Int})

#10036
@test issym(D2)
Expand Down
10 changes: 10 additions & 0 deletions test/linalg/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ let n=10

debug && println("\ntype of a: ", eltya, "\n")

# similar
@test isa(similar(Symmetric(asym)), Symmetric{eltya})
@test isa(similar(Hermitian(asym)), Hermitian{eltya})
@test isa(similar(Symmetric(asym), Int), Symmetric{Int})
@test isa(similar(Hermitian(asym), Int), Hermitian{Int})
@test isa(similar(Symmetric(asym), (3,2)), Matrix{eltya})
@test isa(similar(Hermitian(asym), (3,2)), Matrix{eltya})
@test isa(similar(Symmetric(asym), Int, (3,2)), Matrix{Int})
@test isa(similar(Hermitian(asym), Int, (3,2)), Matrix{Int})

# full
@test asym == full(Hermitian(asym))

Expand Down
8 changes: 6 additions & 2 deletions test/linalg/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,18 @@ for elty1 in (Float32, Float64, BigFloat, Complex64, Complex128, Complex{BigFloa

# similar
@test isa(similar(A1), t1)
@test_throws ArgumentError similar(A1,typeof(A1),(n,n+1))
@test_throws ArgumentError similar(A1,typeof(A1),(n,n,n))
@test eltype(similar(A1)) == elty1
@test isa(similar(A1, Int), t1)
@test eltype(similar(A1, Int)) == Int
@test isa(similar(A1, (3,2)), Matrix{elty1})
@test isa(similar(A1, Int, (3,2)), Matrix{Int})

# getindex
## Linear indexing
for i = 1:length(A1)
@test A1[i] == full(A1)[i]
end
@test isa(A1[2:4,1], Vector)

## Cartesian indexing
for i = 1:size(A1, 1)
Expand Down
11 changes: 8 additions & 3 deletions test/linalg/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ for elty in (Float32, Float64, Complex64, Complex128, Int)
@test_approx_eq x invFsv
@test_approx_eq full(full(Tldlt)) Fs
end

# similar
@test isa(similar(Ts), SymTridiagonal{elty})
@test isa(similar(Ts, Int), SymTridiagonal{Int})
@test isa(similar(Ts, Int, (3,2)), Matrix{Int})
end

# eigenvalues/eigenvectors of symmetric tridiagonal
Expand Down Expand Up @@ -365,9 +370,9 @@ let n = 12 #Size of matrix problem to test
@test size(B) == size(A)
copy!(B,A)
@test B == A
@test_throws DimensionMismatch similar(A,(n,n,2))
@test_throws DimensionMismatch similar(A,(n+1,n))
@test_throws DimensionMismatch similar(A,(n,n+1))
@test isa(similar(A), Tridiagonal{elty})
@test isa(similar(A, Int), Tridiagonal{Int})
@test isa(similar(A, Int, (3,2)), Matrix{Int})
@test size(A,3) == 1
@test_throws ArgumentError size(A,0)

Expand Down