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

조회 수: 11 (최근 30일)
jimaras
jimaras 2014년 3월 14일
댓글: Benjamin Avants 2014년 5월 15일
Hello,
How can I generate a uniformly distributed random vector with its sum to be equal to 1?
Thank you

채택된 답변

John D'Errico
John D'Errico 2014년 3월 14일
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
Matt J
Matt J 2014년 5월 15일
편집: Matt J 2014년 5월 15일
@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 2014년 5월 15일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Benjamin Avants
Benjamin Avants 2014년 3월 14일
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
Benjamin Avants
Benjamin Avants 2014년 5월 13일
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 2014년 5월 14일
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.

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

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

Start Hunting!

Translated by