diff --git a/stdlib/LinearAlgebra/src/bunchkaufman.jl b/stdlib/LinearAlgebra/src/bunchkaufman.jl index 8d1ded9bf8111..5a73c656abe33 100644 --- a/stdlib/LinearAlgebra/src/bunchkaufman.jl +++ b/stdlib/LinearAlgebra/src/bunchkaufman.jl @@ -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 diff --git a/stdlib/LinearAlgebra/src/cholesky.jl b/stdlib/LinearAlgebra/src/cholesky.jl index de418fe8426a5..510ec2f2a341a 100644 --- a/stdlib/LinearAlgebra/src/cholesky.jl +++ b/stdlib/LinearAlgebra/src/cholesky.jl @@ -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) @@ -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 diff --git a/stdlib/LinearAlgebra/src/eigen.jl b/stdlib/LinearAlgebra/src/eigen.jl index d1d2a156b1ed4..e0124f2e9d870 100644 --- a/stdlib/LinearAlgebra/src/eigen.jl +++ b/stdlib/LinearAlgebra/src/eigen.jl @@ -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 diff --git a/stdlib/LinearAlgebra/test/cholesky.jl b/stdlib/LinearAlgebra/test/cholesky.jl index cce26af40108b..af7eed3f5a764 100644 --- a/stdlib/LinearAlgebra/test/cholesky.jl +++ b/stdlib/LinearAlgebra/test/cholesky.jl @@ -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) diff --git a/stdlib/LinearAlgebra/test/eigen.jl b/stdlib/LinearAlgebra/test/eigen.jl index 73d9147a82a09..174deffbc53e9 100644 --- a/stdlib/LinearAlgebra/test/eigen.jl +++ b/stdlib/LinearAlgebra/test/eigen.jl @@ -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 diff --git a/stdlib/LinearAlgebra/test/factorization.jl b/stdlib/LinearAlgebra/test/factorization.jl index 72233293ff515..f80c5197836a1 100644 --- a/stdlib/LinearAlgebra/test/factorization.jl +++ b/stdlib/LinearAlgebra/test/factorization.jl @@ -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