How to create random values given a restriction?

Hello everyone,

I’m trying to generate three vectors (ωa, ωb, ωc) made up of random numbers.

The only restriction is that: ωa[i] + ωb[i] + ωa[i] ==1

However I am new in the Julia and I don’t know how to do it or if there is a package that does something similar.

This will help me later to create a Markowitz model where I decide the proportions where I will distribute the total of my investment in 3 assets

I hope someone can take a look at it and give me his thoughts!

ωa = ones(n,1)
ωb = ones(n,1)
ωc = ones(n,1)

for i=1:n
    ωa[i] = rand()
    ωb[i] = rand()
    ωc[i] = rand()

return [ωa+ωb+ωc]


use triple ` to denote a code block; "his" => "their"

in general it’s difficult, for example, imagine generating a random Sudoku obeying uniform distribution.

But in your case, I think you can generate a rand(3) and normalize it so that the sum is 1, this should give a uniform distribution. (I think)

julia> a = Matrix{Float64}(undef, 10, 3);

julia> for i in 1:size(a)[1]
           v = rand(3)
           a[i,:] = v / sum(v)

julia> (sum(a, dims=2) .≈ 1) |> all

edit: I realized this the problem is highly dependent on what is the range of your ω s, and what is their distribution, in that regards, use Distributions.jl


Normalization, as suggested by @jling, is probably the simplest approach here, and the easiest to customize by using different univariate distributions.

You can also use a Dirichlet distribution to draw a random value in a simplex:

using Distributions
rand(Dirichlet(3, 2))

Finally, you can also use stick-breaking to transform 2 random values (but the result will not be symmetric unless you apply a correction):

using Random

function rand_simplex(rng, n)
    z = 1.0
    s = Vector{Float64}(undef, n)
    for i in 1:(n-1)
        r = rand(rng, Float64)
        s[i] = z * r
        z *= 1 - r
    s[end] = z

rand_simplex(Random.GLOBAL_RNG, 3)

Thanks you both @jling and @Tamas_Papp for your aproaches, in all cases they were very useful to me, in particular I think I will lean towards the Dirichlet method of the distribution package.