Skip to content

Error in LinearAlgebra.copy_oftype on addition of symmetric KeyedArray and UniformScaling #133

@mjp98

Description

@mjp98

In Julia 1.8.2

julia> using AxisKeys, LinearAlgebra

julia> A = Symmetric(rand(2,2))
2×2 Symmetric{Float64, Matrix{Float64}}:
 0.358751  0.612696
 0.612696  0.236462

julia> K = KeyedArray(A, ([:a,:b], [:c, :d]))
2-dimensional KeyedArray(...) with keys:
   2-element Vector{Symbol}
   2-element Vector{Symbol}
And data, 2×2 Symmetric{Float64, Matrix{Float64}}:
        (:c)       (:d)
  (:a)   0.358751   0.612696
  (:b)   0.612696   0.236462

julia> K + I
ERROR: ArgumentError: Cannot set a non-diagonal index in a symmetric matrix
Stacktrace:
 [1] setindex!
   @ /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:227 [inlined]
 [2] setindex!
   @ ~/.julia/dev/AxisKeys.jl/src/struct.jl:132 [inlined]
 [3] copyto_unaliased!(deststyle::IndexCartesian, dest::KeyedArray{Float64, 2, Symmetric{Float64, Matrix{Float64}}, Tuple{Vector{Symbol}, Vector{Symbol}}}, srcstyle::IndexCartesian, src::KeyedArray{Float64, 2, Symmetric{Float64, Matrix{Float64}}, Tuple{Vector{Symbol}, Vector{Symbol}}})
   @ Base ./abstractarray.jl:1052
 [4] copyto!
   @ ./abstractarray.jl:1018 [inlined]
 [5] copy_oftype(A::KeyedArray{Float64, 2, Symmetric{Float64, Matrix{Float64}}, Tuple{Vector{Symbol}, Vector{Symbol}}}, #unused#::Type{Float64})
   @ LinearAlgebra /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/LinearAlgebra/src/LinearAlgebra.jl:377
 [6] +(A::KeyedArray{Float64, 2, Symmetric{Float64, Matrix{Float64}}, Tuple{Vector{Symbol}, Vector{Symbol}}}, J::UniformScaling{Bool})
   @ LinearAlgebra /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:216
 [7] top-level scope
   @ REPL[15]:1

It seems like LinearAlgebra.copyto_oftype should be extended for KeyedArray, deferring to LinearAlgebra.copyto_oftype for the underlying data. e.g. this seems to be sufficient

function LinearAlgebra.copy_oftype(A::KeyedArray, ::Type{T}) where {T}
    return KeyedArray(LinearAlgebra.copy_oftype(A.data, T), axiskeys(A))
end

julia> K + I
2-dimensional KeyedArray(...) with keys:
   2-element Vector{Symbol}
   2-element Vector{Symbol}
And data, 2×2 Symmetric{Float64, Matrix{Float64}}:
        (:c)       (:d)
  (:a)   1.35875    0.612696
  (:b)   0.612696   1.23646

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions