# Execute a matrix of functions

**URL:** <https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440>\
**Category:** General Usage\
**Created:** [May 7, 2023, 3:31pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440 "2023-05-07T15:31:19Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 3:31pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/1 "2023-05-07T15:31:19Z")

</div>

I have defined a 3x3 matrix of functions (all `cos(t)`) as follows:

```julia
vij = SizedMatrix{3,3}([t->cos(t) for i in 1:3 for j in 1:3])

```

I’d like to execute the matrix for a particular value of `t`, say `t=2.`:

```julia
values = [vij[i,j](2.) for i in 1:3 for j in 1:3]

```

This works.

Is there a more idiomatic way to generate this matrix of values, for example something like:

```julia
vij(3.)

```

which I know does not work. I can obviously write a function to do this, but I am wondering if such an approach already exists in the Julia language.

Thanks!

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [May 7, 2023, 3:46pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/2 "2023-05-07T15:46:46Z")

</div>

It can be discussed how idiomatic it is, but this is one way to do it:

```julia
julia> vij = [t->cos(t) for i in 1:3, j in 1:3]
3×3 Matrix{var"#14#16"}:
 #14 #14 #14
 #14 #14 #14
 #14 #14 #14

julia> 3 .|> vij
3×3 Matrix{Float64}:
 -0.989992 -0.989992 -0.989992
 -0.989992 -0.989992 -0.989992
 -0.989992 -0.989992 -0.989992

```

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 4:09pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/3 "2023-05-07T16:09:30Z")

</div>

Cool! I like your solution. I like the pipe operator. I wonder if it is possible without pipes. I had tried, but did not succeed. Thanks!

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [May 7, 2023, 4:38pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/4 "2023-05-07T16:38:26Z")

</div>

Not as pretty as the pipe operator, but one could also do

```julia
map(f->f(3.0), vij)

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [May 7, 2023, 4:49pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/5 "2023-05-07T16:49:19Z")

</div>

> [@GunnarFarneback](#):
>
> `vij = [t->cos(t) for i in 1:3, j in 1:3]`

can be simplified to just

```julia
vij = [cos for i in 1:3, j in 1:3]

```

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 4:49pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/6 "2023-05-07T16:49:20Z")

</div>

Timings with `@time`:

Pipe operator: 0.00003 sec

```julia
@time 3. .|> vij;

```

`map` operator: 0.012

```julia
@time map(3., f -> f(3.))

```

Speed ratio: 400x

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 4:50pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/7 "2023-05-07T16:50:16Z")

</div>

> [@jling](#):
>
> `vij = [cos for i in 1:3, j in 1:3]`

The solution should use `vij`.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [May 7, 2023, 4:50pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/8 "2023-05-07T16:50:56Z")

</div>

> [@erlebach](#):
>
> `vij = SizedMatrix{3,3}([t->cos(t) for i in 1:3 for j in 1:3])`

I’m saying how you get `vij` can be simplified

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [May 7, 2023, 4:59pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/9 "2023-05-07T16:59:47Z")

</div>

I think it’s a timing artefact, both should be equally fast. (But the pipe is in my opinion the nicer solution anyway 😃 )

```julia
using BenchmarkTools
@btime 3.0 .|> $vij; # 23.394 ns (1 allocation: 128 bytes)
@btime map(f -> f(3.0), $vij); # 23.092 ns (1 allocation: 128 bytes)

```

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 5:22pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/10 "2023-05-07T17:22:10Z")

</div>

Thanks. The use of `$vij` makes a big difference. I had not considered that.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [May 7, 2023, 5:26pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/11 "2023-05-07T17:26:17Z")

</div>

> [@erlebach](#):
>
> So one should take the variance into account

The variance usually comes from other processes going on in your system unrelated to the thing you want to measure. That’s why BenchmarkTools reports the minimum time.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 5:31pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/12 "2023-05-07T17:31:16Z")

</div>

```julia
@time 3 .|> vij;
  0.000017 seconds (4 allocations: 208 bytes)

```

even if I execute the command multiple times.  
How is it that `@btime` gives a single allocation?

```julia
@btime 3. .|> vij;
  374.595 ns (4 allocations: 208 bytes)

```

```julia
@btime map(f->f(3.), vij);
  121.870 ns (3 allocations: 160 bytes)

```

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [May 7, 2023, 5:31pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/13 "2023-05-07T17:31:35Z")

</div>

The distributions of the timing (e.g. output of `@benchmark` including the mean and median times per call) are essentially identical for both cases, so, it’s not just the minimal time which is the same. (Anyway, not so important. I don’t want to distract the main discussion.)

* * *

To reply to the last post. There is the interpolation `$` used. The problem with timing is that one often calls in the global scope which introduces extra complications. (See [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/#Measure-performance-with-%5B@time%5D(@ref)-and-pay-attention-to-memory-allocation) ) With the `$` one can inject basically some variable from the global scope such that they behave like local scope variables. That is closer to the setting one usually has when a line of code appears inside a function call.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 5:33pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/14 "2023-05-07T17:33:57Z")

</div>

For comparison:

```julia
@btime [$vij[i,j](3.) for i in 1:3, j in 1:3]

```

I learned a lot from all your answers. I simply do not use Julia enough to permanently change my way of thinking. Thanks!

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [May 7, 2023, 6:35pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/15 "2023-05-07T18:35:22Z")

</div>

Maybe I missed it, but has:

```julia
julia> [f(3.0) for f in vij]
3×3 Matrix{Float64}:
 -0.989992 -0.989992 -0.989992
 -0.989992 -0.989992 -0.989992
 -0.989992 -0.989992 -0.989992

```

been suggested?  
Except for performance, the clarity of the code should always be judged in code sections known not to be time critical.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 6:59pm UTC](https://discourse.julialang.org/t/execute-a-matrix-of-functions/98440/16 "2023-05-07T18:59:45Z")

</div>

I love this solution because it is the same regardless of the matrix structure!  
Efficiency is the same as the other solutions.

```julia
@btime [f(3.0) for f in $vij]
  21.480 ns (1 allocation: 128 bytes)

```

Thank you.
