Skip to content

Commit e0d75d7

Browse files
committed
constructors for bidiagonal, diagonal, tridiagonal for consistency; also accept Range inputs
1 parent 6472a57 commit e0d75d7

File tree

6 files changed

+35
-5
lines changed

6 files changed

+35
-5
lines changed

base/linalg/bidiag.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ type Bidiagonal{T} <: AbstractMatrix{T}
1212
new(dv, ev, isupper)
1313
end
1414
end
15-
Bidiagonal{T}(dv::AbstractVector{T}, ev::AbstractVector{T}, isupper::Bool) = Bidiagonal{T}(dv, ev, isupper)
16-
Bidiagonal{T}(dv::AbstractVector{T}, ev::AbstractVector{T}) = throw(ArgumentError("did you want an upper or lower Bidiagonal? Try again with an additional true (upper) or false (lower) argument."))
15+
Bidiagonal{T}(dv::AbstractVector{T}, ev::AbstractVector{T}, isupper::Bool) = Bidiagonal{T}(collect(dv), collect(ev), isupper)
16+
Bidiagonal(dv::AbstractVector, ev::AbstractVector) = throw(ArgumentError("did you want an upper or lower Bidiagonal? Try again with an additional true (upper) or false (lower) argument."))
1717

1818
#Convert from BLAS uplo flag to boolean internal
1919
Bidiagonal(dv::AbstractVector, ev::AbstractVector, uplo::Char) = begin
@@ -24,7 +24,7 @@ Bidiagonal(dv::AbstractVector, ev::AbstractVector, uplo::Char) = begin
2424
else
2525
throw(ArgumentError("Bidiagonal uplo argument must be upper 'U' or lower 'L', got $(repr(uplo))"))
2626
end
27-
Bidiagonal(copy(dv), copy(ev), isupper)
27+
Bidiagonal(collect(dv), collect(ev), isupper)
2828
end
2929
function Bidiagonal{Td,Te}(dv::AbstractVector{Td}, ev::AbstractVector{Te}, isupper::Bool)
3030
T = promote_type(Td,Te)

base/linalg/diagonal.jl

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ immutable Diagonal{T} <: AbstractMatrix{T}
66
diag::Vector{T}
77
end
88
Diagonal(A::AbstractMatrix) = Diagonal(diag(A))
9+
Diagonal(V::AbstractVector) = Diagonal(collect(V))
910

1011
convert{T}(::Type{Diagonal{T}}, D::Diagonal{T}) = D
1112
convert{T}(::Type{Diagonal{T}}, D::Diagonal) = Diagonal{T}(convert(Vector{T}, D.diag))

base/linalg/tridiag.jl

+17-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ end
1616

1717
SymTridiagonal{T}(dv::Vector{T}, ev::Vector{T}) = SymTridiagonal{T}(dv, ev)
1818

19-
function SymTridiagonal{Td,Te}(dv::Vector{Td}, ev::Vector{Te})
19+
function SymTridiagonal{Td,Te}(dv::AbstractVector{Td}, ev::AbstractVector{Te})
2020
T = promote_type(Td,Te)
2121
SymTridiagonal(convert(Vector{T}, dv), convert(Vector{T}, ev))
2222
end
@@ -271,17 +271,32 @@ immutable Tridiagonal{T} <: AbstractMatrix{T}
271271
du::Vector{T} # sup-diagonal
272272
du2::Vector{T} # supsup-diagonal for pivoting
273273
end
274+
275+
# Basic constructor takes in three dense vectors of same type
274276
function Tridiagonal{T}(dl::Vector{T}, d::Vector{T}, du::Vector{T})
275277
n = length(d)
276278
if (length(dl) != n-1 || length(du) != n-1)
277279
throw(ArgumentError("Cannot make Tridiagonal from incompatible lengths of subdiagonal, diagonal and superdiagonal: ($(length(dl)), $(length(d)), $(length(du))"))
278280
end
279281
Tridiagonal(dl, d, du, zeros(T,n-2))
280282
end
281-
function Tridiagonal{Tl, Td, Tu}(dl::Vector{Tl}, d::Vector{Td}, du::Vector{Tu})
283+
284+
# Construct from diagonals of any abstract vector, any eltype
285+
function Tridiagonal{Tl, Td, Tu}(dl::AbstractVector{Tl}, d::AbstractVector{Td}, du::AbstractVector{Tu})
282286
Tridiagonal(map(v->convert(Vector{promote_type(Tl,Td,Tu)}, v), (dl, d, du))...)
283287
end
284288

289+
# Provide a constructor Tridiagonal(A) similar to the triangulars, diagonal, symmetric
290+
"""
291+
Tridiagonal(A)
292+
293+
returns a `Tridiagonal` array based on (abstract) matrix `A`, using its lower diagonal,
294+
diagonal, and upper diagonal.
295+
"""
296+
function Tridiagonal(A::AbstractMatrix)
297+
return Tridiagonal(diag(A,-1), diag(A), diag(A,+1))
298+
end
299+
285300
size(M::Tridiagonal) = (length(M.d), length(M.d))
286301
function size(M::Tridiagonal, d::Integer)
287302
if d < 1

test/linalg/bidiag.jl

+3
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ let A = Bidiagonal([1,2,3], [0,0], true)
184184
@test isdiag(A)
185185
end
186186

187+
# test construct from range
188+
@test Bidiagonal(1:3, 1:2, true) == [1 1 0; 0 2 2; 0 0 3]
189+
187190
#test promote_rule
188191
A = Bidiagonal(ones(Float32,10),ones(Float32,9),true)
189192
B = rand(Float64,10,10)

test/linalg/diagonal.jl

+3
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,6 @@ let d = randn(n), D = Diagonal(d)
214214
@test inv(D) inv(full(D))
215215
end
216216
@test_throws SingularException inv(Diagonal(zeros(n)))
217+
218+
# allow construct from range
219+
@test Diagonal(linspace(1,3,3)) == Diagonal([1.,2.,3.])

test/linalg/tridiag.jl

+8
Original file line numberDiff line numberDiff line change
@@ -400,3 +400,11 @@ SymTridiagonal([1, 2], [0])^3 == [1 0; 0 8]
400400
#test convert for SymTridiagonal
401401
@test convert(SymTridiagonal{Float64},SymTridiagonal(ones(Float32,5),ones(Float32,4))) == SymTridiagonal(ones(Float64,5),ones(Float64,4))
402402
@test convert(AbstractMatrix{Float64},SymTridiagonal(ones(Float32,5),ones(Float32,4))) == SymTridiagonal(ones(Float64,5),ones(Float64,4))
403+
404+
# Test constructors from matrix
405+
@test SymTridiagonal([1 2 3; 2 5 6; 0 6 9]) == [1 2 0; 2 5 6; 0 6 9]
406+
@test Tridiagonal([1 2 3; 4 5 6; 7 8 9]) == [1 2 0; 4 5 6; 0 8 9]
407+
408+
# Test constructors with range and other abstract vectors
409+
@test SymTridiagonal(1:3, 1:2) == [1 1 0; 1 2 2; 0 2 3]
410+
@test Tridiagonal(4:5, 1:3, 1:2) == [1 1 0; 4 2 2; 0 5 3]

0 commit comments

Comments
 (0)