1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/*
2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more
3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements.  See the NOTICE file distributed with
4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership.
5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0
6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with
7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License.  You may obtain a copy of the License at
8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *      http://www.apache.org/licenses/LICENSE-2.0
10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software
12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS,
13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and
15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License.
16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.distribution;
18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathException;
20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException;
21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats;
22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.special.Gamma;
23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.special.Beta;
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.util.FastMath;
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/**
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Implements the Beta distribution.
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * References:
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul>
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><a href="http://en.wikipedia.org/wiki/Beta_distribution">
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Beta distribution</a></li>
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul>
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p>
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class BetaDistributionImpl
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    extends AbstractContinuousDistribution implements BetaDistribution {
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Default inverse cumulative probability accuracy
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.1
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Serializable version identifier. */
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final long serialVersionUID = -1221965979403477668L;
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** First shape parameter. */
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private double alpha;
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Second shape parameter. */
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private double beta;
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Normalizing factor used in density computations.
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * updated whenever alpha or beta are changed.
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private double z;
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Inverse cumulative probability accuracy */
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final double solverAbsoluteAccuracy;
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Build a new instance.
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param alpha first shape parameter (must be positive)
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param beta second shape parameter (must be positive)
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.1
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public BetaDistributionImpl(double alpha, double beta, double inverseCumAccuracy) {
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.alpha = alpha;
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.beta = beta;
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        z = Double.NaN;
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        solverAbsoluteAccuracy = inverseCumAccuracy;
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Build a new instance.
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param alpha first shape parameter (must be positive)
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param beta second shape parameter (must be positive)
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public BetaDistributionImpl(double alpha, double beta) {
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc}
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated as of 2.1 (class will become immutable in 3.0)
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setAlpha(double alpha) {
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.alpha = alpha;
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        z = Double.NaN;
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getAlpha() {
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return alpha;
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc}
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated as of 2.1 (class will become immutable in 3.0)
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setBeta(double beta) {
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.beta = beta;
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        z = Double.NaN;
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getBeta() {
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return beta;
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Recompute the normalization factor.
118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private void recomputeZ() {
120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (Double.isNaN(z)) {
121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            z = Gamma.logGamma(alpha) + Gamma.logGamma(beta) - Gamma.logGamma(alpha + beta);
122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Return the probability density for a particular point.
127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param x The point at which the density should be computed.
129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return The pdf at point x.
130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @deprecated
131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Deprecated
133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double density(Double x) {
134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return density(x.doubleValue());
135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Return the probability density for a particular point.
139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param x The point at which the density should be computed.
141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return The pdf at point x.
142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.1
143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double density(double x) {
146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        recomputeZ();
147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (x < 0 || x > 1) {
148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 0;
149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else if (x == 0) {
150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (alpha < 1) {
151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                throw MathRuntimeException.createIllegalArgumentException(
152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                        LocalizedFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA, alpha);
153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 0;
155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else if (x == 1) {
156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if (beta < 1) {
157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                throw MathRuntimeException.createIllegalArgumentException(
158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                        LocalizedFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA, beta);
159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 0;
161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else {
162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            double logX = FastMath.log(x);
163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            double log1mX = FastMath.log1p(-x);
164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return FastMath.exp((alpha - 1) * logX + (beta - 1) * log1mX - z);
165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double inverseCumulativeProbability(double p) throws MathException {
171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (p == 0) {
172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 0;
173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else if (p == 1) {
174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 1;
175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else {
176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return super.inverseCumulativeProbability(p);
177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected double getInitialDomain(double p) {
183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return p;
184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected double getDomainLowerBound(double p) {
189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return 0;
190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected double getDomainUpperBound(double p) {
195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return 1;
196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double cumulativeProbability(double x) throws MathException {
200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (x <= 0) {
201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 0;
202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else if (x >= 1) {
203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 1;
204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } else {
205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return Beta.regularizedBeta(x, alpha, beta);
206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double cumulativeProbability(double x0, double x1) throws MathException {
212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return cumulativeProbability(x1) - cumulativeProbability(x0);
213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Return the absolute accuracy setting of the solver used to estimate
217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * inverse cumulative probabilities.
218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the solver absolute accuracy
220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.1
221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected double getSolverAbsoluteAccuracy() {
224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return solverAbsoluteAccuracy;
225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the lower bound of the support for this distribution.
229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * The support of the Beta distribution is always [0, 1], regardless
230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * of the parameters, so this method always returns 0.
231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return lower bound of the support (always 0)
233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.2
234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getSupportLowerBound() {
236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return 0;
237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the upper bound of the support for this distribution.
241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * The support of the Beta distribution is always [0, 1], regardless
242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * of the parameters, so this method always returns 1.
243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return lower bound of the support (always 1)
245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.2
246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getSupportUpperBound() {
248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return 1;
249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the mean.
253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * For first shape parameter <code>s1</code> and
255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * second shape parameter <code>s2</code>, the mean is
256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <code>s1 / (s1 + s2)</code>
257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the mean
259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.2
260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getNumericalMean() {
262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final double a = getAlpha();
263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return a / (a + getBeta());
264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns the variance.
268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * For first shape parameter <code>s1</code> and
270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * second shape parameter <code>s2</code>,
271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * the variance is
272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <code>[ s1 * s2 ] / [ (s1 + s2)^2 * (s1 + s2 + 1) ]</code>
273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the variance
275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @since 2.2
276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public double getNumericalVariance() {
278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final double a = getAlpha();
279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final double b = getBeta();
280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final double alphabetasum = a + b;
281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (a * b) / ((alphabetasum * alphabetasum) * (alphabetasum + 1));
282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond}
285