Skip to content

Commit 88e7fbc

Browse files
authored
Adjust signatures for bkfact to use Symmetric and Hermitian (#22605)
* Adjust signatures for bkfact to use Symmetric and Hermitian * Add NEWS.md entry
1 parent 05719b4 commit 88e7fbc

File tree

5 files changed

+63
-61
lines changed

5 files changed

+63
-61
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ Deprecated or removed
105105
have been deprecated in favor of `isposdef(Hermitian(A, UL))` and `isposdef!(Hermitian(A, UL))`
106106
respectively ([#22245]).
107107

108+
* The `bkfact`/`bkfact!` methods that accepted `uplo` and `issymmetric` symbols have been deprecated
109+
in favor of using `Hermitian` (or `Symmetric`) views ([#22605]).
110+
108111
* The function `current_module` is deprecated and replaced with `@__MODULE__` ([#22064]).
109112
This caused the deprecation of some reflection methods (such as `macroexpand` and `isconst`),
110113
which now require a module argument.

base/deprecated.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,18 @@ export conv, conv2, deconv, filt, filt!, xcorr
14911491
@deprecate cov(X::AbstractVector, Y::AbstractVector, corrected::Bool) cov(X, Y, corrected=corrected)
14921492
@deprecate cov(X::AbstractVecOrMat, Y::AbstractVecOrMat, vardim::Int, corrected::Bool) cov(X, Y, vardim, corrected=corrected)
14931493

1494+
# bkfact
1495+
function bkfact(A::StridedMatrix, uplo::Symbol, symmetric::Bool = issymmetric(A), rook::Bool = false)
1496+
depwarn("bkfact with uplo and symmetric arguments deprecated. Please use bkfact($(symmetric ? "Symmetric(" : "Hermitian(")A, :$uplo))",
1497+
:bkfact)
1498+
return bkfact(symmetric ? Symmetric(A, uplo) : Hermitian(A, uplo), rook)
1499+
end
1500+
function bkfact!(A::StridedMatrix, uplo::Symbol, symmetric::Bool = issymmetric(A), rook::Bool = false)
1501+
depwarn("bkfact! with uplo and symmetric arguments deprecated. Please use bkfact!($(symmetric ? "Symmetric(" : "Hermitian(")A, :$uplo))",
1502+
:bkfact!)
1503+
return bkfact!(symmetric ? Symmetric(A, uplo) : Hermitian(A, uplo), rook)
1504+
end
1505+
14941506
# END 0.7 deprecations
14951507

14961508
# BEGIN 1.0 deprecations

base/linalg/bunchkaufman.jl

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,22 @@ BunchKaufman(A::AbstractMatrix{T}, ipiv::Vector{BlasInt}, uplo::Char, symmetric:
2222
`bkfact!` is the same as [`bkfact`](@ref), but saves space by overwriting the
2323
input `A`, instead of creating a copy.
2424
"""
25-
function bkfact!(A::StridedMatrix{<:BlasReal}, uplo::Symbol = :U,
26-
symmetric::Bool = issymmetric(A), rook::Bool = false)
27-
28-
if !symmetric
29-
throw(ArgumentError("Bunch-Kaufman decomposition is only valid for symmetric matrices"))
30-
end
31-
if rook
32-
LD, ipiv, info = LAPACK.sytrf_rook!(char_uplo(uplo), A)
33-
else
34-
LD, ipiv, info = LAPACK.sytrf!(char_uplo(uplo), A)
35-
end
36-
BunchKaufman(LD, ipiv, char_uplo(uplo), symmetric, rook, info)
25+
function bkfact!(A::RealHermSymComplexSym{T,S} where {T<:BlasReal,S<:StridedMatrix}, rook::Bool = false)
26+
LD, ipiv, info = rook ? LAPACK.sytrf_rook!(A.uplo, A.data) : LAPACK.sytrf!(A.uplo, A.data)
27+
BunchKaufman(LD, ipiv, A.uplo, true, rook, info)
3728
end
38-
function bkfact!(A::StridedMatrix{<:BlasComplex}, uplo::Symbol=:U,
39-
symmetric::Bool=issymmetric(A), rook::Bool=false)
40-
41-
if rook
42-
if symmetric
43-
LD, ipiv, info = LAPACK.sytrf_rook!(char_uplo(uplo), A)
44-
else
45-
LD, ipiv, info = LAPACK.hetrf_rook!(char_uplo(uplo), A)
46-
end
29+
function bkfact!(A::Hermitian{T,S} where {T<:BlasComplex,S<:StridedMatrix{T}}, rook::Bool = false)
30+
LD, ipiv, info = rook ? LAPACK.hetrf_rook!(A.uplo, A.data) : LAPACK.hetrf!(A.uplo, A.data)
31+
BunchKaufman(LD, ipiv, A.uplo, false, rook, info)
32+
end
33+
function bkfact!(A::StridedMatrix{<:BlasFloat}, rook::Bool = false)
34+
if ishermitian(A)
35+
return bkfact!(Hermitian(A), rook)
36+
elseif issymmetric(A)
37+
return bkfact!(Symmetric(A), rook)
4738
else
48-
if symmetric
49-
LD, ipiv, info = LAPACK.sytrf!(char_uplo(uplo), A)
50-
else
51-
LD, ipiv, info = LAPACK.hetrf!(char_uplo(uplo), A)
52-
end
39+
throw(ArgumentError("Bunch-Kaufman decomposition is only valid for symmetric or Hermitian matrices"))
5340
end
54-
BunchKaufman(LD, ipiv, char_uplo(uplo), symmetric, rook, info)
5541
end
5642

5743
"""
@@ -69,13 +55,8 @@ The following functions are available for
6955
[^Bunch1977]: J R Bunch and L Kaufman, Some stable methods for calculating inertia and solving symmetric linear systems, Mathematics of Computation 31:137 (1977), 163-179. [url](http://www.ams.org/journals/mcom/1977-31-137/S0025-5718-1977-0428694-0/).
7056
7157
"""
72-
bkfact(A::StridedMatrix{<:BlasFloat}, uplo::Symbol=:U, symmetric::Bool=issymmetric(A),
73-
rook::Bool=false) =
74-
bkfact!(copy(A), uplo, symmetric, rook)
75-
bkfact(A::StridedMatrix{T}, uplo::Symbol=:U, symmetric::Bool=issymmetric(A),
76-
rook::Bool=false) where {T} =
77-
bkfact!(convert(Matrix{promote_type(Float32, typeof(sqrt(one(T))))}, A),
78-
uplo, symmetric, rook)
58+
bkfact(A::AbstractMatrix{T}, rook::Bool=false) where {T} =
59+
bkfact!(copy_oftype(A, typeof(sqrt(one(T)))), rook)
7960

8061
convert(::Type{BunchKaufman{T}}, B::BunchKaufman{T}) where {T} = B
8162
convert(::Type{BunchKaufman{T}}, B::BunchKaufman) where {T} =
@@ -90,9 +71,9 @@ ishermitian(B::BunchKaufman) = !B.symmetric
9071

9172
issuccess(B::BunchKaufman) = B.info == 0
9273

93-
function Base.show(io::IO, F::BunchKaufman)
94-
println(io, summary(F))
95-
print(io, "successful: $(issuccess(F))")
74+
function Base.show(io::IO, mime::MIME{Symbol("text/plain")}, B::BunchKaufman)
75+
println(io, summary(B))
76+
print(io, "successful: $(issuccess(B))")
9677
end
9778

9879
function inv(B::BunchKaufman{<:BlasReal})

base/linalg/symmetric.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,6 @@ for T in (:Symmetric, :Hermitian), op in (:+, :-, :*, :/)
330330
@eval ($op)(A::$T, x::$S) = ($T)(($op)(A.data, x), Symbol(A.uplo))
331331
end
332332

333-
bkfact(A::HermOrSym) = bkfact(A.data, Symbol(A.uplo), issymmetric(A))
334333
factorize(A::HermOrSym) = bkfact(A)
335334

336335
det(A::RealHermSymComplexHerm) = real(det(bkfact(A)))

test/linalg/bunchkaufman.jl

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,17 @@ bimg = randn(n,2)/2
2323
a = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal)
2424
a2 = eltya == Int ? rand(1:7, n, n) : convert(Matrix{eltya}, eltya <: Complex ? complex.(a2real, a2img) : a2real)
2525
@testset for atype in ("Array", "SubArray")
26-
asym = a'+a # symmetric indefinite
27-
apd = a'*a # symmetric positive-definite
26+
asym = a.'+ a # symmetric indefinite
27+
aher = a' + a # Hermitian indefinite
28+
apd = a' * a # Positive-definite
2829
if atype == "Array"
29-
a = a
30+
a = a
3031
a2 = a2
3132
else
32-
a = view(a, 1:n, 1:n)
33-
a2 = view(a2, 1:n, 1:n)
34-
asym = view(asym, 1:n, 1:n)
35-
apd = view(apd, 1:n, 1:n)
33+
a = view(a , 1:n, 1:n)
34+
a2 = view(a2 , 1:n, 1:n)
35+
aher = view(aher, 1:n, 1:n)
36+
apd = view(apd , 1:n, 1:n)
3637
end
3738
ε = εa = eps(abs(float(one(eltya))))
3839

@@ -48,36 +49,40 @@ bimg = randn(n,2)/2
4849
εb = eps(abs(float(one(eltyb))))
4950
ε = max(εa,εb)
5051

51-
@testset "(Automatic) Bunch-Kaufman factor of indefinite matrix" begin
52-
bc1 = factorize(asym)
52+
# check that factorize gives a Bunch-Kaufman
53+
@test isa(factorize(asym), LinAlg.BunchKaufman)
54+
@test isa(factorize(aher), LinAlg.BunchKaufman)
55+
56+
@testset "$uplo Bunch-Kaufman factor of indefinite matrix" for uplo in (:L, :U)
57+
bc1 = bkfact(Hermitian(aher, uplo))
5358
@test LinAlg.issuccess(bc1)
5459
@test logabsdet(bc1)[1] log(abs(det(bc1)))
5560
if eltya <: Real
5661
@test logabsdet(bc1)[2] == sign(det(bc1))
5762
else
5863
@test logabsdet(bc1)[2] sign(det(bc1))
5964
end
60-
@test inv(bc1)*asym eye(n)
61-
@test asym*(bc1\b) b atol=1000ε
65+
@test inv(bc1)*aher eye(n)
66+
@test aher*(bc1\b) b atol=1000ε
6267
@testset for rook in (false, true)
63-
@test inv(bkfact(a.'+a, :U, true, rook))*(a.'+a) eye(n)
68+
@test inv(bkfact(Symmetric(a.' + a, uplo), rook))*(a.' + a) eye(n)
6469
@test size(bc1) == size(bc1.LD)
65-
@test size(bc1,1) == size(bc1.LD,1)
66-
@test size(bc1,2) == size(bc1.LD,2)
70+
@test size(bc1, 1) == size(bc1.LD, 1)
71+
@test size(bc1, 2) == size(bc1.LD, 2)
6772
if eltya <: BlasReal
6873
@test_throws ArgumentError bkfact(a)
6974
end
7075
end
7176
end
7277

73-
@testset "Bunch-Kaufman factors of a pos-def matrix" begin
74-
@testset for rook in (false, true)
75-
bc2 = bkfact(apd, :U, issymmetric(apd), rook)
78+
@testset "$uplo Bunch-Kaufman factors of a pos-def matrix" for uplo in (:U, :L)
79+
@testset "rook pivoting: $rook" for rook in (false, true)
80+
bc2 = bkfact(Hermitian(apd, uplo), rook)
7681
@test LinAlg.issuccess(bc2)
7782
@test logdet(bc2) log(det(bc2))
7883
@test logabsdet(bc2)[1] log(abs(det(bc2)))
7984
@test logabsdet(bc2)[2] == sign(det(bc2))
80-
@test inv(bc2)*apd eye(n)
85+
@test inv(bc2)*apd eye(eltyb, n)
8186
@test apd*(bc2\b) b atol=150000ε
8287
@test ishermitian(bc2) == !issymmetric(bc2)
8388
end
@@ -104,11 +109,13 @@ end
104109
end
105110

106111
@testset for rook in (false, true)
107-
F = bkfact(As, :U, issymmetric(As), rook)
108-
@test !LinAlg.issuccess(F)
109-
@test det(F) == 0
110-
@test_throws LinAlg.SingularException inv(F)
111-
@test_throws LinAlg.SingularException F \ ones(size(As, 1))
112+
@testset for uplo in (:L, :U)
113+
F = bkfact(issymmetric(As) ? Symmetric(As, uplo) : Hermitian(As, uplo), rook)
114+
@test !LinAlg.issuccess(F)
115+
@test det(F) == 0
116+
@test_throws LinAlg.SingularException inv(F)
117+
@test_throws LinAlg.SingularException F \ ones(size(As, 1))
118+
end
112119
end
113120
end
114121
end

0 commit comments

Comments
 (0)