~ubuntu-branches/ubuntu/trusty/commons-math/trusty

« back to all changes in this revision

Viewing changes to src/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2009-03-15 20:20:21 UTC
  • Revision ID: james.westby@ubuntu.com-20090315202021-zto3nmvqgcf3ami4
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
23
/**
 
24
 * The default implementation of {@link ChiSquaredDistribution}
 
25
 *
 
26
 * @version $Revision: 617953 $ $Date: 2008-02-02 22:54:00 -0700 (Sat, 02 Feb 2008) $
 
27
 */
 
28
public class ChiSquaredDistributionImpl
 
29
    extends AbstractContinuousDistribution
 
30
    implements ChiSquaredDistribution, Serializable  {
 
31
    
 
32
    /** Serializable version identifier */
 
33
    private static final long serialVersionUID = -8352658048349159782L;
 
34
 
 
35
    /** Internal Gamma distribution. */    
 
36
    private GammaDistribution gamma;
 
37
    
 
38
    /**
 
39
     * Create a Chi-Squared distribution with the given degrees of freedom.
 
40
     * @param df degrees of freedom.
 
41
     */
 
42
    public ChiSquaredDistributionImpl(double df) {
 
43
        this(df, new GammaDistributionImpl(df / 2.0, 2.0));
 
44
    }
 
45
    
 
46
    /**
 
47
     * Create a Chi-Squared distribution with the given degrees of freedom.
 
48
     * @param df degrees of freedom.
 
49
     * @param g the underlying gamma distribution used to compute probabilities.
 
50
     * @since 1.2
 
51
     */
 
52
    public ChiSquaredDistributionImpl(double df, GammaDistribution g) {
 
53
        super();
 
54
        setGamma(g);
 
55
        setDegreesOfFreedom(df);
 
56
    }
 
57
    
 
58
    /**
 
59
     * Modify the degrees of freedom.
 
60
     * @param degreesOfFreedom the new degrees of freedom.
 
61
     */
 
62
    public void setDegreesOfFreedom(double degreesOfFreedom) {
 
63
        getGamma().setAlpha(degreesOfFreedom / 2.0);
 
64
    }
 
65
        
 
66
    /**
 
67
     * Access the degrees of freedom.
 
68
     * @return the degrees of freedom.
 
69
     */
 
70
    public double getDegreesOfFreedom() {
 
71
        return getGamma().getAlpha() * 2.0;
 
72
    }
 
73
        
 
74
    /**
 
75
     * For this disbution, X, this method returns P(X < x).
 
76
     * @param x the value at which the CDF is evaluated.
 
77
     * @return CDF for this distribution. 
 
78
     * @throws MathException if the cumulative probability can not be
 
79
     *            computed due to convergence or other numerical errors.
 
80
     */
 
81
    public double cumulativeProbability(double x) throws MathException {
 
82
        return getGamma().cumulativeProbability(x);
 
83
    }
 
84
    
 
85
    /**
 
86
     * For this distribution, X, this method returns the critical point x, such
 
87
     * that P(X &lt; x) = <code>p</code>.
 
88
     * <p>
 
89
     * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
 
90
     *
 
91
     * @param p the desired probability
 
92
     * @return x, such that P(X &lt; x) = <code>p</code>
 
93
     * @throws MathException if the inverse cumulative probability can not be
 
94
     *         computed due to convergence or other numerical errors.
 
95
     * @throws IllegalArgumentException if <code>p</code> is not a valid
 
96
     *         probability.
 
97
     */
 
98
    public double inverseCumulativeProbability(final double p)
 
99
        throws MathException {
 
100
        if (p == 0) {
 
101
            return 0d;
 
102
        }
 
103
        if (p == 1) {
 
104
            return Double.POSITIVE_INFINITY;
 
105
        }
 
106
        return super.inverseCumulativeProbability(p);
 
107
    }
 
108
        
 
109
    /**
 
110
     * Access the domain value lower bound, based on <code>p</code>, used to
 
111
     * bracket a CDF root.  This method is used by
 
112
     * {@link #inverseCumulativeProbability(double)} to find critical values.
 
113
     * 
 
114
     * @param p the desired probability for the critical value
 
115
     * @return domain value lower bound, i.e.
 
116
     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code> 
 
117
     */
 
118
    protected double getDomainLowerBound(double p) {
 
119
        return Double.MIN_VALUE * getGamma().getBeta();
 
120
    }
 
121
 
 
122
    /**
 
123
     * Access the domain value upper bound, based on <code>p</code>, used to
 
124
     * bracket a CDF root.  This method is used by
 
125
     * {@link #inverseCumulativeProbability(double)} to find critical values.
 
126
     * 
 
127
     * @param p the desired probability for the critical value
 
128
     * @return domain value upper bound, i.e.
 
129
     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code> 
 
130
     */
 
131
    protected double getDomainUpperBound(double p) {
 
132
        // NOTE: chi squared is skewed to the left
 
133
        // NOTE: therefore, P(X < &mu;) > .5
 
134
 
 
135
        double ret;
 
136
 
 
137
        if (p < .5) {
 
138
            // use mean
 
139
            ret = getDegreesOfFreedom();
 
140
        } else {
 
141
            // use max
 
142
            ret = Double.MAX_VALUE;
 
143
        }
 
144
        
 
145
        return ret;
 
146
    }
 
147
 
 
148
    /**
 
149
     * Access the initial domain value, based on <code>p</code>, used to
 
150
     * bracket a CDF root.  This method is used by
 
151
     * {@link #inverseCumulativeProbability(double)} to find critical values.
 
152
     * 
 
153
     * @param p the desired probability for the critical value
 
154
     * @return initial domain value
 
155
     */
 
156
    protected double getInitialDomain(double p) {
 
157
        // NOTE: chi squared is skewed to the left
 
158
        // NOTE: therefore, P(X < &mu;) > .5
 
159
        
 
160
        double ret;
 
161
 
 
162
        if (p < .5) {
 
163
            // use 1/2 mean
 
164
            ret = getDegreesOfFreedom() * .5;
 
165
        } else {
 
166
            // use mean
 
167
            ret = getDegreesOfFreedom();
 
168
        }
 
169
        
 
170
        return ret;
 
171
    }
 
172
    
 
173
    /**
 
174
     * Modify the underlying gamma distribution.  The caller is responsible for
 
175
     * insuring the gamma distribution has the proper parameter settings.
 
176
     * @param g the new distribution.
 
177
     * @since 1.2 made public
 
178
     */
 
179
    public void setGamma(GammaDistribution g) {
 
180
        this.gamma = g;
 
181
        
 
182
    }
 
183
 
 
184
    /**
 
185
     * Access the Gamma distribution.
 
186
     * @return the internal Gamma distribution.
 
187
     */
 
188
    private GammaDistribution getGamma() {
 
189
        return gamma;
 
190
    }
 
191
}