From 75d178804214a81410f8fec86a17fe8e18f892eb Mon Sep 17 00:00:00 2001 From: KristofferC Date: Thu, 9 May 2024 11:52:46 +0200 Subject: [PATCH] Revert "Use `copyto!` in converting `Diagonal`/`Bidiagonal`/`Tridiagonal` to `Matrix` (#53912)" This reverts commit 19919b70d342250c69b59e006d2b1e1dd704c06a. --- stdlib/LinearAlgebra/src/bidiag.jl | 19 +++++++++------ stdlib/LinearAlgebra/src/diagonal.jl | 11 ++++----- stdlib/LinearAlgebra/src/tridiag.jl | 33 ++++++++++++--------------- stdlib/LinearAlgebra/test/bidiag.jl | 13 ----------- stdlib/LinearAlgebra/test/diagonal.jl | 13 ----------- stdlib/LinearAlgebra/test/special.jl | 2 -- stdlib/LinearAlgebra/test/tridiag.jl | 8 ------- 7 files changed, 32 insertions(+), 67 deletions(-) diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index 53fbff5839630..7236488563ca7 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -195,14 +195,19 @@ end #Converting from Bidiagonal to dense Matrix function Matrix{T}(A::Bidiagonal) where T - B = Matrix{T}(undef, size(A)) - if haszero(T) # optimized path for types with zero(T) defined - size(B,1) > 1 && fill!(B, zero(T)) - copyto!(view(B, diagind(B)), A.dv) - copyto!(view(B, diagind(B, A.uplo == 'U' ? 1 : -1)), A.ev) - else - copyto!(B, A) + n = size(A, 1) + B = Matrix{T}(undef, n, n) + n == 0 && return B + n > 1 && fill!(B, zero(T)) + @inbounds for i = 1:n - 1 + B[i,i] = A.dv[i] + if A.uplo == 'U' + B[i,i+1] = A.ev[i] + else + B[i+1,i] = A.ev[i] + end end + B[n,n] = A.dv[n] return B end Matrix(A::Bidiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(A) diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index bb722d20bb05b..d68a691f8a149 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -116,12 +116,11 @@ AbstractMatrix{T}(D::Diagonal{T}) where {T} = copy(D) Matrix(D::Diagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(D) Array(D::Diagonal{T}) where {T} = Matrix(D) function Matrix{T}(D::Diagonal) where {T} - B = Matrix{T}(undef, size(D)) - if haszero(T) # optimized path for types with zero(T) defined - size(B,1) > 1 && fill!(B, zero(T)) - copyto!(view(B, diagind(B)), D.diag) - else - copyto!(B, D) + n = size(D, 1) + B = Matrix{T}(undef, n, n) + n > 1 && fill!(B, zero(T)) + @inbounds for i in 1:n + B[i,i] = D.diag[i] end return B end diff --git a/stdlib/LinearAlgebra/src/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index ffdb56ba2dd77..081232b08a46a 100644 --- a/stdlib/LinearAlgebra/src/tridiag.jl +++ b/stdlib/LinearAlgebra/src/tridiag.jl @@ -135,17 +135,13 @@ function Matrix{T}(M::SymTridiagonal) where T n = size(M, 1) Mf = Matrix{T}(undef, n, n) n == 0 && return Mf - if haszero(T) # optimized path for types with zero(T) defined - n > 2 && fill!(Mf, zero(T)) - @inbounds for i = 1:n-1 - Mf[i,i] = symmetric(M.dv[i], :U) - Mf[i+1,i] = transpose(M.ev[i]) - Mf[i,i+1] = M.ev[i] - end - Mf[n,n] = symmetric(M.dv[n], :U) - else - copyto!(Mf, M) + n > 2 && fill!(Mf, zero(T)) + @inbounds for i = 1:n-1 + Mf[i,i] = symmetric(M.dv[i], :U) + Mf[i+1,i] = transpose(M.ev[i]) + Mf[i,i+1] = M.ev[i] end + Mf[n,n] = symmetric(M.dv[n], :U) return Mf end Matrix(M::SymTridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M) @@ -590,14 +586,15 @@ axes(M::Tridiagonal) = (ax = axes(M.d,1); (ax, ax)) function Matrix{T}(M::Tridiagonal) where {T} A = Matrix{T}(undef, size(M)) - if haszero(T) # optimized path for types with zero(T) defined - size(A,1) > 2 && fill!(A, zero(T)) - copyto!(view(A, diagind(A)), M.d) - copyto!(view(A, diagind(A,1)), M.du) - copyto!(view(A, diagind(A,-1)), M.dl) - else - copyto!(A, M) - end + n = length(M.d) + n == 0 && return A + n > 2 && fill!(A, zero(T)) + for i in 1:n-1 + A[i,i] = M.d[i] + A[i+1,i] = M.dl[i] + A[i,i+1] = M.du[i] + end + A[n,n] = M.d[n] A end Matrix(M::Tridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M) diff --git a/stdlib/LinearAlgebra/test/bidiag.jl b/stdlib/LinearAlgebra/test/bidiag.jl index 435c99f340b6b..80a1b27ead829 100644 --- a/stdlib/LinearAlgebra/test/bidiag.jl +++ b/stdlib/LinearAlgebra/test/bidiag.jl @@ -904,17 +904,4 @@ end @test mul!(C1, B, sv, 1, 2) == mul!(C2, B, v, 1 ,2) end -@testset "Matrix conversion for non-numeric and undef" begin - B = Bidiagonal(Vector{BigInt}(undef, 4), fill(big(3), 3), :U) - M = Matrix(B) - B[diagind(B)] .= 4 - M[diagind(M)] .= 4 - @test diag(B) == diag(M) - - B = Bidiagonal(fill(Diagonal([1,3]), 3), fill(Diagonal([1,3]), 2), :U) - M = Matrix{eltype(B)}(B) - @test M isa Matrix{eltype(B)} - @test M == B -end - end # module TestBidiagonal diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index 91e69c0e30bf9..d45aa5e7fad98 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -1298,17 +1298,4 @@ end @test yadj == x' end -@testset "Matrix conversion for non-numeric and undef" begin - D = Diagonal(Vector{BigInt}(undef, 4)) - M = Matrix(D) - D[diagind(D)] .= 4 - M[diagind(M)] .= 4 - @test diag(D) == diag(M) - - D = Diagonal(fill(Diagonal([1,3]), 2)) - M = Matrix{eltype(D)}(D) - @test M isa Matrix{eltype(D)} - @test M == D -end - end # module TestDiagonal diff --git a/stdlib/LinearAlgebra/test/special.jl b/stdlib/LinearAlgebra/test/special.jl index be04fb564a6e8..43e114e5b97c1 100644 --- a/stdlib/LinearAlgebra/test/special.jl +++ b/stdlib/LinearAlgebra/test/special.jl @@ -114,8 +114,6 @@ Random.seed!(1) Base.zero(x::Union{TypeWithoutZero, TypeWithZero}) = zero(typeof(x)) Base.zero(::Type{<:Union{TypeWithoutZero, TypeWithZero}}) = TypeWithZero() LinearAlgebra.symmetric(::TypeWithoutZero, ::Symbol) = TypeWithoutZero() - LinearAlgebra.symmetric_type(::Type{TypeWithoutZero}) = TypeWithoutZero - Base.copy(A::TypeWithoutZero) = A Base.transpose(::TypeWithoutZero) = TypeWithoutZero() d = fill(TypeWithoutZero(), 3) du = fill(TypeWithoutZero(), 2) diff --git a/stdlib/LinearAlgebra/test/tridiag.jl b/stdlib/LinearAlgebra/test/tridiag.jl index 3829cd4e1743c..70c84faf9884f 100644 --- a/stdlib/LinearAlgebra/test/tridiag.jl +++ b/stdlib/LinearAlgebra/test/tridiag.jl @@ -859,12 +859,4 @@ end @test axes(B) === (ax, ax) end -@testset "Matrix conversion for non-numeric and undef" begin - T = Tridiagonal(fill(big(3), 3), Vector{BigInt}(undef, 4), fill(big(3), 3)) - M = Matrix(T) - T[diagind(T)] .= 4 - M[diagind(M)] .= 4 - @test diag(T) == diag(M) -end - end # module TestTridiagonal