/* *
 * Title:        

* Description:

* Copyright: Copyright (c)

* Company:

* @author * @version 1.0 */ package umontreal.iro.lecuyer.probdist; import umontreal.iro.lecuyer.util.Num; /** * Extends the class {@link ContinuousDistribution} for * the Johnson SU distribution. * It has shape parameters γ and * δ > 0, location parameter * ξ, and scale parameter * λ > 0. * Denoting * y = (x - ξ)/λ, the distribution has density *

*

*
* f (x) = δ/(λ(y^2 + 1)1/2(2π)1/2exp(- (1/2)[γ + δln[y + (y^2 + 1)1/2]]2))        for - ∞ < x < ∞, *

* and distribution function *

*

*
* F(x) = Φ{γ + δln[y + (y^2 + 1)1/2]},        for - ∞ < x < ∞, *

* where Φ is the standard normal distribution function. * The inverse distribution function is *

*

*
* F-1(u) = ξ + λ(et(u) - e-t(u))/2,        for 0 <= u < 1, *

* where *

*

*
* t(u) = [Φ-1(u) - γ]/δ. *

* *

* This class relies on the methods {@link NormalDist#cdf01 NormalDist.cdf01} and * {@link NormalDist#inverseF01 NormalDist.inverseF01} of {@link NormalDist} to * approximate Φ and Φ-1. * */ public class JohnsonSUDist extends ContinuousDistribution { private double gamma; private double delta; private double xi; private double lambda; private static double calcR (double a, double b, double x) { /* ** Soit y = (x - a)/b; cette fonction calcule r r = y + sqrt(y*y + 1) en utilisant un algorithme stable ****/ double y = (x - a)/b; boolean negative; if (y < 0.0) { y = -y; negative = true; } else negative = false; double r; if (y < 1.0e10) r = y + Math.sqrt (1.0 + y*y); else r = 2.0 * y; if (negative) r = 1.0 / r; return r; } /** * Same as {@link #JohnsonSUDist(double,double,double,double) JohnsonSUDist} * (gamma, delta, 0.0, 1.0). * */ public JohnsonSUDist (double gamma, double delta) { if (delta <= 0) throw new IllegalArgumentException ("delta <= 0"); this.gamma = gamma; this.delta = delta; this.xi = 0.0; this.lambda = 1.0; } /** * Constructs a JohnsonSUDist object * with shape parameters γ and δ, * location parameter ξ, and scale parameter λ. * */ public JohnsonSUDist (double gamma, double delta, double xi, double lambda) { setParams (gamma, delta, xi, lambda); } public double density (double x) { return density (gamma, delta, xi, lambda, x); } public double cdf (double x) { return cdf (gamma, delta, xi, lambda, x); } public double barF (double x) { return barF (gamma, delta, xi, lambda, x); } public double inverseF (double u){ return inverseF (gamma, delta, xi, lambda, u); } public double getMean() { return JohnsonSUDist.getMean (gamma, delta, xi, lambda); } public double getVariance() { return JohnsonSUDist.getVariance (gamma, delta, xi, lambda); } public double getStandardDeviation() { return JohnsonSUDist.getStandardDeviation (gamma, delta, xi, lambda); } /** * Computes the density function f (x). * */ public static double density (double gamma, double delta, double xi, double lambda, double x) { if (lambda <= 0) throw new IllegalArgumentException ("lambda <= 0"); if (delta <= 0) throw new IllegalArgumentException ("delta <= 0"); double r = calcR (xi, lambda, x); if (r <= 0.0) return 0.0; double t = gamma + delta*Math.log (r); double y = (x - xi)/lambda; return delta/(lambda*Math.sqrt (2.0*Math.PI)*Math.sqrt (y*y + 1.0))* Math.exp (-t*t/2.0); } /** * Computes the distribution function F(x). * */ public static double cdf (double gamma, double delta, double xi, double lambda, double x) { if (lambda <= 0) throw new IllegalArgumentException ("lambda <= 0"); if (delta <= 0) throw new IllegalArgumentException ("delta <= 0"); double r = calcR (xi, lambda, x); if (r > 0.0) return NormalDist.cdf01 (gamma + delta*Math.log (r)); else return 0.0; } /** * Computes the complementary distribution function 1 - F(x). * */ public static double barF (double gamma, double delta, double xi, double lambda, double x) { if (lambda <= 0) throw new IllegalArgumentException ("lambda <= 0"); if (delta <= 0) throw new IllegalArgumentException ("delta <= 0"); double r = calcR (xi, lambda, x); if (r > 0.0) return NormalDist.barF01 (gamma + delta * Math.log (r)); else return 1.0; } /** * Computes the inverse distribution function F-1(u). * */ public static double inverseF (double gamma, double delta, double xi, double lambda, double u) { if (lambda <= 0) throw new IllegalArgumentException ("lambda <= 0"); if (delta <= 0) throw new IllegalArgumentException ("delta <= 0"); if (u > 1.0 || u < 0.0) throw new IllegalArgumentException ("u not in [0,1]"); if (u >= 1.0) return Double.POSITIVE_INFINITY; if (u <= 0.0) return Double.NEGATIVE_INFINITY; double z = NormalDist.inverseF01 (u); double v = (z - gamma)/delta; if (v >= Num.LN2*Num.DBL_MAX_EXP) return Double.POSITIVE_INFINITY; if (v <= Num.LN2*Num.DBL_MIN_EXP) return Double.NEGATIVE_INFINITY; return xi + lambda * Math.sinh(v); } /** * Computes and returns the mean * of the Johnson SU distribution with parameters γ, δ, ξ and λ. * * @return the mean of the Johnson SU distribution * * E[X] = ξ - λexp1/(2δ2)sinh(γ/δ) * */ public static double getMean (double gamma, double delta, double xi, double lambda) { if (lambda <= 0.0) throw new IllegalArgumentException ("lambda <= 0"); if (delta <= 0.0) throw new IllegalArgumentException ("delta <= 0"); return (xi - (lambda * Math.exp(1.0 / (2.0 * delta * delta)) * Math.sinh(gamma / delta))); } /** * Computes and returns the variance * of the Johnson SU distribution with parameters γ, δ, ξ and λ. * * @return the variance of the Johnson SU distribution * * Var[X] = (λ2/2)(exp1/δ2 -1)(exp1/δ2cosh(2γ/δ) + 1) * */ public static double getVariance (double gamma, double delta, double xi, double lambda) { double omega2; if (lambda <= 0.0) throw new IllegalArgumentException ("lambda <= 0"); if (delta <= 0.0) throw new IllegalArgumentException ("delta <= 0"); omega2 = Math.exp(1 / (delta * delta)); return ((omega2 - 1) * (omega2 * Math.cosh(2 * gamma / delta) + 1) / 2 * lambda * lambda); } /** * Computes and returns the standard deviation of the Johnson SU * distribution with parameters γ, δ, ξ and λ. * * @return the standard deviation of the Johnson SU distribution * */ public static double getStandardDeviation (double gamma, double delta, double xi, double lambda) { return Math.sqrt (JohnsonSUDist.getVariance (gamma, delta, xi, lambda)); } /** * Returns the value of γ for this object. * */ public double getGamma() { return gamma; } /** * Returns the value of δ for this object. * */ public double getDelta() { return delta; } /** * Returns the value of ξ for this object. * */ public double getXi() { return xi; } /** * Returns the value of λ for this object. * */ public double getLambda() { return lambda; } /** * Sets the value of the parameters γ, δ, ξ and * λ for this object. * */ public void setParams (double gamma, double delta, double xi, double lambda) { if (lambda <= 0) throw new IllegalArgumentException ("lambda <= 0"); if (delta <= 0) throw new IllegalArgumentException ("delta <= 0"); this.gamma = gamma; this.delta = delta; this.xi = xi; this.lambda = lambda; } /** * Return a table containing the parameters of the current distribution. * This table is put in regular order: [γ, δ, ξ, λ]. * * */ public double[] getParams () { double[] retour = {gamma, delta, xi, lambda}; return retour; } public String toString () { return getClass().getSimpleName() + " : gamma = " + gamma + ", delta = " + delta + ", xi = " + xi + ", lambda = " + lambda; } }

Ads help maintain this website.