# How to efficiently generate a distribution for every element in matrix

**URL:** <https://discourse.julialang.org/t/how-to-efficiently-generate-a-distribution-for-every-element-in-matrix/118695>\
**Category:** Statistics\
**Created:** [August 28, 2024, 6:37am UTC](https://discourse.julialang.org/t/how-to-efficiently-generate-a-distribution-for-every-element-in-matrix/118695 "2024-08-28T06:37:03Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ZC\_H](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zc_h/32/207967_2.png) [@ZC\_H](https://discourse.julialang.org/u/ZC_H)\
**Post date:** [August 28, 2024, 6:37am UTC](https://discourse.julialang.org/t/how-to-efficiently-generate-a-distribution-for-every-element-in-matrix/118695/1 "2024-08-28T06:37:03Z")

</div>

for example, I have two matrix which separately represent mu and std:

```julia
mu = [1.0 2.0; 3.0 4.0]
std = [0.1 0.2; 0.3 0.4]

```

I want to generate a matrix Normal Distribution like this:

```julia
dist = [Normal(1.0, 0.1) Normal(2.0, 0.2); Normal(3.0, 0.3) Normal(4.0, 0.4)]

```

Unfortunately, Distributions.jl does not support directly using matrix to generate this distribution, so the only method I can figure out to solve this is like bellow:

```julia
mu = [1.0 2.0; 3.0 4.0]
std = [0.1 0.2; 0.3 0.4]
dist = [Normal(mu[i, j], std[i, j]) for i in 1:size(mu, 1), j in 1:size(mu, 2)]

```

but I think this can be very low efficiency. because the matrix I need to deal with may be very big. so how can I improve the efficiency? 😭

---

<div class="post-metadata">

**Author:** ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)\
**Post date:** [August 28, 2024, 7:20am UTC](https://discourse.julialang.org/t/how-to-efficiently-generate-a-distribution-for-every-element-in-matrix/118695/2 "2024-08-28T07:20:33Z")

</div>

If you want to shorten the expression, you can use [broadcasting](https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting), but I think the performance is the almost the same between your list comprehension and the broadcast:

```julia
using Distributions
using BenchmarkTools

mu = [1.0 2.0; 3.0 4.0]
sigma = [0.1 0.2; 0.3 0.4]

make_dist(mu, sigma) = dist = [Normal(mu[i, j], sigma[i, j]) for i in 1:size(mu, 1), j in 1:size(mu, 2)]

@btime make_dist($mu, $sigma)
# 38.013 ns (1 allocation: 128 bytes)

@btime Normal.($mu, $sigma)
# 32.173 ns (1 allocation: 128 bytes)

```

Note: If you want to sample a matrix with the corresponding random entries later, you can also broadcast `rand.(dist)`, otherwise, you will pick the _element_ of the matrix of distributions randomly.

PS: For larger matrices, the broadcast version seems to be consistently a bit faster than the array comprehension.

---

<div class="post-metadata">

**Author:** ![ZC\_H](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zc_h/32/207967_2.png) [@ZC\_H](https://discourse.julialang.org/u/ZC_H)\
**Post date:** [August 28, 2024, 7:23am UTC](https://discourse.julialang.org/t/how-to-efficiently-generate-a-distribution-for-every-element-in-matrix/118695/3 "2024-08-28T07:23:21Z")

</div>

Oh, thank you very much. I don’t know “.” can even work here, thanks!
