I want to simulate a process with 3 discrete outcomes. Let’s say they have probabilities .2, .3 and .5 and I want to run nSim = 10 simulations, each of which is a series of nDraw = 5 draws from the discrete distribution:
using Distributions
d = Multinomial(1,[.2;.3;.5])
M = rand(d, 5, 10)
I get an nDraw x nSim matrix, each element of which is a 3-vector with 2 zeros and 1 one in the slot to show which of the 3 outcomes occurred for the particular draw. Here’s an example:
5×10 Matrix{Vector{Int64}}:
[1, 0, 0] [0, 0, 1] [0, 0, 1] [0, 0, 1] [0, 1, 0] [1, 0, 0] [0, 0, 1] [0, 1, 0] [0, 0, 1] [0, 0, 1]
[0, 0, 1] [0, 1, 0] [0, 0, 1] [0, 0, 1] [0, 0, 1] [0, 0, 1] [0, 1, 0] [0, 1, 0] [0, 0, 1] [0, 0, 1]
[0, 1, 0] [0, 1, 0] [0, 1, 0] [0, 0, 1] [0, 1, 0] [0, 1, 0] [0, 0, 1] [1, 0, 0] [0, 0, 1] [0, 1, 0]
[1, 0, 0] [0, 0, 1] [0, 1, 0] [0, 0, 1] [0, 1, 0] [0, 0, 1] [0, 0, 1] [0, 0, 1] [1, 0, 0] [1, 0, 0]
[0, 1, 0] [1, 0, 0] [0, 0, 1] [0, 1, 0] [0, 1, 0] [0, 1, 0] [0, 1, 0] [0, 0, 1] [0, 0, 1] [0, 1, 0]
Anyway, all of this is just to say that, because I’m using Distributions.Multinomial and want to create all the sims at once, I’m stuck with a matrix of vectors…
THE QUESTION (finally): Why can’t I say something like a[1,:] .= [0, 1, 0]
to assign that 3 vector to all the elements in the first row of M? When I do so I get:
ERROR: DimensionMismatch: array could not be broadcast to match destination
Stacktrace:
[1] check_broadcast_shape
@ ./broadcast.jl:540 [inlined]
[2] check_broadcast_axes
@ ./broadcast.jl:543 [inlined]
[3] instantiate
@ ./broadcast.jl:284 [inlined]
[4] materialize!
@ ./broadcast.jl:871 [inlined]
[5] materialize!(dest::SubArray{Vector{Int64}, 1, Matrix{Vector{Int64}}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}, bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(identity), Tuple{Vector{Int64}}})
@ Base.Broadcast ./broadcast.jl:868
[6] top-level scope
@ REPL[159]:1
This is weird to me. I know I can do the assignment by looping but I like broadcasting and also want to understand what I’m doing wrong here…
EDIT: The moral of the story is “Think before you type” :<
I should have written the assignment as a[1,:] .= Ref([0, 1, 0]).
In honor of the world cup: Screwed by the Refs once again…