|
1 | 1 | # special Toeplitz types that can be represented by a single vector |
2 | 2 | # Symmetric, Circulant, LowerTriangular, UpperTriangular |
| 3 | + |
| 4 | +abstract type AbstractToeplitzSingleVector{T} <: AbstractToeplitz{T} end |
| 5 | + |
| 6 | +parent(A::AbstractToeplitzSingleVector) = A.v |
| 7 | +basetype(x) = basetype(typeof(x)) |
| 8 | + |
| 9 | +function size(A::AbstractToeplitzSingleVector) |
| 10 | + n = length(parent(A)) |
| 11 | + (n,n) |
| 12 | +end |
| 13 | + |
| 14 | +adjoint(A::AbstractToeplitzSingleVector) = transpose(conj(A)) |
| 15 | +function zero!(A::AbstractToeplitzSingleVector) |
| 16 | + fill!(parent(A), zero(eltype(A))) |
| 17 | + return A |
| 18 | +end |
| 19 | + |
| 20 | +function lmul!(x::Number, A::AbstractToeplitzSingleVector) |
| 21 | + lmul!(x,parent(A)) |
| 22 | + A |
| 23 | +end |
| 24 | +function rmul!(A::AbstractToeplitzSingleVector, x::Number) |
| 25 | + rmul!(parent(A),x) |
| 26 | + A |
| 27 | +end |
| 28 | + |
| 29 | +for fun in (:iszero,) |
| 30 | + @eval $fun(A::AbstractToeplitzSingleVector) = $fun(parent(A)) |
| 31 | +end |
| 32 | + |
| 33 | +AbstractToeplitz{T}(A::AbstractToeplitzSingleVector) where T = basetype(A){T}(A) |
| 34 | + |
| 35 | +(*)(scalar::Number, C::AbstractToeplitzSingleVector) = basetype(C)(scalar * parent(C)) |
| 36 | +(*)(C::AbstractToeplitzSingleVector, scalar::Number) = basetype(C)(parent(C) * scalar) |
| 37 | + |
| 38 | +AbstractMatrix{T}(A::AbstractToeplitzSingleVector) where {T} = basetype(A){T}(AbstractVector{T}(A.v)) |
| 39 | + |
| 40 | +for fun in (:zero, :conj, :copy, :-, :real, :imag) |
| 41 | + @eval $fun(A::AbstractToeplitzSingleVector) = basetype(A)($fun(parent(A))) |
| 42 | +end |
| 43 | + |
3 | 44 | for TYPE in (:SymmetricToeplitz, :Circulant, :LowerTriangularToeplitz, :UpperTriangularToeplitz) |
4 | 45 | @eval begin |
5 | | - struct $TYPE{T, V<:AbstractVector{T}} <: AbstractToeplitz{T} |
| 46 | + struct $TYPE{T, V<:AbstractVector{T}} <: AbstractToeplitzSingleVector{T} |
6 | 47 | v::V |
7 | | - end |
8 | | - $TYPE{T}(v::V) where {T,V<:AbstractVector{T}} = $TYPE{T,V}(v) |
9 | | - $TYPE{T}(v::AbstractVector) where T = $TYPE{T}(convert(AbstractVector{T},v)) |
10 | | - |
11 | | - AbstractToeplitz{T}(A::$TYPE) where T = $TYPE{T}(A) |
12 | | - $TYPE{T}(A::$TYPE) where T = $TYPE{T}(convert(AbstractVector{T},A.v)) |
13 | | - convert(::Type{$TYPE{T}}, A::$TYPE) where {T} = $TYPE{T}(A) |
14 | | - |
15 | | - size(A::$TYPE) = (length(A.v),length(A.v)) |
16 | | - |
17 | | - adjoint(A::$TYPE) = transpose(conj(A)) |
18 | | - (*)(scalar::Number, C::$TYPE) = $TYPE(scalar * C.v) |
19 | | - (*)(C::$TYPE, scalar::Number) = $TYPE(C.v * scalar) |
20 | | - (==)(A::$TYPE,B::$TYPE) = A.v==B.v |
21 | | - function zero!(A::$TYPE) |
22 | | - if isconcrete(A) |
23 | | - fill!(A.v,zero(eltype(A))) |
24 | | - else |
25 | | - A.v=zero(A.v) |
| 48 | + function $TYPE{T,V}(v::V) where {T,V<:AbstractVector{T}} |
| 49 | + require_one_based_indexing(v) |
| 50 | + new{T,V}(v) |
26 | 51 | end |
27 | 52 | end |
| 53 | + function $TYPE{T}(v::AbstractVector) where T |
| 54 | + vT = convert(AbstractVector{T},v) |
| 55 | + $TYPE{T, typeof(vT)}(vT) |
| 56 | + end |
| 57 | + $TYPE(v::V) where {T,V<:AbstractVector{T}} = $TYPE{T,V}(v) |
| 58 | + |
| 59 | + basetype(::Type{T}) where {T<:$TYPE} = $TYPE |
| 60 | + |
| 61 | + (==)(A::$TYPE, B::$TYPE) = A.v == B.v |
| 62 | + |
| 63 | + convert(::Type{$TYPE{T}}, A::$TYPE) where {T} = A isa $TYPE{T} ? A : $TYPE{T}(A)::$TYPE{T} |
28 | 64 |
|
29 | 65 | function copyto!(A::$TYPE,B::$TYPE) |
30 | 66 | copyto!(A.v,B.v) |
31 | 67 | A |
32 | 68 | end |
33 | | - similar(A::$TYPE, T::Type) = $TYPE{T}(similar(A.v, T)) |
34 | | - function lmul!(x::Number, A::$TYPE) |
35 | | - lmul!(x,A.v) |
36 | | - A |
37 | | - end |
38 | | - function rmul!(A::$TYPE, x::Number) |
39 | | - rmul!(A.v,x) |
40 | | - A |
41 | | - end |
42 | | - end |
43 | | - for fun in (:zero, :conj, :copy, :-, :real, :imag) |
44 | | - @eval $fun(A::$TYPE) = $TYPE($fun(A.v)) |
45 | | - end |
46 | | - for fun in (:iszero,) |
47 | | - @eval $fun(A::$TYPE) = $fun(A.v) |
48 | 69 | end |
49 | 70 | for op in (:+, :-) |
50 | 71 | @eval $op(A::$TYPE,B::$TYPE) = $TYPE($op(A.v,B.v)) |
@@ -95,8 +116,12 @@ function getproperty(A::UpperTriangularToeplitz, s::Symbol) |
95 | 116 | end |
96 | 117 | end |
97 | 118 |
|
98 | | -_circulate(v::AbstractVector) = vcat(v[1],v[end:-1:2]) |
99 | | -_firstnonzero(v::AbstractVector) = vcat(v[1],zero(view(v,2:lastindex(v)))) |
| 119 | +_circulate(v::AbstractVector) = reverse(v, 2) |
| 120 | +function _firstnonzero(v::AbstractVector) |
| 121 | + w = zero(v) |
| 122 | + w[1] = v[1] |
| 123 | + w |
| 124 | +end |
100 | 125 |
|
101 | 126 | # transpose |
102 | 127 | transpose(A::SymmetricToeplitz) = A |
@@ -226,3 +251,6 @@ function _trisame!(A::TriangularToeplitz, k::Integer) |
226 | 251 | end |
227 | 252 | tril!(A::LowerTriangularToeplitz, k::Integer) = _trisame!(A,k) |
228 | 253 | triu!(A::UpperTriangularToeplitz, k::Integer) = _trisame!(A,-k) |
| 254 | + |
| 255 | +isdiag(A::Union{Circulant, LowerTriangularToeplitz, SymmetricToeplitz}) = all(iszero, @view _vc(A)[2:end]) |
| 256 | +isdiag(A::UpperTriangularToeplitz) = all(iszero, @view _vr(A)[2:end]) |
0 commit comments