Replies: 7 comments 11 replies
-
I would recommend that the thing being mutated is the first argument. That is: function rand!(x::ArraySlot, rng::AbstractRNG, d::AbstractMeasure) |
Beta Was this translation helpful? Give feedback.
-
Everything else looks good to me! |
Beta Was this translation helpful? Give feedback.
-
Yeah, I'd think so too, first or maybe second. But then there's this: help?> rand!
search: rand! randn rand transcode macroexpand @macroexpand1 @macroexpand CartesianIndex
rand!([rng=GLOBAL_RNG], A, [S=eltype(A)])
Populate the array A with random values. If S is specified (S can be a type or a
collection, cf. rand for details), the values are picked randomly from S. This is
equivalent to copyto!(A, rand(rng, S, size(A))) but without allocating a new array.
Examples
≡≡≡≡≡≡≡≡≡≡
julia> rng = MersenneTwister(1234);
julia> rand!(rng, zeros(5))
5-element Vector{Float64}:
0.5908446386657102
0.7667970365022592
0.5662374165061859
0.4600853424625171
0.7940257103317943
───────────────────────────────────────────────────────────────────────────────────────────
rand!([rng::AbstractRNG,] s::Sampleable, A::AbstractArray)
Generate one or multiple samples from s to a pre-allocated array A. A should be in the form
as specified above. The rules are summarized as below:
• When s is univariate, A can be an array of arbitrary shape. Each element of A will be
overriden by one sample.
• When s is multivariate, A can be a vector to store one sample, or a matrix with each
column for a sample.
• When s is matrix-variate, A can be a matrix to store one sample, or an array of
matrices with each element for a sample matrix.
───────────────────────────────────────────────────────────────────────────────────────────
rand!(rng::AbstractRNG, ::UnivariateDistribution, ::AbstractArray)
Sample a univariate distribution and store the results in the provided array.
───────────────────────────────────────────────────────────────────────────────────────────
rand!([rng::AbstractRNG,] d::MultivariateDistribution, x::AbstractArray)
Draw samples and output them to a pre-allocated array x. Here, x can be either a vector of
length dim(d) or a matrix with dim(d) rows.
───────────────────────────────────────────────────────────────────────────────────────────
rand!(::AbstractRNG, ::Sampleable, ::AbstractArray)
Samples in-place from the sampler and stores the result in the provided array.
───────────────────────────────────────────────────────────────────────────────────────────
rand!(d::Union{UnivariateMixture, MultivariateMixture}, r::AbstactArray)
Draw multiple samples from d and write them to r. |
Beta Was this translation helpful? Give feedback.
-
Huh. Good catch. We should be consistent with what other people have done previously. |
Beta Was this translation helpful? Give feedback.
-
@DilumAluthge Do you know of any work for a nice interface to avoid allocation, like this is trying to do? I'd think that comes up a lot. |
Beta Was this translation helpful? Give feedback.
-
Yes rng usually goes first because it's the mutated argument for all |
Beta Was this translation helpful? Give feedback.
-
@matbesancon What do you think of this approach?
So for any new distribution, you only define the latter |
Beta Was this translation helpful? Give feedback.
-
rand
methods often look like this:That's great for univariate distributions. But if
sampletype(d) <: Array
, there's going to have to be allocation. Ok fine, so maybe we have aRandom.rand!
method, andrand
calls that for array types. So for example,Now, say we have a distribution that's built from other distributions, which may themselves be built from other distributions, etc, and we want to draw a sample and insert it into an array without doing any allocations. One way to do this that seems natural to me is to make only
rand!
calls, and specify where each piece goes. Ideally, we can have things set up to be able to make a guarantee thatrand!
never allocates.But this gets tricky. What if a
sampletype
along the way is immutable, say aFloat64
or maybe aTuple{Int, Char}
? We can still haverand!
put things into an array, but now we need a way to say where to put them.We can't just pass things like
x[2,3]
as a destination forrand!
, because it will be eagerly expanded beforerand!
is called.I'm thinking we could have something like
Then
What do you think?
Beta Was this translation helpful? Give feedback.
All reactions