Я с zdav: распределение Dirichlet кажется наиболее простым, а алгоритм выборки распределения Dirichlet, на который ссылается zdav, также представлен на странице Википедии в Dirichlet .
С точки зрения реализации, сначала стоит выполнить полный дистрибутив Дирихле, так как все, что вам действительно нужно, это n
случайных Gamma[1,1]
выборок.Сравните ниже
Простая реализация
SimplexSample[n_, opts:OptionsPattern[RandomReal]] :=
(#/Total[#])& @ RandomReal[GammaDistribution[1,1],n,opts]
Полная реализация Дирихле
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[Table[SimplexSample[10,WorkingPrecision-> 20],{10000}];]
Timing[Table[SimplexSample2[10,WorkingPrecision-> 20],{10000}];]
Out[159]= {1.30249,Null}
Out[160]= {3.52216,Null}
Таким образом, полный Дирихле в 3 раза медленнее.Если вам нужно m> 1 выборочных точек за раз, вы можете выиграть, выполнив (#/Total[#]&)/@RandomReal[GammaDistribution[1,1],{m,n}]
.