Skip to content

ND-conv with mixed offset/non-offset axes #583

@martinholters

Description

@martinholters

We currently have

julia> conv([1 1; 1 1], [1 1; 1 1])
3×3 Matrix{Int64}:
 1  2  1
 2  4  2
 1  2  1

julia> x = OffsetArray([1 1; 1 1], (-1, -1))
2×2 OffsetArray(::Matrix{Int64}, 0:1, 0:1) with eltype Int64 with indices 0:1×0:1:
 1  1
 1  1

julia> conv(x, x)
3×3 OffsetArray(::Matrix{Int64}, 0:2, 0:2) with eltype Int64 with indices 0:2×0:2:
 1  2  1
 2  4  2
 1  2  1

julia> x = OffsetArray([1 1; 1 1])
2×2 OffsetArray(::Matrix{Int64}, 1:2, 1:2) with eltype Int64 with indices 1:2×1:2:
 1  1
 1  1

julia> conv(x, x)
3×3 OffsetArray(::Matrix{Int64}, 2:4, 2:4) with eltype Int64 with indices 2:4×2:4:
 1  2  1
 2  4  2
 1  2  1

Note that the first two cases each make perfect sense on their own but are inconsistent with each other, so that conv([1 1; 1 1], [1 1; 1 1]) != conv(OffsetArray([1 1; 1 1]), OffsetArray([1 1; 1 1])) (due to different axes) as seen by that last case. Despite this inconsistency, this was deemed the least bad behavior we could think of.

The present implementation decides the indexing (with/without offset) individually per axes. For an x such that

axes(x) == (Base.OneTo(2), OffsetArrays.IdOffsetRange(values=0:1, indices=0:1))

we would (theoretically*⁾) get

axes(conv(x,x)) == (Base.OneTo(3), OffsetArrays.IdOffsetRange(values=0:2, indices=0:2))

As far as I know, there is presently no type that supports such heterogeneous axes, so it is hard to say whether this behavior is desirable. Alternatives would be

axes(conv(x,x)) == (OffsetArrays.IdOffsetRange(values=0:2, indices=0:2), OffsetArrays.IdOffsetRange(values=0:2, indices=0:2))

or

axes(conv(x,x)) == (OffsetArrays.IdOffsetRange(values=2:4, indices=2:4), OffsetArrays.IdOffsetRange(values=0:2, indices=0:2))

Without this case even being possible, I find it very hard to decide what the outcome should be. Nevertheless, we should consider what should happen if this becomes possible in the future. I tend to throw an error for now so that we are free to decide later when (and if) such an array type becomes reality.

*) Actually, with conv using similar to generate the output array and

julia> axes(similar(zeros(2,2), (0:2, Base.OneTo(3))))
(OffsetArrays.IdOffsetRange(values=0:2, indices=0:2), OffsetArrays.IdOffsetRange(values=1:3, indices=1:3))

that would be what we actually get, unless the fictitious input array type also comes with appropriate similar methods to produce a matching heterogeneous-axes array here.

Ref. #580 (comment) and the following comments, CC @wheeheee.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions