# Overloading vectorization?

**URL:** https://discourse.julialang.org/t/overloading-vectorization/49526
**Category:** General Usage
**Created:** [November 3, 2020, 2:19pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526 "2020-11-03T14:19:18Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![bcsj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcsj/32/18526_2.png) [@bcsj](https://discourse.julialang.org/u/bcsj)
#### Post date: [November 3, 2020, 2:19pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/1 "2020-11-03T14:19:18Z")

</div>

So say I have a function, e.g. `f(x,y) = x*y` and two arrays `a=[1,2]; b=[3,4]`, then I can perform `f` element-wise by calling `f.(a,b)`.

But now `f` is a more complicated operation, `f.(a,b)` still works, but say I can write another version of the function `g` such that  
`g(a,b) == f.(a,b)`  
but `g` is much more efficient than the element-wise operation. Can I overload `f.` to perform `g` instead of an element-wise `f`? So a user, not knowing the difference, doesn’t get the bad performance by naively using the `f.` version.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [November 3, 2020, 2:32pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/2 "2020-11-03T14:32:48Z")

</div>

Can you give an example of the type of `f` you are worried won’t vectorize efficiently?

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [November 3, 2020, 2:38pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/3 "2020-11-03T14:38:32Z")

</div>

Vectorisation with `.` is just syntactic sugar for `broadcast(f, args..)`

So you can absolutely override that. But the `broadcast` mechanism is complicated. ~~You would need to dispatch on a specific subset of `broadcast` for the function `f` operating on some specific types~~. Add methods to Base.broadcasted, as @mbauman says below. I’ve never tried that but I guess it’s possible.

There might be other ways to do this too, but you’ll have to learn a bit about `broadcast`.

---

<div class="post-metadata">

### Author: ![bcsj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcsj/32/18526_2.png) [@bcsj](https://discourse.julialang.org/u/bcsj)
#### Post date: [November 3, 2020, 2:40pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/4 "2020-11-03T14:40:04Z")

</div>

Sure, I have a piecewise linear function on a grid of nodes, i.e I know the grid points and the values. Then I want to evaluate this at some arbitrary point in the confines of the grid. To do this I go over the nodes to find the 4 grid points representing the corners of the square and compute the interpolated value as a weighted sum of the nodal values.

Now I have instead a list of say millions of points I want to evaluate in the confines of the grid. I could do the process above for each, but that would make me traverse the grid nodes for each point. It is many many times more efficient to compute the nodes simultaneously for all points which can be done in a single traversal.

---

<div class="post-metadata">

### Author: ![bcsj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcsj/32/18526_2.png) [@bcsj](https://discourse.julialang.org/u/bcsj)
#### Post date: [November 3, 2020, 2:49pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/5 "2020-11-03T14:49:33Z")

</div>

Okay, thanks, I will have to take a look at that.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [November 3, 2020, 2:53pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/6 "2020-11-03T14:53:58Z")

</div>

> [@Raf](#):
>
> Vectorisation with `.` is just syntactic sugar for `broadcast(f, args..)`

That’s not true. It’s a sugar for a much more complicated piece of infrastructure:

```julia
julia> Meta.@lower f.(x, y)
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ %1 = Base.broadcasted(f, x, y)
│ %2 = Base.materialize(%1)
└── return %2
))))

```

You can overload `Base.broadcasted(::typeof(f), x::Vector, y::Vector)`.

This is the mechanism through which, for example, ranges use O(1) arithmetic and recompute new ranges when possible.

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [November 3, 2020, 3:04pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/7 "2020-11-03T15:04:35Z")

</div>

Errr… it’s true in so far as the docs say pretty much what I said:

> A special syntax exists for broadcasting: f.(args…) is equivalent to broadcast(f, args…), and nested f.(g.(args…)) calls are fused into a single  
> broadcast loop.

Which is a useful start for someone who doesn’t know that.

I also mention that `broadcast` is complicated, and that there probably is a better way to do it.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [November 3, 2020, 3:50pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/8 "2020-11-03T15:50:11Z")

</div>

Yeah, there’s a tension between documenting the behavior for calling users and the behavior as you overload it… the documentation there is correct for how `broadcast` works when you call it but it doesn’t translate to how dot-call extension works.

It may seem like splitting hairs, but what you wrote was very different. I’m sorry my message was so short and curt — just wanted to point the way to `broadcasted` rather than `broadcast`.

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [November 3, 2020, 4:29pm UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/9 "2020-11-03T16:29:41Z")

</div>

No problem! It was the wrong method lol. I was just trying to point the way to broadcast in general, as it hadn’t been mentioned… but I can honestly never remember how it works even after implementing it in a well used package 😬

---

<div class="post-metadata">

### Author: ![bcsj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcsj/32/18526_2.png) [@bcsj](https://discourse.julialang.org/u/bcsj)
#### Post date: [November 4, 2020, 8:32am UTC](https://discourse.julialang.org/t/overloading-vectorization/49526/10 "2020-11-04T08:32:42Z")

</div>

As a note for anyone reading this later…

If `f` is a struct of type `S` so that `f(x,y)` is defined as `(s::S)(x,y) = ...` instead of “`::typeof(f)`” in `Base.broadcasted(::typeof(f), ...)` you simply use `s::S` so you can refer back to the object itself as `s` in evaluation.
