Skip to content

Commit c5607ce

Browse files
authored
Support A[:,3:end] when A isa InfToeplitz (#2)
* Support A[:,3:end] when A isa InfToeplitz * General pert Toeplitz QL * fix submaterialize * fix banded Toeplitz * resave * improve q * tests pass again
1 parent 329f083 commit c5607ce

File tree

11 files changed

+276
-268
lines changed

11 files changed

+276
-268
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ MatrixFactorizations = "a3b82374-2e81-5b9e-98ce-41277c0e4c87"
1414

1515

1616
[compat]
17-
BandedMatrices = "0.12.2"
17+
BandedMatrices = "0.12.3"
1818
BlockArrays = "0.10"
1919
BlockBandedMatrices = "0.5.1"
2020
FillArrays = "0.7.1"

examples/toeplitz.jl

Lines changed: 28 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using Revise, InfiniteLinearAlgebra, BlockBandedMatrices, BlockArrays, BandedMatrices, LazyArrays, FillArrays, MatrixFactorizations, Plots
2-
import MatrixFactorizations: reflectorApply!, QLPackedQ
3-
import InfiniteLinearAlgebra: blocktailiterate, _ql, qltail, rightasymptotics
4-
import BandedMatrices: bandeddata,_BandedMatrix
1+
using InfiniteLinearAlgebra, BandedMatrices, PyPlot
2+
53

64
function ℓ11(A,λ; kwds...)
75
try
@@ -16,24 +14,23 @@ function findsecond(λ)
1614
λ[j], j
1715
end
1816

19-
function qlplot(A; branch=findmax, x=range(-4,4; length=200), y=range(-4,4;length=200), kwds...)
17+
qlplot(A::AbstractMatrix; kwds...) = qlplot(BandedMatrix(A); kwds...)
18+
function qlplot(A::BandedMatrix; branch=findmax, x=range(-4,4; length=200), y=range(-4,4;length=200), kwds...)
2019
z = ℓ11.(Ref(A), x' .+ y.*im; branch=branch)
2120
contourf(x,y,z; kwds...)
2221
end
2322

24-
function symbolplot!(A::BandedMatrix; kwds...)
23+
24+
25+
toepcoeffs(A::BandedMatrix) = InfiniteLinearAlgebra.rightasymptotics(A.data).args[1]
26+
toepcoeffs(A::Adjoint) = reverse(toepcoeffs(A'))
27+
28+
function symbolplot(A::BandedMatrix; kwds...)
2529
l,u = bandwidths(A)
26-
a = rightasymptotics(A.data).args[1]
30+
a = toepcoeffs(A)
2731
θ = range(0,2π; length=1000)
28-
i = Vector{ComplexF64}()
29-
for t in θ
30-
r = 0.0+0.0im
31-
for k=1:length(a)
32-
r += exp(im*(k-l-1)*t) * a[k]
33-
end
34-
push!(i,r)
35-
end
36-
plot!(i; kwds...)
32+
i = map(t -> dot(exp.(im.*(u:-1:-l).*t),a),θ)
33+
plot(real.(i), imag.(i); kwds...)
3734
end
3835

3936

@@ -42,212 +39,30 @@ end
4239
###
4340

4441
A = BandedMatrix(1 => Fill(2im,∞), 2 => Fill(-1,∞), 3 => Fill(2,∞), -2 => Fill(-4,∞), -3 => Fill(-2im,∞))
45-
p =plot(); symbolplot!(A)
42+
clf();qlplot(A; x=range(-10,7; length=100), y=range(-7,8;length=100)); symbolplot(A; color=:black); title("Trefethen & Embree")
43+
clf(); qlplot(transpose(A); x=range(-10,7; length=200), y=range(-7,8;length=200)); symbolplot(A; color=:black); title("Trefethen & Embree, transpose")
4644

4745
###
48-
# Non-normal
46+
# limaçon
4947
###
5048

51-
A = BandedMatrix(-1 => Vcat(Float64[], Fill(1/4,∞)), 0 => Vcat([1im],Fill(0,∞)), 1 => Vcat(Float64[], Fill(1,∞)))
52-
qlplot(A; title="A", linewidth=0, x=range(-2,2; length=100), y=range(-2,2;length=100))
53-
symbolplot!(A; linewidth=2.0, linecolor=:blue, legend=false)
54-
qlplot(BandedMatrix(A'); title="A', 1st", linewidth=0, nlevels=100, x=range(-2,2; length=100), y=range(-2,2;length=100))
55-
symbolplot!(A; linewidth=2.0, linecolor=:blue, legend=false)
56-
qlplot(BandedMatrix(A'); branch=findsecond, title="A'", linewidth=0, nlevels=100, x=range(-2,2; length=100), y=range(-2,2;length=100))
57-
58-
59-
heatmap!(x,y,fill(-100,length(y),length(x)); legend=false, color=:grays, fillalpha=(z -> isnan(z) ? 0.0 : 1.0).(z))
60-
61-
Matrix((A)[1:1000,1:1000]) |> eigvals |> scatter
62-
63-
ql(A-2I)
64-
65-
66-
θ = range(0,2π; length=1000)
67-
a = z -> z + 0.25/z
68-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
69-
70-
71-
72-
73-
74-
A = BandedMatrix(-10 => Fill(4.0,∞), 1 => Fill(1,∞))
75-
ql(A+0im*I)
76-
77-
78-
79-
80-
θ = range(0,2π-0.5; length=1000)
81-
a = z -> 4z^10 + 1/z
82-
θ = range(0,2π; length=1000)
83-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
84-
85-
import InfiniteLinearAlgebra: tail_de
86-
a = reverse(A.data.args[1]) .+ 0im
87-
88-
a = randn(10) .+ im*randn(10); a[1] += 10; a[end] = 1;
89-
de = tail_de(a)
90-
91-
@which tail_de(a)
92-
93-
ql([transpose(a); 0 transpose(de)])
94-
95-
ql([transpose(a); 0 transpose(de2)])
96-
97-
de
98-
99-
contourf(x,y,angle.(a.(x' .+ y.*im)))
100-
101-
A'
102-
Fun(a, Laurent())
103-
104-
A'
105-
106-
107-
a(1.0exp(0.5im))
49+
A = BandedMatrix(-2 => Fill(1.0,∞), -1 => Fill(1.0,∞), 1 => Fill(eps(),∞))
50+
qlplot(A; x=range(-2,3; length=100), y=range(-2.5,2.5;length=100)); symbolplot(A; color=:black); title("Limacon")
51+
clf(); qlplot(A; branch=findsecond, x=range(-2,3; length=100), y=range(-2.5,2.5;length=100)); symbolplot(A; color=:black); title("Limacon, second branch")
52+
clf(); qlplot(transpose(A); x=range(-2,3; length=100), y=range(-2.5,2.5;length=100)); symbolplot(A; color=:black); title("Limacon, transpose")
10853

109-
#### To be cleaned
11054

55+
ql(A-(0.5+0.000001im)*I; branch=findsecond)
11156

112-
function reduceband(A)
113-
l,u = bandwidths(A)
114-
H = _BandedMatrix(A.data, ∞, l+u-1, 1)
115-
Q1,L1 = ql(H)
116-
D = Q1[1:l+u+1,1:1]'A[1:l+u+1,1:u-1]
117-
D, Q1, L1
118-
end
119-
_Lrightasymptotics(D::Vcat) = D.args[2]
120-
_Lrightasymptotics(D::ApplyArray) = D.args[1][2:end] * Ones{ComplexF64}(1,∞)
121-
Lrightasymptotics(L) = _Lrightasymptotics(rightasymptotics(parent(L).data))
122-
123-
function qdL(A)
124-
l,u = bandwidths(A)
125-
H = _BandedMatrix(A.data, ∞, l+u-1, 1)
126-
Q1,L1 = ql(H)
127-
D1, Q1, L1 = reduceband(A)
128-
T2 = _BandedMatrix(Lrightasymptotics(L1), ∞, l, u)
129-
l1 = L1[1,1]
130-
A2 = [[D1 l1 zeros(1,10-size(D1,2)-1)]; T2[1:10-1,1:10]] # TODO: remove
131-
B2 = _BandedMatrix(T2.data, ∞, l+u-2, 2)
132-
B2 = _BandedMatrix(T2.data, ∞, l+u-2, 2)
133-
D2, Q2, L2 = reduceband(B2)
134-
l2 = L2[1,1]
135-
# peroidic tail
136-
T3 = _BandedMatrix(Lrightasymptotics(L2), ∞, l+1, u-1)
137-
A3 = [[D2 l2 zeros(1,10-size(D2,2)-1)]; T3[1:10-1,1:10]] # TODO: remove
138-
139-
Q3,L3 = ql( [A2[1,1] A2[1:1,2:3]; [Q2[1:3,1:1]' * T2[1:3,1] A3[1:1,1:2] ]])
140-
141-
fd_data = hcat([0; L3[:,1]; Q2[1:3,2:3]' * T2[1:3,1]], [L3[:,2]; T3[1:3,1]], [L3[2,3]; T3[1:4,2]])
142-
B3 = _BandedMatrix(Hcat(fd_data, T3.data), ∞, l+u-1, 1)
143-
144-
ql(B3).L
145-
end
146-
# Bull's head
147-
A = BandedMatrix(-3 => Fill(7/10,10), -2 => Fill(1,11), 1 => Fill(2im,9))
57+
###
58+
# bull-head
59+
###
14860

14961
A = BandedMatrix(-3 => Fill(7/10,∞), -2 => Fill(1,∞), 1 => Fill(2im,∞))
150-
qlplot(A; title="largest", linewidth=0)
151-
152-
153-
qlplot(A; branch=findsecond, title="second largest", linewidth=0)
154-
155-
156-
157-
sortp
158-
159-
ql(A-(1+2im)*I)
160-
161-
θ = range(0,2π; length=1000)
162-
a = z -> 2im/z + z^2 + 7/10 * z^3
163-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
164-
qlplot(A; branch=2, title="branch=2", linewidth=0)
165-
166-
167-
62+
clf();qlplot(A; x=range(-10,7; length=100), y=range(-7,8;length=100)); symbolplot(A; color=:black); title("Bull-head")
63+
clf(); qlplot(transpose(A); x=range(-10,7; length=100), y=range(-7,8;length=100)); symbolplot(A; color=:black); title("Bull-head, transpose")
16864

169-
θ = range(0,2π; length=1000)
170-
a = z -> 2im/z + z^2 + 7/10 * z^3
171-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
172-
173-
174-
ql(A - (5+2im)*I; branch=1)
175-
176-
= λ -> try abs(ql(A-λ*I).L[1,1]) catch DomainError
177-
(-1) end
178-
x,y = range(-4,4; length=200),range(-4,4;length=200)
179-
z = .(x' .+ y.*im)
180-
contourf(x,y,z; nlevels=100, title="A", linewidth=0)
181-
θ = range(0,2π; length=1000)
182-
a = z -> 2im/z + z^2 + 7/10 * z^3
183-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
184-
185-
Ac = BandedMatrix(A')
186-
187-
= λ -> try abs(qdL(Ac-conj(λ)*I)[1,1]) catch DomainError
188-
(-1.0) end
189-
x,y = range(-4,4; length=100),range(-4,4;length=100)
190-
@time z = .(x' .+ y.*im)
191-
contourf(x,y,z; nlevels=100, title="A'", linewidth=0.0)
192-
θ = range(0,2π; length=1000)
193-
a = z -> 2im/z + z^2 + 7/10 * z^3
194-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
19565

66+
###
19667
# Grcar
197-
A = BandedMatrix(-3 => Fill(1,∞), -2 => Fill(1,∞), -1 => Fill(1,∞), 0 => Fill(1,∞), 1 => Fill(-1,∞))
198-
= λ -> try abs(ql(A-λ*I).L[1,1]) catch DomainError
199-
-1 end
200-
x,y = range(-4,4; length=200),range(-4,4;length=200)
201-
z = .(x' .+ y.*im)
202-
203-
θ = range(0,2π; length=1000)
204-
a = z -> -1/z + 1 + z + z^2 + z^3
205-
contourf(x,y,z; nlevels=50)
206-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
207-
208-
209-
# Triangle
210-
A = BandedMatrix(-2 => Fill(1/4,∞), 1 => Fill(1,∞))
211-
= λ -> try abs(ql(A-λ*I).L[1,1]) catch DomainError
212-
(-1) end
213-
x,y = range(-2,2; length=200),range(-2,2;length=200)
214-
z = .(x' .+ y.*im)
215-
θ = range(0,2π; length=1000)
216-
a = z -> z^2/4 + 1/z
217-
218-
contourf(x,y,z; nlevels=50)
219-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
220-
221-
222-
function Toep_L11(T)
223-
l,u = bandwidths(T)
224-
@assert u == 2
225-
# shift by one
226-
H = _BandedMatrix(T.data, ∞, l+1, 1)
227-
Q1,L1 = ql(H)
228-
229-
d = Q1[1:3,1]'T[1:1+l,1]
230-
= Q1.factors.data.args[2].args[1][2:end] # new L
231-
T2 = _BandedMatrix(Hcat([[zero(d); d; ℓ[3:end]] L1[1:5,1]], ℓ*Ones{eltype(T)}(1,∞)), ∞, 3, 1)
232-
Q2,L2 = ql(T2)
233-
D = (Q2')[1:5,1:4] * (Q1')[1:4,1:3] * T[3:5,1:3]
234-
X = [Matrix(T[3:4,1:6]); [zeros(2,2) [-1 0; 0 1]*D[1:2,:] [-1 0; 0 1]*L2[1:2,2]]]
235-
ql(X).L[1,3]
236-
end
237-
238-
239-
240-
A = BandedMatrix(2 => Fill(1/4,∞), -1 => Fill(1,∞), -2 => Fill(0.0, ∞))
241-
@time Toep_L11(A-(0.1+0im)I)
242-
243-
T = A-(0.1+0im)I
244-
245-
246-
= λ -> abs(Toep_L11(A-λ*I))
247-
x,y = range(-2,2; length=51),range(-2,2;length=50)
248-
z = .(x' .+ y.*im)
249-
θ = range(0,2π; length=1000)
250-
a = z -> z^2/4 + 1/z
251-
252-
contour(x,y,z; nlevels=50)
253-
plot!(a.(exp.(im.*θ)); linewidth=2.0, linecolor=:blue, legend=false)
68+
###

src/InfiniteLinearAlgebra.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@ module InfiniteLinearAlgebra
22
using BlockArrays, BlockBandedMatrices, BandedMatrices, LazyArrays, FillArrays, InfiniteArrays, MatrixFactorizations, LinearAlgebra
33

44
import Base: +, -, *, /, \, ^, OneTo, getindex, promote_op, _unsafe_getindex, print_matrix_row, size, axes,
5-
AbstractMatrix, AbstractArray, Matrix, Array, Vector, AbstractVector,
5+
AbstractMatrix, AbstractArray, Matrix, Array, Vector, AbstractVector, Slice,
66
show, getproperty
77
import Base.Broadcast: BroadcastStyle
88

9-
import InfiniteArrays: OneToInf, InfUnitRange, Infinity, InfStepRange
9+
import InfiniteArrays: OneToInf, InfUnitRange, Infinity, InfStepRange, AbstractInfUnitRange
1010
import FillArrays: AbstractFill, getindex_value
11-
import BandedMatrices: BandedMatrix, _BandedMatrix, bandeddata, bandwidths
11+
import BandedMatrices: BandedMatrix, _BandedMatrix, AbstractBandedMatrix, bandeddata, bandwidths, BandedColumns, bandedcolumns
1212
import LinearAlgebra: lmul!, ldiv!, matprod, qr, AbstractTriangular, AbstractQ, adjoint, transpose
1313
import LazyArrays: CachedArray, CachedMatrix, CachedVector, DenseColumnMajor, FillLayout, ApplyMatrix, check_mul_axes, ApplyStyle, LazyArrayApplyStyle, LazyArrayStyle,
1414
CachedMatrix, CachedArray, resizedata!, MemoryLayout, mulapplystyle, LmulStyle, RmulStyle,
15-
colsupport, rowsupport, triangularlayout, factorize
15+
colsupport, rowsupport, triangularlayout, factorize, subarraylayout, sub_materialize,
16+
@lazymul
1617
import MatrixFactorizations: ql, ql!, QLPackedQ, getL, getR, reflector!, reflectorApply!, QL, QR, QRPackedQ
1718

1819
import BlockArrays: BlockSizes, cumulsizes, _find_block, AbstractBlockVecOrMat, sizes_from_blocks
1920

20-
import BandedMatrices: BandedMatrix, bandwidths, AbstractBandedLayout, _banded_qr!, _banded_qr
21+
import BandedMatrices: BandedMatrix, bandwidths, AbstractBandedLayout, _banded_qr!, _banded_qr, _BandedMatrix
2122

2223
import BlockBandedMatrices: _BlockSkylineMatrix, _BandedMatrix, AbstractBlockSizes, cumulsizes, _BlockSkylineMatrix, BlockSizes, blockstart, blockstride,
2324
BlockSkylineSizes, BlockSkylineMatrix, BlockBandedMatrix, _BlockBandedMatrix, BlockTridiagonal

src/banded/hessenbergq.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,24 @@ adjoint(Q::LowerHessenbergQ) = UpperHessenbergQ(adjoint.(Q.q))
9090
check_mul_axes(A::AbstractHessenbergQ, B, C...) =
9191
axes(A,2) == axes(B,1) || throw(DimensionMismatch("Second axis of A, $(axes(A,2)), and first axis of B, $(axes(B,1)) must match"))
9292

93+
@lazymul AbstractHessenbergQ
94+
95+
# ambiguities
96+
for Arr in (:AbstractBandedMatrix, :StridedVector, :StridedMatrix)
97+
@eval begin
98+
*(A::AbstractHessenbergQ, B::$Arr) = apply(*, A, B)
99+
*(A::$Arr, B::AbstractHessenbergQ) = apply(*, A, B)
100+
end
101+
end
93102

94103
function lmul!(Q::LowerHessenbergQ{T}, x::AbstractVector) where T
95104
t = Array{T}(undef, 2)
105+
nz = nzzeros(x,1)
96106
for n = 1:length(Q.q)
97107
v = view(x, n:n+1)
98108
mul!(t, Q.q[n], v)
99109
v .= t
100-
all(iszero,t) && return x
110+
n > nz && norm(t)  10floatmin(real(T)) && return x
101111
end
102112
x
103113
end
@@ -112,6 +122,13 @@ function lmul!(Q::UpperHessenbergQ{T}, x::AbstractVector) where T
112122
x
113123
end
114124

125+
function lmul!(Q::AbstractHessenbergQ, X::AbstractMatrix)
126+
for j in axes(X,2)
127+
lmul!(Q, view(X,:,j))
128+
end
129+
X
130+
end
131+
115132

116133
###
117134
# getindex

0 commit comments

Comments
 (0)