random vector v from uniform distribution at (0,1) with sum(v)=1

18 vues (au cours des 30 derniers jours)
jimaras
jimaras le 14 Mar 2014
Commenté : Benjamin Avants le 15 Mai 2014
Hello,
How can I generate a uniformly distributed random vector with its sum to be equal to 1?
Thank you

Réponse acceptée

John D'Errico
John D'Errico le 14 Mar 2014
Too many people think that generating a uniform sample, then normalizing by the sum will generate a uniform sample. In fact, this is NOT at all true.
A good way to visualize this is to generate that sample for the 2-d case. For example, suppose we do it the wrong way first?
xy = rand(100,2);
plot(xy(:,1),xy(:,2),'.')
Now, lets do the sum projection that virtually everyone poses. (Yes, it is the obvious choice. Now we will see why it is the wrong approach.)
xys = bsxfun(@rdivide,xy,sum(xy,2));
hold on
plot(xys(:,1),xys(:,2),'ro')
axis equal
axis square
The sum-projected points lie along the diagonal line. Note the distribution seems to be biased towards the middle of the line. A uniform sample would have points uniformly distributed along that line.
In a low number of dimensions there are some nice tricks to generate a sample that is indeed uniform. I tend to use Roger Stafford's submission to the file exchange, randfixedsum. It is efficient, and works in any number of dimensions.
figure
xyr = randfixedsum(2,100,1,0,1)';
plot(xyr(:,1),xyr(:,2),'ro')
axis equal
axis square
  17 commentaires
Matt J
Matt J le 15 Mai 2014
Modifié(e) : Matt J le 15 Mai 2014
@Ben,
The shape of spoints, when plotted, is not what is germane to the posted topic. The spoints that you've generated is just one vector drawn randomly from the set S={x| sum(x)=1}. The idea of the post is to draw multiple such vectors from S repeatedly and in a uniformly randomized manner (uniformly over S).
Benjamin Avants
Benjamin Avants le 15 Mai 2014
If that's the case, I concede the point. I had interpreted the post to be asking for a single vector with uniform distribution and a total sum of 1 derived from a uniform distribution with range (0,1). I was assuming @jimaras was simply asking for a way to convert a uniform distribution (perhaps generated using the rand function) into another uniform distribution with a total sum of 1.
Further, @John stated that my approach does not yield a uniformly distributed result. I suppose this is true if you are trying to maintain uniformity in the (0,1) range, but that did not seem to be his argument. Within the new range of the scaled distribution, I believe I have shown that uniformity is maintained.
I rely on shifting and scaling pseudo-random numbers in some of my work and I felt it was important to understand if my methods were in fact impacting the uniformity of those numbers. So far, it does not seem to be the case.
I appreciate you and @John's willingness to discuss this topic at length.

Connectez-vous pour commenter.

Plus de réponses (1)

Benjamin Avants
Benjamin Avants le 14 Mar 2014
You could use rand() to create a uniform distribution then divide each element by the sum.
v = rand(10,1);
vSum = sum(v);
v = v ./ vSum;
  3 commentaires
Benjamin Avants
Benjamin Avants le 13 Mai 2014
John,
Your answer does not explain why my suggestion would not work. Please read my comment on your answer and explain it for me. I would like to understand why this approach is not valid.
John D'Errico
John D'Errico le 14 Mai 2014
Read my answer, which does show that the simple renormalizing scheme fails to yield a uniform result.
A good way to look at it is if you think of projecting the domain from a square region onto a diagonal straight line crossing the square, you can see that the ends of the line will have fewer points that can contribute to those regions.
Your renormalizing scheme is a terribly common mistake I see made. After all, it is simple, and it seems to get the job done at first glance. It is only when you look more carefully at the actual distribution along the line that people should see it is wrong. Wrong here means non-uniform.

Connectez-vous pour commenter.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by