+5  A: 

After a little digging around, I found this page which gives a nice implementation of the Dirichlet Distribution. From there it seems like it would be pretty simple to follow Wikipedia's method 1. This seems like the best way to do it.

As a test:

In[14]:= RandomReal[DirichletDistribution[{1,1}],WorkingPrecision->25]
Out[14]= {0.8428995243540368880268079,0.1571004756459631119731921}
In[15]:= Total[%]
Out[15]= 1.000000000000000000000000

A plot of 100 samples:

alt text

zdav
+3  A: 

I'm with zdav: the Dirichlet distribution seems to be the easiest way ahead, and the algorithm for sampling the Dirichlet distribution which zdav refers to is also presented on the Wikipedia page on the Dirichlet distribution.

Implementationwise, it is a bit of an overhead to do the full Dirichlet distribution first, as all you really need is n random Gamma[1,1] samples. Compare below
Simple implementation

SimplexSample[n_, opts:OptionsPattern[RandomReal]] :=
  (#/Total[#])& @ RandomReal[GammaDistribution[1,1],n,opts]

Full Dirichlet implementation

DirichletDistribution/:Random`DistributionVector[
 DirichletDistribution[alpha_?(VectorQ[#,Positive]&)],n_Integer,prec_?Positive]:=
    Block[{gammas}, gammas = 
        Map[RandomReal[GammaDistribution[#,1],n,WorkingPrecision->prec]&,alpha];
      Transpose[gammas]/Total[gammas]]

SimplexSample2[n_, opts:OptionsPattern[RandomReal]] := 
  (#/Total[#])& @ RandomReal[DirichletDistribution[ConstantArray[1,{n}]],opts]

Timing

Timing[Table[SimplexSample[10,WorkingPrecision-> 20],{10000}];]
Timing[Table[SimplexSample2[10,WorkingPrecision-> 20],{10000}];]
Out[159]= {1.30249,Null}
Out[160]= {3.52216,Null}

So the full Dirichlet is a factor of 3 slower. If you need m>1 samplepoints at a time, you could probably win further by doing (#/Total[#]&)/@RandomReal[GammaDistribution[1,1],{m,n}].

Janus
+5  A: 

Here's a nice concise implementation of the second algorithm from Wikipedia:

SimplexSample[n_] := Rest@# - Most@# &[Sort@Join[{0,1}, RandomReal[{0,1}, n-1]]]

That's adapted from here: http://www.mofeel.net/1164-comp-soft-sys-math-mathematica/14968.aspx (Originally it had Union instead of Sort@Join -- the latter is slightly faster.)

(See comments for some evidence that this is correct!)

dreeves
@dreeves I just ran a test, and it seems to work ok - the values are pretty uniform and all on the right line. I'm not sure why it was downvoted.
zdav
@dreeves: The downvote was mine, and was accidental; I apologise. If you can make a trivial edit to your answer, I'll upvote. This method looks correct to me.
Mark Dickinson
I was just going to post this same method. On my machine it is eight times faster than the method sampling Gamma[1,1].
Timo
Instead of doing `Rest - Most`, you can also just call the built-in `Differences` and that's the same thing.
Ben Alpert
+1  A: 

This code can work:

samples[n_] := Differences[Join[{0}, Sort[RandomReal[Range[0, 1], n - 1]], {1}]]

Basically you just choose n - 1 places on the interval [0,1] to split it up then take the size of each of the pieces using Differences.

A quick run of Timing on this shows that it's a little faster than Janus's first answer.

Ben Alpert
Thanks! I think this is pretty much isomorphic to the one I posted. Thanks for the speed comparison, btw!
dreeves
Oh, indeed it is! Somehow I thought that yours was different, but it looks the same now that I've taken another look.
Ben Alpert