3
3
# ### Specialized matrix types ####
4
4
5
5
# # (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} }
10
10
if ! (length (dv) - 1 <= length (ev) <= length (dv))
11
11
throw (DimensionMismatch (" subdiagonal has wrong length. Has length $(length (ev)) , but should be either $(length (dv) - 1 ) or $(length (dv)) ." ))
12
12
end
13
- new (dv,ev)
13
+ new {T,V} (dv,ev)
14
14
end
15
15
end
16
16
17
17
"""
18
18
SymTridiagonal(dv, ev)
19
19
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).
24
24
25
25
# Examples
26
26
```jldoctest
27
- julia> dv = [1; 2; 3; 4]
27
+ julia> dv = [1, 2, 3, 4]
28
28
4-element Array{Int64,1}:
29
29
1
30
30
2
31
31
3
32
32
4
33
33
34
- julia> ev = [7; 8; 9]
34
+ julia> ev = [7, 8, 9]
35
35
3-element Array{Int64,1}:
36
36
7
37
37
8
38
38
9
39
39
40
40
julia> SymTridiagonal(dv, ev)
41
- 4×4 SymTridiagonal{Int64}:
41
+ 4×4 SymTridiagonal{Int64,Array{Int64,1} }:
42
42
1 7 ⋅ ⋅
43
43
7 2 8 ⋅
44
44
⋅ 8 3 9
45
45
⋅ ⋅ 9 4
46
46
```
47
47
"""
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
49
54
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
52
56
SymTridiagonal (convert (Vector{T}, dv), convert (Vector{T}, ev))
53
57
end
54
58
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
+ """
55
80
function SymTridiagonal (A:: AbstractMatrix )
56
81
if diag (A,1 ) == diag (A,- 1 )
57
82
SymTridiagonal (diag (A), diag (A,1 ))
@@ -61,10 +86,10 @@ function SymTridiagonal(A::AbstractMatrix)
61
86
end
62
87
63
88
convert (:: 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))
65
90
convert (:: 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
68
93
n = size (M, 1 )
69
94
Mf = zeros (T, n, n)
70
95
@inbounds begin
311
336
# R. Usmani, "Inversion of a tridiagonal Jacobi matrix",
312
337
# Linear Algebra and its Applications 212-213 (1994), pp.413-414
313
338
# 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} }
315
340
n = length (b)
316
341
θ = ZeroOffsetVector (zeros (T, n+ 1 )) # principal minors of A
317
342
θ[0 ] = 1
341
366
342
367
# Implements the determinant using principal minors
343
368
# 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} }
345
370
n = length (b)
346
371
θa = one (T)
347
372
if n == 0
@@ -635,7 +660,7 @@ convert(::Type{AbstractMatrix{T}},M::Tridiagonal) where {T} = convert(Tridiagona
635
660
convert (:: Type{Tridiagonal{T}} , M:: SymTridiagonal{T} ) where {T} = Tridiagonal (M)
636
661
function convert (:: Type{SymTridiagonal{T}} , M:: Tridiagonal ) where T
637
662
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))
639
664
else
640
665
throw (ArgumentError (" Tridiagonal is not symmetric, cannot convert to SymTridiagonal" ))
641
666
end
0 commit comments