Skip to content

Commit 0325f28

Browse files
committed
Update test_bidiagonalconjugation.jl
1 parent 4389524 commit 0325f28

File tree

1 file changed

+73
-19
lines changed

1 file changed

+73
-19
lines changed

test/test_bidiagonalconjugation.jl

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using LazyArrays: LazyLayout
2222
V2 = brand(∞, 0, 1)
2323
A2 = LazyBandedMatrices.Bidiagonal(Fill(0.2, ∞), 2.0 ./ (1.0 .+ (1:∞)), 'L') # LinearAlgebra.Bidiagonal not playing nice for this case
2424
X2 = InfRandBidiagonal('L')
25-
U2 = X2 * V2 * ApplyArray(inv, A2)
25+
U2 = X2 * V2 * ApplyArray(inv, A2)
2626
B2 = BidiagonalConjugation(U2, X2, V2, :L);
2727

2828
for (A, B, uplo) in ((A1, B1, 'U'), (A2, B2, 'L'))
@@ -54,12 +54,12 @@ using LazyArrays: LazyLayout
5454
@test LazyBandedMatrices.Bidiagonal(B) === LazyBandedMatrices.Bidiagonal(B.dv, B.ev, Symbol(uplo))
5555
@test B[1:10, 1:10] A[1:10, 1:10]
5656
@test B[230, 230] A[230, 230]
57-
@test B[102, 102] A[102, 102] # make sure we compute intermediate columns correctly when skipping
57+
@test B[102, 102] A[102, 102] # make sure we compute intermediate columns correctly when skipping
5858
@test B[band(0)][1:100] == B.dv[1:100]
5959
if uplo == 'U'
6060
@test B[band(1)][1:100] == B.ev[1:100]
61-
# @test B[band(-1)][1:100] == zeros(100) # This test requires that we define a
62-
# convert(::Type{BidiagonalConjugationBand{T}}, ::Zeros{V, 1, Tuple{OneToInf{Int}}}) where {T, V} method,
61+
# @test B[band(-1)][1:100] == zeros(100) # This test requires that we define a
62+
# convert(::Type{BidiagonalConjugationBand{T}}, ::Zeros{V, 1, Tuple{OneToInf{Int}}}) where {T, V} method,
6363
# which we probably don't need beyond this test
6464
else
6565
@test B[band(-1)][1:100] == B.ev[1:100]
@@ -74,7 +74,7 @@ using LazyArrays: LazyLayout
7474
@test (B*I)[1:100, 1:100] B[1:100, 1:100]
7575
# @test (B*Diagonal(1:∞))[1:100, 1:100] ≈ B[1:100, 1:100] * Diagonal(1:100) # Uncomment once https://github.com/JuliaLinearAlgebra/ArrayLayouts.jl/pull/241 is registered
7676

77-
# Pointwise tests
77+
# Pointwise tests
7878
for i in 1:10
7979
for j in 1:10
8080
@test B[i, j] A[i, j]
@@ -92,7 +92,7 @@ using LazyArrays: LazyLayout
9292
R0 = BandedMatrices._BandedMatrix(Vcat(-Ones(1,∞)/2,
9393
Zeros(1,∞),
9494
Hcat(Ones(1,1),Ones(1,∞)/2)), ℵ₀, 0,2)
95-
95+
9696
D0 = BandedMatrix(1 => 1:∞)
9797
R1 = BandedMatrix(0 => 1 ./ (1:∞), 2 => -1 ./ (3:∞))
9898

@@ -112,7 +112,7 @@ end
112112

113113
function upper_mul_tri_triview!(UX::Tridiagonal, U::BandedMatrix, X::Tridiagonal)
114114
n = size(U,1)
115-
115+
116116
j = 1
117117
Xⱼⱼ, Xⱼ₊₁ⱼ = X.d[1], X.dl[1]
118118
Uⱼⱼ, Uⱼⱼ₊₁, Uⱼⱼ₊₂ = U.data[3,1], U.data[2,2], U.data[1,3] # U[j,j], U[j,j+1], U[j,j+2]
@@ -157,7 +157,7 @@ function tri_mul_invupper_triview!(Y, X, R)
157157
Rₖₖ,Rₖₖ₊₁ = R.data[3,k], R.data[2,k+1] # R[1,1], R[1,2]
158158
Y.d[k] = Xₖₖ/Rₖₖ
159159
Y.du[k] = Xₖₖ₊₁ - Xₖₖ * Rₖₖ₊₁/Rₖₖ
160-
160+
161161
@inbounds for k = 2:n-1
162162
Xₖₖ₋₁,Xₖₖ,Xₖₖ₊₁ = X.dl[k-1], X.d[k], X.du[k]
163163
Y.dl[k-1] = Xₖₖ₋₁/Rₖₖ
@@ -180,18 +180,72 @@ function tri_mul_invupper_triview!(Y, X, R)
180180

181181
Y
182182
end
183+
"""
184+
TridiagonalConjugationData(U, X, V, Y)
185+
186+
caches the infinite dimensional Tridiagonal(U*X/V)
187+
in the tridiagonal matrix `Y`
188+
"""
189+
190+
mutable struct TridiagonalConjugationData{T}
191+
const U::AbstractMatrix{T}
192+
const X::AbstractMatrix{T}
193+
const V::AbstractMatrix{T}
194+
195+
const UX::Tridiagonal{T,Vector{T}} # cache Tridiagonal(U*X)
196+
const Y::Tridiagonal{T,Vector{T}} # cache Tridiagonal(U*X/V)
197+
198+
datasize::Int
199+
end
200+
201+
function TridiagonalConjugationData(U, X, V, uplo::Char)
202+
T = promote_type(typeof(inv(V[1, 1])), eltype(U), eltype(C)) # include inv so that we can't get Ints
203+
return BidiagonalConjugationData(U, X, V, Tridiagonal(T[], T[], T[]), Tridiagonal(T[], T[], T[]), 0)
204+
end
205+
206+
copy(data::TridiagonalConjugationData) = TridiagonalConjugationData(copy(data.U), copy(data.X), copy(data.V), copy(data.UX), copy(data.Y), data.datasize)
207+
208+
209+
function resizedata!(data::TridiagonalConjugationData, n)
210+
n 0 && return data
211+
n = max(v, n)
212+
dv, ev = data.dv, data.ev
213+
if n > length(ev) # Avoid O(n²) growing. Note min(length(dv), length(ev)) == length(ev)
214+
resize!(dv, 2n + 1)
215+
resize!(ev, 2n)
216+
end
217+
218+
219+
end
183220

184221

185222
@testset "TridiagonalConjugation" begin
186-
R0 = BandedMatrices._BandedMatrix(Vcat(-Ones(1,∞)/2,
187-
Zeros(1,∞),
188-
Hcat(Ones(1,1),Ones(1,∞)/2)), ℵ₀, 0,2)
189-
X_T = LazyBandedMatrices.Tridiagonal(Vcat(1.0, Fill(1/2,∞)), Zeros(∞), Fill(1/2,∞))
190-
191-
n = 1000; @time U = V = R0[1:n,1:n];
192-
@time X = Tridiagonal(Vector(X_T.dl[1:n-1]), Vector(X_T.d[1:n]), Vector(X_T.du[1:n-1]));
193-
@time UX = upper_mul_tri_triview(U, X)
194-
@test Tridiagonal(U*X) UX
195-
# U*X*inv(U) only depends on Tridiagonal(U*X)
196-
@test Tridiagonal(U*X / U) Tridiagonal(UX / U) tri_mul_invupper_triview(UX, U)
223+
@testset "T -> U" begin
224+
R = BandedMatrices._BandedMatrix(Vcat(-Ones(1,∞)/2,
225+
Zeros(1,∞),
226+
Hcat(Ones(1,1),Ones(1,∞)/2)), ℵ₀, 0,2)
227+
X_T = LazyBandedMatrices.Tridiagonal(Vcat(1.0, Fill(1/2,∞)), Zeros(∞), Fill(1/2,∞))
228+
n = 1000
229+
@time U = V = R[1:n,1:n];
230+
@time X = Tridiagonal(Vector(X_T.dl[1:n-1]), Vector(X_T.d[1:n]), Vector(X_T.du[1:n-1]));
231+
@time UX = upper_mul_tri_triview(U, X)
232+
@test Tridiagonal(U*X) UX
233+
# U*X*inv(U) only depends on Tridiagonal(U*X)
234+
@time Y = tri_mul_invupper_triview(UX, U)
235+
@test Tridiagonal(U*X / U) Tridiagonal(UX / U) Y
236+
end
237+
@testset "P -> Ultraspherical(3/2)" begin
238+
R = BandedMatrices._BandedMatrix(Vcat((-1 ./ (1:2:∞))',
239+
Zeros(1,∞),
240+
(1 ./ (1:2:∞))'), ℵ₀, 0,2)
241+
X_P = LazyBandedMatrices.Tridiagonal((1:∞) ./ (1:2:∞), Zeros(∞), (1:∞) ./ (3:2:∞))
242+
n = 1000
243+
@time U = V = R[1:n,1:n]
244+
@time X = Tridiagonal(Vector(X_P.dl[1:n-1]), Vector(X_P.d[1:n]), Vector(X_P.du[1:n-1]))
245+
@time UX = upper_mul_tri_triview(U, X)
246+
@test Tridiagonal(U*X) UX
247+
# U*X*inv(U) only depends on Tridiagonal(U*X)
248+
@time Y = tri_mul_invupper_triview(UX, U)
249+
@test Tridiagonal(U*X / U) Tridiagonal(UX / U) Y
250+
end
197251
end

0 commit comments

Comments
 (0)