001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.math3.distribution;
018
019import org.apache.commons.math3.exception.NumberIsTooLargeException;
020import org.apache.commons.math3.exception.OutOfRangeException;
021
022/**
023 * Base interface for distributions on the reals.
024 *
025 * @since 3.0
026 */
027public interface RealDistribution {
028    /**
029     * For a random variable {@code X} whose values are distributed according
030     * to this distribution, this method returns {@code P(X = x)}. In other
031     * words, this method represents the probability mass function (PMF)
032     * for the distribution.
033     *
034     * @param x the point at which the PMF is evaluated
035     * @return the value of the probability mass function at point {@code x}
036     */
037    double probability(double x);
038
039    /**
040     * Returns the probability density function (PDF) of this distribution
041     * evaluated at the specified point {@code x}. In general, the PDF is
042     * the derivative of the {@link #cumulativeProbability(double) CDF}.
043     * If the derivative does not exist at {@code x}, then an appropriate
044     * replacement should be returned, e.g. {@code Double.POSITIVE_INFINITY},
045     * {@code Double.NaN}, or  the limit inferior or limit superior of the
046     * difference quotient.
047     *
048     * @param x the point at which the PDF is evaluated
049     * @return the value of the probability density function at point {@code x}
050     */
051    double density(double x);
052
053    /**
054     * For a random variable {@code X} whose values are distributed according
055     * to this distribution, this method returns {@code P(X <= x)}. In other
056     * words, this method represents the (cumulative) distribution function
057     * (CDF) for this distribution.
058     *
059     * @param x the point at which the CDF is evaluated
060     * @return the probability that a random variable with this
061     * distribution takes a value less than or equal to {@code x}
062     */
063    double cumulativeProbability(double x);
064
065    /**
066     * For a random variable {@code X} whose values are distributed according
067     * to this distribution, this method returns {@code P(x0 < X <= x1)}.
068     *
069     * @param x0 the exclusive lower bound
070     * @param x1 the inclusive upper bound
071     * @return the probability that a random variable with this distribution
072     * takes a value between {@code x0} and {@code x1},
073     * excluding the lower and including the upper endpoint
074     * @throws NumberIsTooLargeException if {@code x0 > x1}
075     *
076     * @deprecated As of 3.1. In 4.0, this method will be renamed
077     * {@code probability(double x0, double x1)}.
078     */
079    @Deprecated
080    double cumulativeProbability(double x0, double x1) throws NumberIsTooLargeException;
081
082    /**
083     * Computes the quantile function of this distribution. For a random
084     * variable {@code X} distributed according to this distribution, the
085     * returned value is
086     * <ul>
087     * <li><code>inf{x in R | P(X<=x) >= p}</code> for {@code 0 < p <= 1},</li>
088     * <li><code>inf{x in R | P(X<=x) > 0}</code> for {@code p = 0}.</li>
089     * </ul>
090     *
091     * @param p the cumulative probability
092     * @return the smallest {@code p}-quantile of this distribution
093     * (largest 0-quantile for {@code p = 0})
094     * @throws OutOfRangeException if {@code p < 0} or {@code p > 1}
095     */
096    double inverseCumulativeProbability(double p) throws OutOfRangeException;
097
098    /**
099     * Use this method to get the numerical value of the mean of this
100     * distribution.
101     *
102     * @return the mean or {@code Double.NaN} if it is not defined
103     */
104    double getNumericalMean();
105
106    /**
107     * Use this method to get the numerical value of the variance of this
108     * distribution.
109     *
110     * @return the variance (possibly {@code Double.POSITIVE_INFINITY} as
111     * for certain cases in {@link TDistribution}) or {@code Double.NaN} if it
112     * is not defined
113     */
114    double getNumericalVariance();
115
116    /**
117     * Access the lower bound of the support. This method must return the same
118     * value as {@code inverseCumulativeProbability(0)}. In other words, this
119     * method must return
120     * <p><code>inf {x in R | P(X <= x) > 0}</code>.</p>
121     *
122     * @return lower bound of the support (might be
123     * {@code Double.NEGATIVE_INFINITY})
124     */
125    double getSupportLowerBound();
126
127    /**
128     * Access the upper bound of the support. This method must return the same
129     * value as {@code inverseCumulativeProbability(1)}. In other words, this
130     * method must return
131     * <p><code>inf {x in R | P(X <= x) = 1}</code>.</p>
132     *
133     * @return upper bound of the support (might be
134     * {@code Double.POSITIVE_INFINITY})
135     */
136    double getSupportUpperBound();
137
138    /**
139     * Whether or not the lower bound of support is in the domain of the density
140     * function.  Returns true iff {@code getSupporLowerBound()} is finite and
141     * {@code density(getSupportLowerBound())} returns a non-NaN, non-infinite
142     * value.
143     *
144     * @return true if the lower bound of support is finite and the density
145     * function returns a non-NaN, non-infinite value there
146     * @deprecated to be removed in 4.0
147     */
148    @Deprecated
149    boolean isSupportLowerBoundInclusive();
150
151    /**
152     * Whether or not the upper bound of support is in the domain of the density
153     * function.  Returns true iff {@code getSupportUpperBound()} is finite and
154     * {@code density(getSupportUpperBound())} returns a non-NaN, non-infinite
155     * value.
156     *
157     * @return true if the upper bound of support is finite and the density
158     * function returns a non-NaN, non-infinite value there
159     * @deprecated to be removed in 4.0
160     */
161    @Deprecated
162    boolean isSupportUpperBoundInclusive();
163
164    /**
165     * Use this method to get information about whether the support is connected,
166     * i.e. whether all values between the lower and upper bound of the support
167     * are included in the support.
168     *
169     * @return whether the support is connected or not
170     */
171    boolean isSupportConnected();
172
173    /**
174     * Reseed the random generator used to generate samples.
175     *
176     * @param seed the new seed
177     */
178    void reseedRandomGenerator(long seed);
179
180    /**
181     * Generate a random value sampled from this distribution.
182     *
183     * @return a random value.
184     */
185    double sample();
186
187    /**
188     * Generate a random sample from the distribution.
189     *
190     * @param sampleSize the number of random values to generate
191     * @return an array representing the random sample
192     * @throws org.apache.commons.math3.exception.NotStrictlyPositiveException
193     * if {@code sampleSize} is not positive
194     */
195    double[] sample(int sampleSize);
196}