View Javadoc

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