Skip to content

Commit 955d096

Browse files
committed
Fast finite tri-conj
1 parent e64a854 commit 955d096

File tree

1 file changed

+39
-41
lines changed

1 file changed

+39
-41
lines changed

test/test_bidiagonalconjugation.jl

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -102,37 +102,17 @@ end
102102

103103

104104
"""
105-
upper_mul_tri_triview(A, B) == Tridiagonal(A*B) where A is Upper triangular BandedMatrix and B is
105+
upper_mul_tri_triview(U, X) == Tridiagonal(U*X) where U is Upper triangular BandedMatrix and X is Tridiagonal
106106
"""
107-
function upper_mul_tri_triview(U, X)
107+
function upper_mul_tri_triview(U::BandedMatrix, X::Tridiagonal)
108108
T = promote_type(eltype(U), eltype(X))
109109
n = size(U,1)
110110
upper_mul_tri_triview!(Tridiagonal(Vector{T}(undef, n-1), Vector{T}(undef, n), Vector{T}(undef, n-1)), U, X)
111111
end
112112

113-
114-
# function upper_mul_tri_triview!(UX::Tridiagonal, U::BandedMatrix, X::Tridiagonal)
115-
# n = size(U,1)
116-
# @inbounds for j = 1:n-1
117-
# UX.d[j] = U.data[3,j]*X.d[j] + U.data[2,j]*X.dl[j]
118-
# end
119-
# UX.d[n] = U.data[3,n]*X.d[n]
120-
121-
# @inbounds for j = 1:n-1
122-
# UX.dl[j] = U.data[3,j+1]*X.dl[j]
123-
# end
124-
125-
# @inbounds for j = 1:n-2
126-
# UX.du[j] = U.data[3,j]*X.du[j] + U.data[2,j+1]*X.d[j+1] + U.data[1,j+2]*X.dl[j+1]
127-
# end
128-
129-
# UX.du[n-1] = U.data[3,n-1]*X.du[n-1] + U.data[2,n]*X.d[n]
130-
131-
# UX
132-
# end
133-
134113
function upper_mul_tri_triview!(UX::Tridiagonal, U::BandedMatrix, X::Tridiagonal)
135114
n = size(U,1)
115+
136116
j = 1
137117
Xⱼⱼ, Xⱼ₊₁ⱼ = X.d[1], X.dl[1]
138118
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]
@@ -163,25 +143,42 @@ function upper_mul_tri_triview!(UX::Tridiagonal, U::BandedMatrix, X::Tridiagonal
163143
UX
164144
end
165145

166-
tri_mul_invupper_triview(UX::Tridiagonal, R::BandedMatrix) = tri_mul_invupper_triview!(similar(UX, promote_type(eltype(UX), eltype(R))), UX, R)
167146

168-
function tri_mul_invupper_triview!(X, UX, R)
169-
@inbounds for j = 1:n-1
170-
UX.d[j] = UX.d[j]/ U.data[3,j]*X.d[j] + U.data[2,j]*X.dl[j]
147+
# X*R^{-1} = X*[1/R₁₁ -R₁₂/(R₁₁R₂₂) -R₁₃/R₂₂ …
148+
# 0 1/R₂₂ -R₂₃/R₃₃
149+
# 1/R₃₃
150+
151+
tri_mul_invupper_triview(X::Tridiagonal, R::BandedMatrix) = tri_mul_invupper_triview!(similar(X, promote_type(eltype(X), eltype(R))), X, R)
152+
153+
function tri_mul_invupper_triview!(Y, X, R)
154+
n = size(X,1)
155+
k = 1
156+
Xₖₖ,Xₖₖ₊₁ = X.d[k], X.du[k]
157+
Rₖₖ,Rₖₖ₊₁ = R.data[3,k], R.data[2,k+1] # R[1,1], R[1,2]
158+
Y.d[k] = Xₖₖ/Rₖₖ
159+
Y.du[k] = Xₖₖ₊₁ - Xₖₖ * Rₖₖ₊₁/Rₖₖ
160+
161+
for k = 2:n-1
162+
Xₖₖ₋₁,Xₖₖ,Xₖₖ₊₁ = X.dl[k-1], X.d[k], X.du[k]
163+
Y.dl[k-1] = Xₖₖ₋₁/Rₖₖ
164+
Y.d[k] = Xₖₖ-Xₖₖ₋₁*Rₖₖ₊₁/Rₖₖ
165+
Y.du[k] = Xₖₖ₋₁/Rₖₖ
166+
Rₖₖ,Rₖₖ₊₁,Rₖ₋₁ₖ₊₁,Rₖ₋₁ₖ = R.data[3,k], R.data[2,k+1],R.data[1,k+1],Rₖₖ₊₁ # R[2,2], R[2,3], R[1,3]
167+
Y.d[k] /= Rₖₖ
168+
Y.du[k-1] /= Rₖₖ
169+
Y.du[k] *= Rₖ₋₁ₖ*Rₖₖ₊₁/Rₖₖ - Rₖ₋₁ₖ₊₁
170+
Y.du[k] += Xₖₖ₊₁ - Xₖₖ * Rₖₖ₊₁ / Rₖₖ
171171
end
172-
UX.d[n] = U.data[3,n]*X.d[n]
173172

174-
@inbounds for j = 1:n-1
175-
UX.dl[j] = U.data[3,j+1]*X.dl[j]
176-
end
173+
k = n
174+
Xₖₖ₋₁,Xₖₖ = X.dl[k-1], X.d[k]
175+
Y.dl[k-1] = Xₖₖ₋₁/Rₖₖ
176+
Y.d[k] = Xₖₖ-Xₖₖ₋₁*Rₖₖ₊₁/Rₖₖ
177+
Rₖₖ = R.data[3,k] # R[2,2], R[2,3], R[1,3]
178+
Y.d[k] /= Rₖₖ
179+
Y.du[k-1] /= Rₖₖ
177180

178-
@inbounds for j = 1:n-2
179-
UX.du[j] = U.data[3,j]*X.du[j] + U.data[2,j+1]*X.d[j+1] + U.data[1,j+2]*X.dl[j+1]
180-
end
181-
182-
UX.du[n-1] = U.data[3,n-1]*X.du[n-1] + U.data[2,n]*X.d[n]
183-
184-
UX
181+
Y
185182
end
186183

187184

@@ -193,7 +190,8 @@ end
193190

194191
n = 1000; @time U = V = R0[1:n,1:n];
195192
@time X = Tridiagonal(Vector(X_T.dl[1:n-1]), Vector(X_T.d[1:n]), Vector(X_T.du[1:n-1]));
196-
197-
@test Tridiagonal(U*X) upper_mul_tri_triview(U, X)
198-
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)
199197
end

0 commit comments

Comments
 (0)