mcabbott / mcabbott/AxisKeys.jl

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

Open
#133 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Julia
Stars
154
Forks
31
PR merge metrics
No merged PRs in 30d

Description

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with the Julia session in the issue, then inspect src/struct.jl around the KeyedArray setindex! implementation and LinearAlgebra.copy_oftype. The fix should let copying a KeyedArray defer to its underlying symmetric data while preserving axis keys; verify that K + I succeeds and retains the shown keys and values.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
data
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.