Reducing sum of OffsetArray

I’m getting an error with sum(B, dims=1), where B is an OffsetArray.

using OffsetArrays
A = rand(3,3)
B = OffsetArray(A, -1:1, 5:7)
sum(A, dims=1)   # OK
sum(B, dims=1)   # errors

Here’s the output:

Julia-1.4.0> sum(A, dims=1)
1×3 Array{Float64,2}:
 1.15857  1.72228  1.86123
Julia-1.4.0> sum(B, dims=1)
ERROR: ArgumentError: No method is implemented for reducing index range of type typeof(i). Please implement
reduced_index for this index type or report this as an issue.

Stacktrace:
 [1] reduced_index(::OffsetArrays.IdOffsetRange{Int64,Base.OneTo{Int64}}) at .\reducedim.jl:8
 [2] reduced_indices(::Tuple{OffsetArrays.IdOffsetRange{Int64,Base.OneTo{Int64}},OffsetArrays.IdOffsetRange{Int64,Base.OneTo{Int64}}}, ::Int64) at .\reducedim.jl:23
 [3] reduced_indices at .\reducedim.jl:15 [inlined]
 [4] reducedim_initarray(::OffsetArray{Float64,2,Array{Float64,2}}, ::Int64, ::Float64, ::Type{Float64}) at .\reducedim.jl:92
 [5] reducedim_initarray at .\reducedim.jl:93 [inlined]
 [6] reducedim_init at .\reducedim.jl:172 [inlined]
 [7] _mapreduce_dim at .\reducedim.jl:317 [inlined]
 [8] #mapreduce#580 at .\reducedim.jl:307 [inlined]
 [9] _sum at .\reducedim.jl:679 [inlined]
 [10] _sum at .\reducedim.jl:678 [inlined]
 [11] #sum#583 at .\reducedim.jl:652 [inlined]
 [12] top-level scope at REPL[5]:1

I’m not really sure what I expected, but perhaps the same as this:

Julia-1.4.0> sum(B[i:i, :] for i in axes(B,1))
1×3 OffsetArray(::Array{Float64,2}, 1:1, 5:7) with eltype Float64 with indices 1:1×5:7:
 1.15857  1.72228  1.86123

This looks like a bug/missing implementation, maybe open an issue? Possible workaround (not tested):

import Base: reduced_index
Base.reduced_index(i::OffsetArrays.IdOffsetRange) = oftype(i, first(i):first(i))
2 Likes

Issue logged here: Reduction over OffsetArray error · Issue #107 · JuliaArrays/OffsetArrays.jl · GitHub
Workaround seems to work for me.
Thanks!

2 Likes