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 agents.anac.y2019.harddealer.math3.distribution;
|
---|
18 |
|
---|
19 | import agents.anac.y2019.harddealer.math3.random.RandomGenerator;
|
---|
20 | import agents.anac.y2019.harddealer.math3.random.Well19937c;
|
---|
21 |
|
---|
22 | /**
|
---|
23 | * Implementation of the chi-squared distribution.
|
---|
24 | *
|
---|
25 | * @see <a href="http://en.wikipedia.org/wiki/Chi-squared_distribution">Chi-squared distribution (Wikipedia)</a>
|
---|
26 | * @see <a href="http://mathworld.wolfram.com/Chi-SquaredDistribution.html">Chi-squared Distribution (MathWorld)</a>
|
---|
27 | */
|
---|
28 | public class ChiSquaredDistribution extends AbstractRealDistribution {
|
---|
29 | /**
|
---|
30 | * Default inverse cumulative probability accuracy
|
---|
31 | * @since 2.1
|
---|
32 | */
|
---|
33 | public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
|
---|
34 | /** Serializable version identifier */
|
---|
35 | private static final long serialVersionUID = -8352658048349159782L;
|
---|
36 | /** Internal Gamma distribution. */
|
---|
37 | private final GammaDistribution gamma;
|
---|
38 | /** Inverse cumulative probability accuracy */
|
---|
39 | private final double solverAbsoluteAccuracy;
|
---|
40 |
|
---|
41 | /**
|
---|
42 | * Create a Chi-Squared distribution with the given degrees of freedom.
|
---|
43 | *
|
---|
44 | * @param degreesOfFreedom Degrees of freedom.
|
---|
45 | */
|
---|
46 | public ChiSquaredDistribution(double degreesOfFreedom) {
|
---|
47 | this(degreesOfFreedom, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
|
---|
48 | }
|
---|
49 |
|
---|
50 | /**
|
---|
51 | * Create a Chi-Squared distribution with the given degrees of freedom and
|
---|
52 | * inverse cumulative probability accuracy.
|
---|
53 | * <p>
|
---|
54 | * <b>Note:</b> this constructor will implicitly create an instance of
|
---|
55 | * {@link Well19937c} as random generator to be used for sampling only (see
|
---|
56 | * {@link #sample()} and {@link #sample(int)}). In case no sampling is
|
---|
57 | * needed for the created distribution, it is advised to pass {@code null}
|
---|
58 | * as random generator via the appropriate constructors to avoid the
|
---|
59 | * additional initialisation overhead.
|
---|
60 | *
|
---|
61 | * @param degreesOfFreedom Degrees of freedom.
|
---|
62 | * @param inverseCumAccuracy the maximum absolute error in inverse
|
---|
63 | * cumulative probability estimates (defaults to
|
---|
64 | * {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}).
|
---|
65 | * @since 2.1
|
---|
66 | */
|
---|
67 | public ChiSquaredDistribution(double degreesOfFreedom,
|
---|
68 | double inverseCumAccuracy) {
|
---|
69 | this(new Well19937c(), degreesOfFreedom, inverseCumAccuracy);
|
---|
70 | }
|
---|
71 |
|
---|
72 | /**
|
---|
73 | * Create a Chi-Squared distribution with the given degrees of freedom.
|
---|
74 | *
|
---|
75 | * @param rng Random number generator.
|
---|
76 | * @param degreesOfFreedom Degrees of freedom.
|
---|
77 | * @since 3.3
|
---|
78 | */
|
---|
79 | public ChiSquaredDistribution(RandomGenerator rng, double degreesOfFreedom) {
|
---|
80 | this(rng, degreesOfFreedom, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
|
---|
81 | }
|
---|
82 |
|
---|
83 | /**
|
---|
84 | * Create a Chi-Squared distribution with the given degrees of freedom and
|
---|
85 | * inverse cumulative probability accuracy.
|
---|
86 | *
|
---|
87 | * @param rng Random number generator.
|
---|
88 | * @param degreesOfFreedom Degrees of freedom.
|
---|
89 | * @param inverseCumAccuracy the maximum absolute error in inverse
|
---|
90 | * cumulative probability estimates (defaults to
|
---|
91 | * {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}).
|
---|
92 | * @since 3.1
|
---|
93 | */
|
---|
94 | public ChiSquaredDistribution(RandomGenerator rng,
|
---|
95 | double degreesOfFreedom,
|
---|
96 | double inverseCumAccuracy) {
|
---|
97 | super(rng);
|
---|
98 |
|
---|
99 | gamma = new GammaDistribution(degreesOfFreedom / 2, 2);
|
---|
100 | solverAbsoluteAccuracy = inverseCumAccuracy;
|
---|
101 | }
|
---|
102 |
|
---|
103 | /**
|
---|
104 | * Access the number of degrees of freedom.
|
---|
105 | *
|
---|
106 | * @return the degrees of freedom.
|
---|
107 | */
|
---|
108 | public double getDegreesOfFreedom() {
|
---|
109 | return gamma.getShape() * 2.0;
|
---|
110 | }
|
---|
111 |
|
---|
112 | /** {@inheritDoc} */
|
---|
113 | public double density(double x) {
|
---|
114 | return gamma.density(x);
|
---|
115 | }
|
---|
116 |
|
---|
117 | /** {@inheritDoc} **/
|
---|
118 | @Override
|
---|
119 | public double logDensity(double x) {
|
---|
120 | return gamma.logDensity(x);
|
---|
121 | }
|
---|
122 |
|
---|
123 | /** {@inheritDoc} */
|
---|
124 | public double cumulativeProbability(double x) {
|
---|
125 | return gamma.cumulativeProbability(x);
|
---|
126 | }
|
---|
127 |
|
---|
128 | /** {@inheritDoc} */
|
---|
129 | @Override
|
---|
130 | protected double getSolverAbsoluteAccuracy() {
|
---|
131 | return solverAbsoluteAccuracy;
|
---|
132 | }
|
---|
133 |
|
---|
134 | /**
|
---|
135 | * {@inheritDoc}
|
---|
136 | *
|
---|
137 | * For {@code k} degrees of freedom, the mean is {@code k}.
|
---|
138 | */
|
---|
139 | public double getNumericalMean() {
|
---|
140 | return getDegreesOfFreedom();
|
---|
141 | }
|
---|
142 |
|
---|
143 | /**
|
---|
144 | * {@inheritDoc}
|
---|
145 | *
|
---|
146 | * @return {@code 2 * k}, where {@code k} is the number of degrees of freedom.
|
---|
147 | */
|
---|
148 | public double getNumericalVariance() {
|
---|
149 | return 2 * getDegreesOfFreedom();
|
---|
150 | }
|
---|
151 |
|
---|
152 | /**
|
---|
153 | * {@inheritDoc}
|
---|
154 | *
|
---|
155 | * The lower bound of the support is always 0 no matter the
|
---|
156 | * degrees of freedom.
|
---|
157 | *
|
---|
158 | * @return zero.
|
---|
159 | */
|
---|
160 | public double getSupportLowerBound() {
|
---|
161 | return 0;
|
---|
162 | }
|
---|
163 |
|
---|
164 | /**
|
---|
165 | * {@inheritDoc}
|
---|
166 | *
|
---|
167 | * The upper bound of the support is always positive infinity no matter the
|
---|
168 | * degrees of freedom.
|
---|
169 | *
|
---|
170 | * @return {@code Double.POSITIVE_INFINITY}.
|
---|
171 | */
|
---|
172 | public double getSupportUpperBound() {
|
---|
173 | return Double.POSITIVE_INFINITY;
|
---|
174 | }
|
---|
175 |
|
---|
176 | /** {@inheritDoc} */
|
---|
177 | public boolean isSupportLowerBoundInclusive() {
|
---|
178 | return true;
|
---|
179 | }
|
---|
180 |
|
---|
181 | /** {@inheritDoc} */
|
---|
182 | public boolean isSupportUpperBoundInclusive() {
|
---|
183 | return false;
|
---|
184 | }
|
---|
185 |
|
---|
186 | /**
|
---|
187 | * {@inheritDoc}
|
---|
188 | *
|
---|
189 | * The support of this distribution is connected.
|
---|
190 | *
|
---|
191 | * @return {@code true}
|
---|
192 | */
|
---|
193 | public boolean isSupportConnected() {
|
---|
194 | return true;
|
---|
195 | }
|
---|
196 | }
|
---|