1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 < <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 < 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 < 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 < <i>lower bound</i>) < <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 < <i>upper bound</i>) > <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 }