Skip to content

Commit e1439a3

Browse files
dkarraschandreasnoack
authored andcommitted
add rdiv! for Cholesky(Pivoted) (#32594)
* add rdiv! for Cholesky(Pivoted) * also test L-branches
1 parent b9b099f commit e1439a3

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

stdlib/LinearAlgebra/src/cholesky.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,32 @@ function ldiv!(C::CholeskyPivoted, B::StridedMatrix)
514514
end
515515
end
516516

517+
function rdiv!(B::StridedMatrix, C::Cholesky{<:Any,<:AbstractMatrix})
518+
if C.uplo == 'L'
519+
return rdiv!(rdiv!(B, adjoint(LowerTriangular(C.factors))), LowerTriangular(C.factors))
520+
else
521+
return rdiv!(rdiv!(B, UpperTriangular(C.factors)), adjoint(UpperTriangular(C.factors)))
522+
end
523+
end
524+
525+
function LinearAlgebra.rdiv!(B::StridedMatrix, C::CholeskyPivoted)
526+
n = size(C, 2)
527+
for i in 1:size(B, 1)
528+
permute!(view(B, i, 1:n), C.piv)
529+
end
530+
if C.uplo == 'L'
531+
rdiv!(rdiv!(B, adjoint(LowerTriangular(C.factors))),
532+
LowerTriangular(C.factors))
533+
else
534+
rdiv!(rdiv!(B, UpperTriangular(C.factors)),
535+
adjoint(UpperTriangular(C.factors)))
536+
end
537+
for i in 1:size(B, 1)
538+
invpermute!(view(B, i, 1:n), C.piv)
539+
end
540+
B
541+
end
542+
517543
isposdef(C::Union{Cholesky,CholeskyPivoted}) = C.info == 0
518544

519545
function det(C::Cholesky)

stdlib/LinearAlgebra/test/cholesky.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,42 @@ end
168168
end
169169
end
170170
end
171+
172+
@testset "solve with generic Cholesky" begin
173+
Breal = convert(Matrix{BigFloat}, randn(n,n)/2)
174+
Bimg = convert(Matrix{BigFloat}, randn(n,n)/2)
175+
B = eltya <: Complex ? complex.(Breal, Bimg) : Breal
176+
εb = eps(abs(float(one(eltype(B)))))
177+
ε = max(εa,εb)
178+
179+
for B in (B, view(B, 1:n, 1:n)) # Array and SubArray
180+
181+
# Test error bound on linear solver: LAWNS 14, Theorem 2.1
182+
# This is a surprisingly loose bound
183+
cpapd = cholesky(eltya <: Complex ? apdh : apds)
184+
BB = copy(B)
185+
rdiv!(BB, cpapd)
186+
@test norm(B / apd - BB, 1) / norm(BB, 1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
187+
@test norm(BB * apd - B, 1) / norm(B, 1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
188+
cpapd = cholesky(eltya <: Complex ? apdhL : apdsL)
189+
BB = copy(B)
190+
rdiv!(BB, cpapd)
191+
@test norm(B / apd - BB, 1) / norm(BB, 1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
192+
@test norm(BB * apd - B, 1) / norm(B, 1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
193+
if eltya != BigFloat
194+
cpapd = cholesky(eltya <: Complex ? apdh : apds, Val(true))
195+
BB = copy(B)
196+
rdiv!(BB, cpapd)
197+
@test norm(B / apd - BB, 1) / norm(BB, 1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
198+
@test norm(BB * apd - B, 1) / norm(B, 1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
199+
cpapd = cholesky(eltya <: Complex ? apdhL : apdsL, Val(true))
200+
BB = copy(B)
201+
rdiv!(BB, cpapd)
202+
@test norm(B / apd - BB, 1) / norm(BB, 1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
203+
@test norm(BB * apd - B, 1) / norm(B, 1) <= (3n^2 + n + n^3*ε)*ε/(1-(n+1)*ε)*κ
204+
end
205+
end
206+
end
171207
if eltya <: BlasFloat
172208
@testset "generic cholesky!" begin
173209
if eltya <: Complex

0 commit comments

Comments
 (0)