Skip to content

Commit

Permalink
Compare Cholesky and BunchKaufman by properties (JuliaLang#54509)
Browse files Browse the repository at this point in the history
  • Loading branch information
jishnub authored May 18, 2024
1 parent c28a9de commit df94a65
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 14 deletions.
11 changes: 11 additions & 0 deletions stdlib/LinearAlgebra/src/bunchkaufman.jl
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,17 @@ end
Base.propertynames(B::BunchKaufman, private::Bool=false) =
(:p, :P, :L, :U, :D, (private ? fieldnames(typeof(B)) : ())...)

function Base.:(==)(B1::BunchKaufman, B2::BunchKaufman)
# check for the equality between properties instead of fields
B1.p == B2.p || return false
if B1.uplo == 'L'
B1.L == B2.L || return false
else
B1.U == B2.U || return false
end
return (B1.D == B2.D)
end

function getproperties!(B::BunchKaufman{T,<:StridedMatrix}) where {T<:BlasFloat}
# NOTE: Unlike in the 'getproperty' function, in this function L/U and D are computed in place.
if B.rook
Expand Down
10 changes: 10 additions & 0 deletions stdlib/LinearAlgebra/src/cholesky.jl
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,11 @@ end
Base.propertynames(F::Cholesky, private::Bool=false) =
(:U, :L, :UL, (private ? fieldnames(typeof(F)) : ())...)

function Base.:(==)(C1::Cholesky, C2::Cholesky)
C1.uplo == C2.uplo || return false
C1.uplo == 'L' ? (C1.L == C2.L) : (C1.U == C2.U)
end

function getproperty(C::CholeskyPivoted{T}, d::Symbol) where {T}
Cfactors = getfield(C, :factors)
Cuplo = getfield(C, :uplo)
Expand All @@ -569,6 +574,11 @@ end
Base.propertynames(F::CholeskyPivoted, private::Bool=false) =
(:U, :L, :p, :P, (private ? fieldnames(typeof(F)) : ())...)

function Base.:(==)(C1::CholeskyPivoted, C2::CholeskyPivoted)
(C1.uplo == C2.uplo && C1.p == C2.p) || return false
C1.uplo == 'L' ? (C1.L == C2.L) : (C1.U == C2.U)
end

issuccess(C::Union{Cholesky,CholeskyPivoted}) = C.info == 0

adjoint(C::Union{Cholesky,CholeskyPivoted}) = C
Expand Down
21 changes: 13 additions & 8 deletions stdlib/LinearAlgebra/src/eigen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -658,14 +658,19 @@ function show(io::IO, mime::MIME{Symbol("text/plain")}, F::Union{Eigen,Generaliz
show(io, mime, F.vectors)
end

function Base.hash(F::Eigen, h::UInt)
return hash(F.values, hash(F.vectors, hash(Eigen, h)))
end
function Base.:(==)(A::Eigen, B::Eigen)
return A.values == B.values && A.vectors == B.vectors
end
function Base.isequal(A::Eigen, B::Eigen)
return isequal(A.values, B.values) && isequal(A.vectors, B.vectors)
_equalcheck(f, Avalues, Avectors, Bvalues, Bvectors) = f(Avalues, Bvalues) && f(Avectors, Bvectors)
for T in (Eigen, GeneralizedEigen)
@eval begin
function Base.hash(F::$T, h::UInt)
return hash(F.values, hash(F.vectors, hash($T, h)))
end
function Base.:(==)(A::$T, B::$T)
return _equalcheck(==, A..., B...)
end
function Base.isequal(A::$T, B::$T)
return _equalcheck(isequal, A..., B...)
end
end
end

# Conversion methods
Expand Down
1 change: 1 addition & 0 deletions stdlib/LinearAlgebra/test/cholesky.jl
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ end
M = Matrix{BigFloat}(undef, 2, 2)
M[1,1] = M[2,2] = M[1+(uplo=='L'), 1+(uplo=='U')] = 3
C = Cholesky(M, uplo, 0)
@test C == C
@test C.L == C.U'
# parameters are arbitrary
C = CholeskyPivoted(M, uplo, [1,2], 2, 0.0, 0)
Expand Down
20 changes: 16 additions & 4 deletions stdlib/LinearAlgebra/test/eigen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,22 @@ end
end

@testset "equality of eigen factorizations" begin
A = randn(3, 3)
@test eigen(A) == eigen(A)
@test hash(eigen(A)) == hash(eigen(A))
@test isequal(eigen(A), eigen(A))
A1 = Float32[1 0; 0 2]
A2 = Float64[1 0; 0 2]
EA1 = eigen(A1)
EA2 = eigen(A2)
@test EA1 == EA2
@test hash(EA1) == hash(EA2)
@test isequal(EA1, EA2)

# trivial RHS to ensure that values match exactly
B1 = Float32[1 0; 0 1]
B2 = Float64[1 0; 0 1]
EA1B1 = eigen(A1, B1)
EA2B2 = eigen(A2, B2)
@test EA1B1 == EA2B2
@test hash(EA1B1) == hash(EA2B2)
@test isequal(EA1B1, EA2B2)
end

@testset "Float16" begin
Expand Down
4 changes: 2 additions & 2 deletions stdlib/LinearAlgebra/test/factorization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ using Test, LinearAlgebra
return x isa AbstractArray{Float64} ? Float64.(Float32.(x)) : x
end...)

@test F == G broken=!(f === eigen || f === qr)
@test isequal(F, G) broken=!(f === eigen || f === qr)
@test F == G broken=!(f === eigen || f === qr || f == bunchkaufman || f == cholesky || F isa CholeskyPivoted)
@test isequal(F, G) broken=!(f === eigen || f === qr || f == bunchkaufman || f == cholesky || F isa CholeskyPivoted)
@test hash(F) == hash(G)
end

Expand Down

0 comments on commit df94a65

Please sign in to comment.