package umontreal.iro.lecuyer.randvar;
import umontreal.iro.lecuyer.rng.*;
import umontreal.iro.lecuyer.probdist.BetaSymmetricalDist;


/**
 * This class implements symmetrical beta random variate generators using
 * Devroye's one-liner method. It is based on Best's relation 
 * between a Student-t variate and a symmetrical beta variate:
 * 
 * 

*
* Bα, α$\displaystyle \;\stackrel{{ L}}{{=}}\;$$\displaystyle {\textstyle\frac{1}{2}}$(1 + $\displaystyle {\frac{{T_{2\alpha}}}{{\sqrt{2\alpha + T_{2\alpha}^2}}}}$). *

* If S is a random sign and U1, U2 are two independent uniform [0, 1] * random variates, then the following gives a symmetrical * beta variate: * *

*
* Bα, α[tex2html_wrap_indisplay172][tex2html_wrap_indisplay173] + $\displaystyle {\frac{{S}}{{2
 * \sqrt{1 + \frac{1}{(U_1^{-1/\alpha} - 1)\cos^2(2\pi U_2)}}}}}$ *

* valid for any shape parameter * α > 0. * */ public class BetaSymmetricalBestGen extends BetaSymmetricalGen { private RandomStream stream2; private RandomStream stream3; private double afactor; // = 1/alpha private static final double TWOPI = 2.0*Math.PI; // = 2 Pi /** * Creates a symmetrical beta random variate generator with * parameter α = alpha, using stream s1 to generate * U1, stream s2 to generate U2 and stream s3 to * generate S, as given in equation. * */ public BetaSymmetricalBestGen (RandomStream s1, RandomStream s2, RandomStream s3, double alpha) { super (s1, null); stream2 = s2; stream3 = s3; afactor = 1.0/alpha; setParams (alpha, alpha, 0.0, 1.0); } /** * Creates a symmetrical beta random variate generator with * parameter α = alpha, using only one stream s1 * to generate U1, U2, and S as given in equation. * */ public BetaSymmetricalBestGen (RandomStream s1, double alpha) { this (s1, s1, s1, alpha); } /** * Creates a new generator for the distribution dist, * using stream s1 to generate U1, stream s2 to generate U2 * and stream s3 to generate S as given in equation. * */ public BetaSymmetricalBestGen (RandomStream s1, RandomStream s2, RandomStream s3, BetaSymmetricalDist dist) { super (s1, dist); stream2 = s2; stream3 = s3; afactor = 1.0/dist.getAlpha(); if (dist != null) setParams (dist.getAlpha(), dist.getAlpha(), dist.getA(), dist.getB()); } /** * Creates a new generator for the distribution dist, * using only one stream s1. * */ public BetaSymmetricalBestGen (RandomStream s1, BetaSymmetricalDist dist) { this (s1, s1, s1, dist); } /** * Generates a random number using Devroye's one-liner method. * Restriction: * α > 0. * */ public static double nextDouble (RandomStream s1, RandomStream s2, RandomStream s3, double alpha) { double cos, temp, v, S; cos = Math.cos (TWOPI * s2.nextDouble()); temp = 1.0/Math.pow(s1.nextDouble(), 1.0/alpha) - 1.0; v = Math.sqrt(1.0 + 1.0 / (temp*cos*cos)); S = s3.nextDouble(); if (S < 0.5) return 0.5 - 0.5/v; else return 0.5 + 0.5/v; } /** * Generates a random number using Devroye's one-liner method with * only one stream s. * Restriction: * α > 0. * */ public static double nextDouble (RandomStream s, double alpha) { return nextDouble (s, s, s, alpha); } public double nextDouble() { // Generates a random number using Devroye's one liner method double cos, temp, v, S; cos = Math.cos (TWOPI * stream2.nextDouble()); temp = 1.0/Math.pow(stream.nextDouble(), afactor) - 1.0; v = Math.sqrt(1.0 + 1.0 / (temp*cos*cos)); S = stream3.nextDouble(); if (S < 0.5) return 0.5 - 0.5/v; else return 0.5 + 0.5/v; } /** * Returns stream s2 associated with this object. * */ public RandomStream getStream2() { return stream2; } /** * Returns stream s3 associated with this object. * */ public RandomStream getStream3() { return stream3; } }

Ads help maintain this website.