View Javadoc

    1   /*
    2    * Copyright 2003-2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.math.distribution;
    17
    18  import java.io.Serializable;
    19
    20  import org.apache.commons.math.MathException;
    21  import org.apache.commons.math.special.Beta;
    22
    23  /***
    24   * Default implementation of
    25   * {@link org.apache.commons.math.distribution.TDistribution}.
    26   *
    27   * @version $Revision: 348519 $ $Date: 2005-11-23 12:12:18 -0700 (Wed, 23 Nov 2005) $
    28   */
    29  public class TDistributionImpl
    30      extends AbstractContinuousDistribution
    31      implements TDistribution, Serializable  {
    32
    33      /*** Serializable version identifier */
    34      private static final long serialVersionUID = -5852615386664158222L;
    35
    36      /*** The degrees of freedom*/
    37      private double degreesOfFreedom;
    38
    39      /***
    40       * Create a t distribution using the given degrees of freedom.
    41       * @param degreesOfFreedom the degrees of freedom.
    42       */
    43      public TDistributionImpl(double degreesOfFreedom) {
    44          super();
    45          setDegreesOfFreedom(degreesOfFreedom);
    46      }
    47
    48      /***
    49       * Modify the degrees of freedom.
    50       * @param degreesOfFreedom the new degrees of freedom.
    51       */
    52      public void setDegreesOfFreedom(double degreesOfFreedom) {
    53          if (degreesOfFreedom <= 0.0) {
    54              throw new IllegalArgumentException("degrees of freedom must be positive.");
    55          }
    56          this.degreesOfFreedom = degreesOfFreedom;
    57      }
    58
    59      /***
    60       * Access the degrees of freedom.
    61       * @return the degrees of freedom.
    62       */
    63      public double getDegreesOfFreedom() {
    64          return degreesOfFreedom;
    65      }
    66
    67      /***
    68       * For this disbution, X, this method returns P(X &lt; <code>x</code>).
    69       * @param x the value at which the CDF is evaluated.
    70       * @return CDF evaluted at <code>x</code>.
    71       * @throws MathException if the cumulative probability can not be
    72       *            computed due to convergence or other numerical errors.
    73       */
    74      public double cumulativeProbability(double x) throws MathException{
    75          double ret;
    76          if (x == 0.0) {
    77              ret = 0.5;
    78          } else {
    79              double t =
    80                  Beta.regularizedBeta(
    81                      getDegreesOfFreedom() / (getDegreesOfFreedom() + (x * x)),
    82                      0.5 * getDegreesOfFreedom(),
    83                      0.5);
    84              if (x < 0.0) {
    85                  ret = 0.5 * t;
    86              } else {
    87                  ret = 1.0 - 0.5 * t;
    88              }
    89          }
    90
    91          return ret;
    92      }
    93
    94      /***
    95       * For this distribution, X, this method returns the critical point x, such
    96       * that P(X &lt; x) = <code>p</code>.
    97       * <p>
    98       * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
    99       * <code>Double.POSITIVE_INFINITY</code> for p=1.
    100      *
    101      * @param p the desired probability
    102      * @return x, such that P(X &lt; x) = <code>p</code>
    103      * @throws MathException if the inverse cumulative probability can not be
    104      *         computed due to convergence or other numerical errors.
    105      * @throws IllegalArgumentException if <code>p</code> is not a valid
    106      *         probability.
    107      */
    108     public double inverseCumulativeProbability(final double p)
    109     throws MathException {
    110         if (p == 0) {
    111             return Double.NEGATIVE_INFINITY;
    112         }
    113         if (p == 1) {
    114             return Double.POSITIVE_INFINITY;
    115         }
    116         return super.inverseCumulativeProbability(p);
    117     }
    118
    119     /***
    120      * Access the domain value lower bound, based on <code>p</code>, used to
    121      * bracket a CDF root.  This method is used by
    122      * {@link #inverseCumulativeProbability(double)} to find critical values.
    123      *
    124      * @param p the desired probability for the critical value
    125      * @return domain value lower bound, i.e.
    126      *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
    127      */
    128     protected double getDomainLowerBound(double p) {
    129         return -Double.MAX_VALUE;
    130     }
    131
    132     /***
    133      * Access the domain value upper bound, based on <code>p</code>, used to
    134      * bracket a CDF root.  This method is used by
    135      * {@link #inverseCumulativeProbability(double)} to find critical values.
    136      *
    137      * @param p the desired probability for the critical value
    138      * @return domain value upper bound, i.e.
    139      *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
    140      */
    141     protected double getDomainUpperBound(double p) {
    142         return Double.MAX_VALUE;
    143     }
    144
    145     /***
    146      * Access the initial domain value, based on <code>p</code>, used to
    147      * bracket a CDF root.  This method is used by
    148      * {@link #inverseCumulativeProbability(double)} to find critical values.
    149      *
    150      * @param p the desired probability for the critical value
    151      * @return initial domain value
    152      */
    153     protected double getInitialDomain(double p) {
    154         return 0.0;
    155     }
    156 }