# How make .+ work with A::Vector{Float64} and B::OffsetArray(::Vector{Float64}, 0:1)

**URL:** <https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524>\
**Category:** General Usage\
**Created:** [January 4, 2023, 8:13pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524 "2023-01-04T20:13:56Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![elvispy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elvispy/32/45602_2.png) [@elvispy](https://discourse.julialang.org/u/elvispy)\
**Post date:** [January 4, 2023, 8:13pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524/1 "2023-01-04T20:13:57Z")

</div>

The LegendrePolynomials.jl package has a function collectPl which returns an [OffsetArray](https://juliaarrays.github.io/OffsetArrays.jl/stable/) Object.

It appears that, for some reason, the dot operations are not working properly with this type of data:

```julia
julia> A = [1.0, 2.0];
julia> B = collectPl(0.1, lmax = 1) # Just two arrays of the same size

julia> A .+ B
ERROR: DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths 2 and 2")

```

I was able to dispatch another method for the broadcast operator when the second input has the desired data type:

```julia
function broadcast(f::Any, amplitudes::Vector{Float64}, A::T) where T <: OffsetArrays.OffsetArray 
    result = fill(0.0, length(amplitudes));
    for (ii, jj) in zip(eachindex(amplitudes), eachindex(A))
        result[ii] = f(amplitudes[ii], A[jj]); 
    end

    return result
end

```

But the same error appears, probably because .+ is calling the usual broadcast function.

If, however, I try to dispatch another method for .+, Julia complaints that this is not a valid function name.

```julia
julia> .+(amplitudes::Vector{Floag64}, A::T) where T <: OffsetArrays.OffsetArray = broadcast(+, amplitudes, A)
syntax: invalid function name ".+" around ...

```

How can I implement in not that many lines of code the two dot operations that I’m interested in? (+ and \*)

---

<div class="post-metadata">

**Author:** ![aramirezreyes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aramirezreyes/32/42573_2.png) [@aramirezreyes](https://discourse.julialang.org/u/aramirezreyes)\
**Post date:** [January 4, 2023, 9:21pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524/2 "2023-01-04T21:21:11Z")

</div>

Hey elvispy! Welcome to the julia discourse.

**Summary**  
For your use-case you should just use:

```julia
julia> A .+ (B.parent)
2-element Vector{Float64}:
 2.0
 2.1

```

**Reasoning**  
Let me speculate.

I would think that the reason this is not working is that one of the arrays is an `OffsetArray` with indices 0 and 1. So if you interpret the broadcasted addition `.+` as an “element-wise addition” you would like to add `A[i] + B[i]` for all the indices in A in B. But in this case A has indices `0` and `1` and B has indices `1` and `2`. So even though they have the same number of elements they don’t “match”. I agree that the error message is not very useful in this case, but making it work by force in general could be a foot gun.

If you are sure that the operation you want to do is the element-wise addition disregarding the fact that both vectors have different indices you could acces the underlying array of B, which you can do with `B.parent`:

```julia
julia> using LegendrePolynomials

julia> A = [1.0, 2.0];

julia> B = collectPl(0.1, lmax = 1) # Just two arrays of the same size
2-element OffsetArray(::Vector{Float64}, 0:1) with eltype Float64 with indices 0:1:
 1.0
 0.1

julia> A
2-element Vector{Float64}:
 1.0
 2.0

julia> A .+ B
ERROR: DimensionMismatch: arrays could not be broadcast to a common size; got a dimension with lengths 2 and 2
Stacktrace:
 [1] _bcs1
   @ ./broadcast.jl:516 [inlined]
 [2] _bcs
   @ ./broadcast.jl:510 [inlined]
 [3] broadcast_shape
   @ ./broadcast.jl:504 [inlined]
 [4] combine_axes
   @ ./broadcast.jl:499 [inlined]
 [5] instantiate
   @ ./broadcast.jl:281 [inlined]
 [6] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(+), Tuple{Vector{Float64}, OffsetArrays.OffsetVector{Float64, Vector{Float64}}}})
   @ Base.Broadcast ./broadcast.jl:860
 [7] top-level scope
   @ REPL[8]:1

julia> A .+ B.parent
2-element Vector{Float64}:
 2.0
 2.1

```

The problem then is not that broadcasting does not work for OffsetArrays. For example if we re-wrap the contents of B in an `OffsetArray` with indices 1:2 (the same indices as in A) things work as you would expect.

```julia
# Code continues from previous snippet
julia> using OffsetArrays

julia> C = OffsetArray(B.parent, 1:2)
2-element OffsetArray(::Vector{Float64}, 1:2) with eltype Float64 with indices 1:2:
 1.0
 0.1

julia> A .+ C
2-element OffsetArray(::Vector{Float64}, 1:2) with eltype Float64 with indices 1:2:
 2.0
 2.1

```

This discussion seems to be related: [Check that axes start with 1 for AbstractRange operations by timholy · Pull Request #30950 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/30950)

---

<div class="post-metadata">

**Author:** ![elvispy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elvispy/32/45602_2.png) [@elvispy](https://discourse.julialang.org/u/elvispy)\
**Post date:** [January 4, 2023, 9:58pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524/3 "2023-01-04T21:58:01Z")

</div>

Thank you! This solution is really practical to me.

On another note, could you tell me why the following code works

```julia
julia> collectPl.(0.1, lmax = 1).parent .* collectPl.(0.1, lmax = 1).parent
2-element Vector{Float64}:
 1.0
 0.01

```

but not

```julia
julia> LegendrePolys(x::Float64; lmax::Integer) = (collectPl(x, lmax = lmax)).parent
julia> @. LegendrePolys(0.1, lmax = 1) * LegendrePolys(0.1, lmax=1)
MethodError: no method matching *(::Vector{Float64}, ::Vector{Float64})

```

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [January 4, 2023, 10:13pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524/4 "2023-01-04T22:13:01Z")

</div>

or use parent function instead of field access:  
`A .+ parent(B)`

---

<div class="post-metadata">

**Author:** ![aramirezreyes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aramirezreyes/32/42573_2.png) [@aramirezreyes](https://discourse.julialang.org/u/aramirezreyes)\
**Post date:** [January 4, 2023, 10:20pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524/5 "2023-01-04T22:20:36Z")

</div>

Weird! I would expect that to work! Let’s see if someone else can answer this one!

---

<div class="post-metadata">

**Author:** ![aramirezreyes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aramirezreyes/32/42573_2.png) [@aramirezreyes](https://discourse.julialang.org/u/aramirezreyes)\
**Post date:** [January 4, 2023, 10:34pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524/6 "2023-01-04T22:34:05Z")

</div>

@kristoffer.carlsson shared this two discussions on Slack about why such a thing does not work:

[Broadcasted rand.(::Int64), similar to rand(::Int64), but errs with .\< · Issue #32338 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/32338) and  
[Cannot broadcast when rand(n) is involved · Issue #32744 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/32744)

Basically `@. LegendrePolys(0.1, lmax = 1) * LegendrePolys(0.1, lmax=1)` transforms to ` LegendrePolys.(0.1, lmax = 1) .* LegendrePolys.(0.1, lmax=1)` (see the dots also between LegendrePolys and their arguments).

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 4, 2023, 10:45pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524/7 "2023-01-04T22:45:09Z")

</div>

Indeed, accessing internal fields is not generally recommended. There is also `OffsetArrays.no_offset_view`, not sure which is better suited between this and the `parent` function.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [January 4, 2023, 10:48pm UTC](https://discourse.julialang.org/t/how-make-work-with-a-vector-float64-and-b-offsetarray-vector-float64-0-1/92524/8 "2023-01-04T22:48:46Z")

</div>

And noting that the following will avoid problem with `@.` macro:  
`LegendrePolys(0.1, lmax=1) .* LegendrePolys(0.1, lmax=1)`
