Skip to content

Commit

Permalink
avoid conversion from Char to String to Symbol in some LinearAlgebra …
Browse files Browse the repository at this point in the history
…routines (#29352)
  • Loading branch information
KristofferC authored and fredrikekre committed Sep 25, 2018
1 parent c37f4aa commit 993e7d7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 17 deletions.
20 changes: 17 additions & 3 deletions stdlib/LinearAlgebra/src/LinearAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,28 @@ end

function char_uplo(uplo::Symbol)
if uplo == :U
'U'
return 'U'
elseif uplo == :L
'L'
return 'L'
else
throw(ArgumentError("uplo argument must be either :U (upper) or :L (lower)"))
throw_uplo()
end
end

function sym_uplo(uplo::Char)
if uplo == 'U'
return :U
elseif uplo == 'L'
return :L
else
throw_uplo()
end
end


@noinline throw_uplo() = throw(ArgumentError("uplo argument must be either :U (upper) or :L (lower)"))


"""
ldiv!(Y, A, B) -> Y
Expand Down
4 changes: 2 additions & 2 deletions stdlib/LinearAlgebra/src/cholesky.jl
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,9 @@ function getproperty(C::CholeskyPivoted{T}, d::Symbol) where T<:BlasFloat
Cfactors = getfield(C, :factors)
Cuplo = getfield(C, :uplo)
if d == :U
return UpperTriangular(Symbol(Cuplo) == d ? Cfactors : copy(Cfactors'))
return UpperTriangular(sym_uplo(Cuplo) == d ? Cfactors : copy(Cfactors'))
elseif d == :L
return LowerTriangular(Symbol(Cuplo) == d ? Cfactors : copy(Cfactors'))
return LowerTriangular(sym_uplo(Cuplo) == d ? Cfactors : copy(Cfactors'))
elseif d == :p
return getfield(C, :piv)
elseif d == :P
Expand Down
24 changes: 12 additions & 12 deletions stdlib/LinearAlgebra/src/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ for (S, H) in ((:Symmetric, :Hermitian), (:Hermitian, :Symmetric))
throw(ArgumentError("Cannot construct $($S); uplo doesn't match"))
end
end
$S(A::$H) = $S(A.data, Symbol(A.uplo))
$S(A::$H) = $S(A.data, sym_uplo(A.uplo))
function $S(A::$H, uplo::Symbol)
if A.uplo == char_uplo(uplo)
return $S(A.data, Symbol(A.uplo))
return $S(A.data, sym_uplo(A.uplo))
else
throw(ArgumentError("Cannot construct $($S); uplo doesn't match"))
end
Expand All @@ -185,7 +185,7 @@ size(A::HermOrSym) = size(A.data)
@inline function getindex(A::Symmetric, i::Integer, j::Integer)
@boundscheck checkbounds(A, i, j)
@inbounds if i == j
return symmetric(A.data[i, j], Symbol(A.uplo))::symmetric_type(eltype(A.data))
return symmetric(A.data[i, j], sym_uplo(A.uplo))::symmetric_type(eltype(A.data))
elseif (A.uplo == 'U') == (i < j)
return A.data[i, j]
else
Expand All @@ -195,7 +195,7 @@ end
@inline function getindex(A::Hermitian, i::Integer, j::Integer)
@boundscheck checkbounds(A, i, j)
@inbounds if i == j
return hermitian(A.data[i, j], Symbol(A.uplo))::hermitian_type(eltype(A.data))
return hermitian(A.data[i, j], sym_uplo(A.uplo))::hermitian_type(eltype(A.data))
elseif (A.uplo == 'U') == (i < j)
return A.data[i, j]
else
Expand Down Expand Up @@ -236,14 +236,14 @@ similar(A::Union{Symmetric,Hermitian}, ::Type{T}, dims::Dims{N}) where {T,N} = s
function Matrix(A::Symmetric)
B = copytri!(convert(Matrix, copy(A.data)), A.uplo)
for i = 1:size(A, 1)
B[i,i] = symmetric(B[i,i], Symbol(A.uplo))::symmetric_type(eltype(A.data))
B[i,i] = symmetric(B[i,i], sym_uplo(A.uplo))::symmetric_type(eltype(A.data))
end
return B
end
function Matrix(A::Hermitian)
B = copytri!(convert(Matrix, copy(A.data)), A.uplo, true)
for i = 1:size(A, 1)
B[i,i] = hermitian(B[i,i], Symbol(A.uplo))::hermitian_type(eltype(A.data))
B[i,i] = hermitian(B[i,i], sym_uplo(A.uplo))::hermitian_type(eltype(A.data))
end
return B
end
Expand All @@ -252,10 +252,10 @@ Array(A::Union{Symmetric,Hermitian}) = convert(Matrix, A)
parent(A::HermOrSym) = A.data
Symmetric{T,S}(A::Symmetric{T,S}) where {T,S<:AbstractMatrix} = A
Symmetric{T,S}(A::Symmetric) where {T,S<:AbstractMatrix} = Symmetric{T,S}(convert(S,A.data),A.uplo)
AbstractMatrix{T}(A::Symmetric) where {T} = Symmetric(convert(AbstractMatrix{T}, A.data), Symbol(A.uplo))
AbstractMatrix{T}(A::Symmetric) where {T} = Symmetric(convert(AbstractMatrix{T}, A.data), sym_uplo(A.uplo))
Hermitian{T,S}(A::Hermitian{T,S}) where {T,S<:AbstractMatrix} = A
Hermitian{T,S}(A::Hermitian) where {T,S<:AbstractMatrix} = Hermitian{T,S}(convert(S,A.data),A.uplo)
AbstractMatrix{T}(A::Hermitian) where {T} = Hermitian(convert(AbstractMatrix{T}, A.data), Symbol(A.uplo))
AbstractMatrix{T}(A::Hermitian) where {T} = Hermitian(convert(AbstractMatrix{T}, A.data), sym_uplo(A.uplo))

copy(A::Symmetric{T,S}) where {T,S} = (B = copy(A.data); Symmetric{T,typeof(B)}(B,A.uplo))
copy(A::Hermitian{T,S}) where {T,S} = (B = copy(A.data); Hermitian{T,typeof(B)}(B,A.uplo))
Expand Down Expand Up @@ -442,9 +442,9 @@ mul!(C::StridedMatrix{T}, A::StridedMatrix{T}, B::Hermitian{T,<:StridedMatrix})

for T in (:Symmetric, :Hermitian), op in (:*, :/)
# Deal with an ambiguous case
@eval ($op)(A::$T, x::Bool) = ($T)(($op)(A.data, x), Symbol(A.uplo))
@eval ($op)(A::$T, x::Bool) = ($T)(($op)(A.data, x), sym_uplo(A.uplo))
S = T == :Hermitian ? :Real : :Number
@eval ($op)(A::$T, x::$S) = ($T)(($op)(A.data, x), Symbol(A.uplo))
@eval ($op)(A::$T, x::$S) = ($T)(($op)(A.data, x), sym_uplo(A.uplo))
end

function factorize(A::HermOrSym{T}) where T
Expand Down Expand Up @@ -481,8 +481,8 @@ function _inv(A::HermOrSym)
end
B
end
inv(A::Hermitian{<:Any,<:StridedMatrix}) = Hermitian(_inv(A), Symbol(A.uplo))
inv(A::Symmetric{<:Any,<:StridedMatrix}) = Symmetric(_inv(A), Symbol(A.uplo))
inv(A::Hermitian{<:Any,<:StridedMatrix}) = Hermitian(_inv(A), sym_uplo(A.uplo))
inv(A::Symmetric{<:Any,<:StridedMatrix}) = Symmetric(_inv(A), sym_uplo(A.uplo))

eigen!(A::RealHermSymComplexHerm{<:BlasReal,<:StridedMatrix}) = Eigen(LAPACK.syevr!('V', 'A', A.uplo, A.data, 0.0, 0.0, 0, 0, -1.0)...)

Expand Down

0 comments on commit 993e7d7

Please sign in to comment.