33# ### Specialized matrix types ####
44
55# # (complex) symmetric tridiagonal matrices
6- struct SymTridiagonal{T} <: AbstractMatrix{T}
7- dv:: Vector{T} # diagonal
8- ev:: Vector{T} # subdiagonal
9- function SymTridiagonal {T} (dv:: Vector{T} , ev:: Vector{T} ) where T
6+ struct SymTridiagonal{T,V <: AbstractVector{T} } <: AbstractMatrix{T}
7+ dv:: V # diagonal
8+ ev:: V # subdiagonal
9+ function SymTridiagonal {T} (dv:: V , ev:: V ) where {T,V <: AbstractVector{T} }
1010 if ! (length (dv) - 1 <= length (ev) <= length (dv))
1111 throw (DimensionMismatch (" subdiagonal has wrong length. Has length $(length (ev)) , but should be either $(length (dv) - 1 ) or $(length (dv)) ." ))
1212 end
13- new (dv,ev)
13+ new {T,V} (dv,ev)
1414 end
1515end
1616
1717"""
1818 SymTridiagonal(dv, ev)
1919
20- Construct a symmetric tridiagonal matrix from the diagonal and first sub/super-diagonal,
21- respectively. The result is of type `SymTridiagonal` and provides efficient specialized
22- eigensolvers, but may be converted into a regular matrix with
23- [`convert(Array, _)`](@ref) (or `Array(_)` for short).
20+ Construct a symmetric tridiagonal matrix from the diagonal (`dv`) and first
21+ sub/super-diagonal (`ev`), respectively. The result is of type `SymTridiagonal`
22+ and provides efficient specialized eigensolvers, but may be converted into a
23+ regular matrix with [`convert(Array, _)`](@ref) (or `Array(_)` for short).
2424
2525# Examples
2626```jldoctest
27- julia> dv = [1; 2; 3; 4]
27+ julia> dv = [1, 2, 3, 4]
28284-element Array{Int64,1}:
2929 1
3030 2
3131 3
3232 4
3333
34- julia> ev = [7; 8; 9]
34+ julia> ev = [7, 8, 9]
35353-element Array{Int64,1}:
3636 7
3737 8
3838 9
3939
4040julia> SymTridiagonal(dv, ev)
41- 4×4 SymTridiagonal{Int64}:
41+ 4×4 SymTridiagonal{Int64,Array{Int64,1} }:
4242 1 7 ⋅ ⋅
4343 7 2 8 ⋅
4444 ⋅ 8 3 9
4545 ⋅ ⋅ 9 4
4646```
4747"""
48- SymTridiagonal (dv:: Vector{T} , ev:: Vector{T} ) where {T} = SymTridiagonal {T} (dv, ev)
48+ SymTridiagonal (dv:: V , ev:: V ) where {T,V<: AbstractVector{T} } = SymTridiagonal {T} (dv, ev)
49+
50+ function SymTridiagonal (dv:: AbstractVector{T} , ev:: AbstractVector{S} ) where {T,S}
51+ R = promote_type (T, S)
52+ SymTridiagonal (convert (AbstractVector{R}, dv), convert (AbstractVector{R}, ev))
53+ end
4954
50- function SymTridiagonal (dv:: AbstractVector{Td} , ev:: AbstractVector{Te} ) where {Td,Te}
51- T = promote_type (Td,Te)
55+ function SymTridiagonal (dv:: AbstractVector{T} , ev:: AbstractVector{T} ) where T
5256 SymTridiagonal (convert (Vector{T}, dv), convert (Vector{T}, ev))
5357end
5458
59+ """
60+ SymTridiagonal(A::AbstractMatrix)
61+
62+ Construct a symmetric tridiagonal matrix from the
63+ diagonal and first sub/super-diagonal, of `A`.
64+
65+ # Examples
66+ ```jldoctest
67+ julia> A = [1 2 3; 2 4 5; 3 5 6]
68+ 3×3 Array{Int64,2}:
69+ 1 2 3
70+ 2 4 5
71+ 3 5 6
72+
73+ julia> SymTridiagonal(A)
74+ 3×3 SymTridiagonal{Int64}:
75+ 1 2 ⋅
76+ 2 4 5
77+ ⋅ 5 6
78+ ```
79+ """
5580function SymTridiagonal (A:: AbstractMatrix )
5681 if diag (A,1 ) == diag (A,- 1 )
5782 SymTridiagonal (diag (A), diag (A,1 ))
@@ -61,10 +86,10 @@ function SymTridiagonal(A::AbstractMatrix)
6186end
6287
6388convert (:: Type{SymTridiagonal{T}} , S:: SymTridiagonal ) where {T} =
64- SymTridiagonal (convert (Vector {T}, S. dv), convert (Vector {T}, S. ev))
89+ SymTridiagonal (convert (AbstractVector {T}, S. dv), convert (AbstractVector {T}, S. ev))
6590convert (:: Type{AbstractMatrix{T}} , S:: SymTridiagonal ) where {T} =
66- SymTridiagonal (convert (Vector {T}, S. dv), convert (Vector {T}, S. ev))
67- function convert (:: Type{Matrix{T}} , M:: SymTridiagonal{T} ) where T
91+ SymTridiagonal (convert (AbstractVector {T}, S. dv), convert (AbstractVector {T}, S. ev))
92+ function convert (:: Type{Matrix{T}} , M:: SymTridiagonal ) where T
6893 n = size (M, 1 )
6994 Mf = zeros (T, n, n)
7095 @inbounds begin
311336# R. Usmani, "Inversion of a tridiagonal Jacobi matrix",
312337# Linear Algebra and its Applications 212-213 (1994), pp.413-414
313338# doi:10.1016/0024-3795(94)90414-6
314- function inv_usmani (a:: Vector{T} , b:: Vector{T} , c:: Vector{T} ) where T
339+ function inv_usmani (a:: V , b:: V , c:: V ) where {T,V <: AbstractVector{T} }
315340 n = length (b)
316341 θ = ZeroOffsetVector (zeros (T, n+ 1 )) # principal minors of A
317342 θ[0 ] = 1
341366
342367# Implements the determinant using principal minors
343368# Inputs and reference are as above for inv_usmani()
344- function det_usmani (a:: Vector{T} , b:: Vector{T} , c:: Vector{T} ) where T
369+ function det_usmani (a:: V , b:: V , c:: V ) where {T,V <: AbstractVector{T} }
345370 n = length (b)
346371 θa = one (T)
347372 if n == 0
@@ -635,7 +660,7 @@ convert(::Type{AbstractMatrix{T}},M::Tridiagonal) where {T} = convert(Tridiagona
635660convert (:: Type{Tridiagonal{T}} , M:: SymTridiagonal{T} ) where {T} = Tridiagonal (M)
636661function convert (:: Type{SymTridiagonal{T}} , M:: Tridiagonal ) where T
637662 if M. dl == M. du
638- return SymTridiagonal (convert (Vector {T},M. d), convert (Vector {T},M. dl))
663+ return SymTridiagonal {T} (convert (AbstractVector {T},M. d), convert (AbstractVector {T},M. dl))
639664 else
640665 throw (ArgumentError (" Tridiagonal is not symmetric, cannot convert to SymTridiagonal" ))
641666 end
0 commit comments