@@ -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)
111111end
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-
134113function 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
164144end
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
185182end
186183
187184
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)
199197end
0 commit comments