From: Javier Montoya on
Dear all,

I need to generate a vector of random float numbers between [0,1] such
that their sum equals 1 and that are distributed non-uniformly.
Is there any python function that generates such a vector?

Best wishes
From: Etienne Rousee on
Le 12/06/2010 12:05, Javier Montoya a �crit :
> I need to generate a vector of random float numbers between [0,1] such
> that their sum equals 1 and that are distributed non-uniformly.
> Is there any python function that generates such a vector?

Let f any function (injective is better).
Let a1,...,an n numbers uniformly distributed.
Let s the sum of f(a1),...,f(an).

f(a1)/s, ... , f(an)/s is what you want.

You have to choose f to obtain the distribution you prefer.

--

Etienne

From: Steven D'Aprano on
On Sat, 12 Jun 2010 03:05:43 -0700, Javier Montoya wrote:

> Dear all,
>
> I need to generate a vector of random float numbers between [0,1] such
> that their sum equals 1 and that are distributed non-uniformly. Is there
> any python function that generates such a vector?

You haven't explained your requirements in anywhere near enough detail.
Any of these match your description:

[1.0]
[0.0, 0.0, 0.0, 0.0, 1.0]
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.3]
[0.01, 0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.03, 0.03, 0.84]

and many, many more. What do you mean by "non-uniformly"? Do you have any
specific distribution in mind? Do you have to have a particular number of
items?

For instance, you could do this:

L = []
total = 0.0
while total < 1:
x = random.uniform(0, 1-total)
L.append(x)
total += x

assert sum(L) == total == 1.0


--
Steven
From: Javier Montoya on
On Jun 12, 1:08 pm, Etienne Rousee <etie...(a)rousee.org> wrote:
> Le 12/06/2010 12:05, Javier Montoya a écrit :
>
> > I need to generate a vector of random float numbers between [0,1] such
> > that their sum equals 1 and that are distributed non-uniformly.
> > Is there any python function that generates such a vector?
>
> Let f any function (injective is better).
> Let a1,...,an n numbers uniformly distributed.
> Let s the sum of f(a1),...,f(an).
>
> f(a1)/s, ... , f(an)/s is what you want.
>
> You have to choose f to obtain the distribution you prefer.
>
> --
>
> Etienne

Hi Etienne,

Thanks for your suggestion. I ended with following code:
N=5
a=np.random.random_integers(2*N, size=(1.,N))
a=a/float(sum(a))
However, in some cases, the random numbers are even repeated, for
example, I obtained the following sequence:
[0.03846154, 0.03846154, 0.23076923, 0.34615385, 0.34615385]
This is mainly because in random_integers the integers generated might
be repeated.
One solution, would be to set the first parameter in random_integers
to a larger number.
What do you think? Do you suggest any other function instead of
random_integers?

Best wishes

From: Javier Montoya on
On Jun 12, 1:08 pm, Etienne Rousee <etie...(a)rousee.org> wrote:
> Le 12/06/2010 12:05, Javier Montoya a écrit :
>
> > I need to generate a vector of random float numbers between [0,1] such
> > that their sum equals 1 and that are distributed non-uniformly.
> > Is there any python function that generates such a vector?
>
> Let f any function (injective is better).
> Let a1,...,an n numbers uniformly distributed.
> Let s the sum of f(a1),...,f(an).
>
> f(a1)/s, ... , f(an)/s is what you want.
>
> You have to choose f to obtain the distribution you prefer.
>
> --
>
> Etienne

Hi Etienne,

Thanks for your suggestion. I ended with following code:
N=5
a=np.random.random_integers(2*N, size=(1.,N))
a=a/float(sum(a))
However, in some cases, the random numbers are even repeated, for
example, I obtained the following sequence:
[0.03846154, 0.03846154, 0.23076923, 0.34615385, 0.34615385]
This is mainly because in random_integers the integers generated might
be repeated.
One solution, would be to set the first parameter in random_integers
to a larger number.
What do you think? Do you suggest any other function instead of
random_integers?

Best wishes