package umontreal.iro.lecuyer.randvarmulti;

import umontreal.iro.lecuyer.probdist.GammaDist;
import umontreal.iro.lecuyer.randvar.RandomVariateGen;
import umontreal.iro.lecuyer.randvar.GammaAcceptanceRejectionGen;
import umontreal.iro.lecuyer.rng.RandomStream;


/**
 * Extends {@link RandomMultivariateGen} for a
 * Dirichlet distribution.  This distribution uses the
 * parameters
 * 
 * 
 * α1,..., αk, and has density
 * 

*

*
* f (x1,…, xk) = Γ(α0)∏i=1kxiαi-1 / ∏i=1kΓ(αi)) *

* where * α0 = ∑i=1kαi. * *

* Here, the successive coordinates of the Dirichlet vector are generated * * via the class * {@link umontreal.iro.lecuyer.randvar.GammaAcceptanceRejectionGen GammaAcceptanceRejectionGen} * in package randvar, using the same stream for all the uniforms. * */ public class DirichletGen extends RandomMultivariateGen { private GammaAcceptanceRejectionGen[] ggens; /** * Constructs a new Dirichlet * generator with parameters * αi+1 = alphas[i], * for * i = 0,…, k - 1, and the stream stream. * * @param stream the random number stream used to generate uniforms. * * @param alphas the αi parameters of the generated distribution. * * @exception IllegalArgumentException if one αk is negative or 0. * * @exception NullPointerException if any argument is null. * */ public DirichletGen (RandomStream stream, double[] alphas) { if (stream == null) throw new NullPointerException ("stream is null"); this.stream = stream; dimension = alphas.length; ggens = new GammaAcceptanceRejectionGen[alphas.length]; for (int k = 0; k < alphas.length; k++) ggens[k] = new GammaAcceptanceRejectionGen (stream, new GammaDist (alphas[k], 1.0/2.0)); } /** * Returns the * αi+1 parameter for this * Dirichlet generator. * * @param i the index of the parameter. * * @return the value of the parameter. * @exception ArrayIndexOutOfBoundsException if i is * negative or greater than or equal to {@link #getDimension(()) getDimension}. * * */ public double getAlpha (int i) { return ((GammaDist)ggens[i].getDistribution()).getAlpha(); } /** * Generates a new point from the Dirichlet distribution with * parameters alphas, using the stream stream. * The generated values are placed into p. * * @param stream the random number stream used to generate the uniforms. * * @param alphas the αi parameters of the distribution, for * * i = 1,…, k. * * @param p the array to be filled with the generated point. * * */ public static void nextPoint (RandomStream stream, double[] alphas, double[] p) { double total = 0; for (int i = 0; i < alphas.length; i++) { p[i] = GammaAcceptanceRejectionGen.nextDouble (stream, stream, alphas[i], 1.0/2.0); total += p[i]; } for (int i = 0; i < alphas.length; i++) p[i] /= total; } /** * Generates a point from the Dirichlet distribution. * * @param p the array to be filled with the generated point. * */ public void nextPoint (double[] p) { int n = ggens.length; double total = 0; for (int i = 0; i < n; i++) { p[i] = ggens[i].nextDouble(); total += p[i]; } for (int i = 0; i < n; i++) p[i] /= total; } }

Ads help maintain this website.