# How to broadcast over only certain function arguments?

**URL:** <https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274>\
**Category:** General Usage\
**Tags:** question, broadcast\
**Created:** [January 4, 2019, 4:09pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274 "2019-01-04T16:09:58Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![ronubi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronubi/32/4085_2.png) [@ronubi](https://discourse.julialang.org/u/ronubi)\
**Post date:** [January 4, 2019, 4:09pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/1 "2019-01-04T16:09:58Z")

</div>

I have a function that takes fixed input arrays and variable scalars to produce a scalar return value. I would like to use the broadcast capability of Julia to turn the variable scalars into arrays, and have it return an array of the same size. Is there a straightforward way to get the broadcast syntax `f.()` to interpret the input arguments correctly (not attempting to broadcast over the fixed arrays)? Or is there some other clever way using `map` or `broadcast`?

For now, I will initialize the return array and just use a `for` loop.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 4, 2019, 4:27pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/2 "2019-01-04T16:27:03Z")

</div>

You can turn one of the arguments into a tuple to consider it as a scalar:

For example (if I understood your question correctly):

```julia
f(x,y) = sum(x) + y
f([1,2,3], 4) #-> 10
f([1,2,3], 5) #-> 11

f.([1,2,3], [4,5]) # -> error

f.(([1,2,3],), [4,5]) # -> [10, 11]
                      # this works because ([1,2,3],) is now considered
                      # to be scalar and is broadcasted

```

Note how in the second case, the array argument `[1,2,3]` has been turned into a 1-element tuple containing the actual array argument: `([1,2,3],)`

It would also have been possible to use `Ref([1,2,3])` to achieve the same effect:

```julia
f.(Ref([1,2,3]), [4,5]) #-> [10, 11]

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 4, 2019, 4:39pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/3 "2019-01-04T16:39:10Z")

</div>

Also see this (ongoing) discussion:

> [@recent broadcast changes (iterate by default), scalar struct, and \`@.\`](https://discourse.julialang.org/t/recent-broadcast-changes-iterate-by-default-scalar-struct-and/11178):
>
> The current broadcasting behavior is non-intuitive when used with @. Julia Version 0.7.0-DEV.5222, Commit 7144b6b816 (2018-05-25 20:23 UTC) This is a minimal example, stripped down from a real use case. struct Material a::Float64 end chi(m::Material, energy) = m.a / energy m1 = Material(1.0) energy = 1.5:0.5:2.5 chi1 = @. chi(m1, energy) ┌ Warning: broadcast will default to iterating over its arguments in the future. Wrap arguments of │ type `x::Material` with `Ref(x)` to ensure they b…

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 4, 2019, 4:57pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/4 "2019-01-04T16:57:29Z")

</div>

> [@ffevotte](#):
>
> You can turn one of the arguments into a tuple to consider it as a scalar:

Wrapping an argument in `Ref(x)` also works and is a common idiom for this.

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [January 4, 2019, 8:54pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/5 "2019-01-04T20:54:41Z")

</div>

If you want to override the broadcasting behaviour for a particular function, it’s possible by adding a new method to the broadcasted function. However, I’m not sure it’s a particularly advisable thing to do since your function will behave differently to most other functions.

```julia
julia> _f(x,y) = sum(x) + y
_f (generic function with 1 method)

julia> f(x, y) = _f(x,y)
f (generic function with 1 method)

julia> Broadcast.broadcasted(::typeof(f), x, y) = broadcast(_f, Ref(x), y)

julia> f.([1,2,3], [4,5])
2-element Array{Int64,1}:
 10
 11

```

---

<div class="post-metadata">

**Author:** ![ronubi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronubi/32/4085_2.png) [@ronubi](https://discourse.julialang.org/u/ronubi)\
**Post date:** [January 5, 2019, 5:13am UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/6 "2019-01-05T05:13:27Z")

</div>

The tuple-wrapping trick seems to work with Julia v0.7. I didn’t have success with the `Ref()` trick - will need to experiment further.

Thanks!

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 5, 2019, 9:58am UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/7 "2019-01-05T09:58:10Z")

</div>

> [@ronubi](#):
>
> I didn’t have success with the `Ref()` trick - will need to experiment further.

It is not a “trick”, but part of the [semantics of broadcasting](https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting-1). If it does not work, that is a bug, so please provide a self-contained MWE that demonstrates this.

---

<div class="post-metadata">

**Author:** ![compleat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compleat/32/8958_2.png) [@compleat](https://discourse.julialang.org/u/compleat)\
**Post date:** [February 27, 2022, 1:23pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/8 "2022-02-27T13:23:26Z")

</div>

This doesn’t seem to work, as of Julia 1.7. Has it been replaced/deprecated?

---

<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:** [February 27, 2022, 2:37pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/9 "2022-02-27T14:37:18Z")

</div>

It should work. Can you provide a minimal example?

---

<div class="post-metadata">

**Author:** ![compleat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compleat/32/8958_2.png) [@compleat](https://discourse.julialang.org/u/compleat)\
**Post date:** [February 27, 2022, 2:40pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/10 "2022-02-27T14:40:05Z")

</div>

```julia
f(x,y)=2*x+3*y

```

then

```julia
julia> f.(([1,2]),[3,4,5])
ERROR: DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths 2 and 3")
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(f), Tuple{Vector{Int64}, Vector{Int64}}})
   @ Base.Broadcast ./broadcast.jl:860
 [7] top-level scope
   @ REPL[32]:1
 [8] top-level scope
   @ ~/.julia/packages/CUDA/0IDh2/src/initialization.jl:52

```

---

<div class="post-metadata">

**Author:** ![compleat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compleat/32/8958_2.png) [@compleat](https://discourse.julialang.org/u/compleat)\
**Post date:** [February 27, 2022, 2:43pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/12 "2022-02-27T14:43:24Z")

</div>

Hi Sorry - I tried Ref() again and it worked  
[sorry - I thought I had tried it before, but something must have been different]

---

<div class="post-metadata">

**Author:** ![compleat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compleat/32/8958_2.png) [@compleat](https://discourse.julialang.org/u/compleat)\
**Post date:** [February 27, 2022, 2:44pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/14 "2022-02-27T14:44:52Z")

</div>

Thanks

---

<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:** [February 27, 2022, 2:44pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/15 "2022-02-27T14:44:53Z")

</div>

Ah, OK.

---

<div class="post-metadata">

**Author:** ![compleat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compleat/32/8958_2.png) [@compleat](https://discourse.julialang.org/u/compleat)\
**Post date:** [February 27, 2022, 2:55pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/16 "2022-02-27T14:55:07Z")

</div>

It’s Ref(1,2) that doesn’t work here, which had confused me.

---

<div class="post-metadata">

**Author:** ![ronubi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronubi/32/4085_2.png) [@ronubi](https://discourse.julialang.org/u/ronubi)\
**Post date:** [March 1, 2022, 4:49pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/17 "2022-03-01T16:49:12Z")

</div>

@compleat - You missed a trailing comma in your first argument above:

```julia
julia> ([1,2])
2-element Vector{Int64}:
 1
 2

julia> ([1,2],)
([1, 2],)

julia> typeof(ans)
Tuple{Vector{Int64}}

```

Surrounding an item with parentheses doesn’t make it a tuple.

---

<div class="post-metadata">

**Author:** ![compleat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compleat/32/8958_2.png) [@compleat](https://discourse.julialang.org/u/compleat)\
**Post date:** [March 1, 2022, 5:13pm UTC](https://discourse.julialang.org/t/how-to-broadcast-over-only-certain-function-arguments/19274/18 "2022-03-01T17:13:42Z")

</div>

Hi, thanks so much. [How did I miss that? I never knew]
