comparison libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/ChiSquareTestImpl.html @ 13:cbf34dd4d7e6

commons-math-2.1 added
author dwinter
date Tue, 04 Jan 2011 10:02:07 +0100
parents
children
comparison
equal deleted inserted replaced
12:970d26a94fb7 13:cbf34dd4d7e6
1 <HTML>
2 <BODY BGCOLOR="white">
3 <PRE>
4 <FONT color="green">001</FONT> /*<a name="line.1"></a>
5 <FONT color="green">002</FONT> * Licensed to the Apache Software Foundation (ASF) under one or more<a name="line.2"></a>
6 <FONT color="green">003</FONT> * contributor license agreements. See the NOTICE file distributed with<a name="line.3"></a>
7 <FONT color="green">004</FONT> * this work for additional information regarding copyright ownership.<a name="line.4"></a>
8 <FONT color="green">005</FONT> * The ASF licenses this file to You under the Apache License, Version 2.0<a name="line.5"></a>
9 <FONT color="green">006</FONT> * (the "License"); you may not use this file except in compliance with<a name="line.6"></a>
10 <FONT color="green">007</FONT> * the License. You may obtain a copy of the License at<a name="line.7"></a>
11 <FONT color="green">008</FONT> *<a name="line.8"></a>
12 <FONT color="green">009</FONT> * http://www.apache.org/licenses/LICENSE-2.0<a name="line.9"></a>
13 <FONT color="green">010</FONT> *<a name="line.10"></a>
14 <FONT color="green">011</FONT> * Unless required by applicable law or agreed to in writing, software<a name="line.11"></a>
15 <FONT color="green">012</FONT> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.12"></a>
16 <FONT color="green">013</FONT> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.13"></a>
17 <FONT color="green">014</FONT> * See the License for the specific language governing permissions and<a name="line.14"></a>
18 <FONT color="green">015</FONT> * limitations under the License.<a name="line.15"></a>
19 <FONT color="green">016</FONT> */<a name="line.16"></a>
20 <FONT color="green">017</FONT> package org.apache.commons.math.stat.inference;<a name="line.17"></a>
21 <FONT color="green">018</FONT> <a name="line.18"></a>
22 <FONT color="green">019</FONT> import org.apache.commons.math.MathException;<a name="line.19"></a>
23 <FONT color="green">020</FONT> import org.apache.commons.math.MathRuntimeException;<a name="line.20"></a>
24 <FONT color="green">021</FONT> import org.apache.commons.math.distribution.ChiSquaredDistribution;<a name="line.21"></a>
25 <FONT color="green">022</FONT> import org.apache.commons.math.distribution.ChiSquaredDistributionImpl;<a name="line.22"></a>
26 <FONT color="green">023</FONT> <a name="line.23"></a>
27 <FONT color="green">024</FONT> /**<a name="line.24"></a>
28 <FONT color="green">025</FONT> * Implements Chi-Square test statistics defined in the<a name="line.25"></a>
29 <FONT color="green">026</FONT> * {@link UnknownDistributionChiSquareTest} interface.<a name="line.26"></a>
30 <FONT color="green">027</FONT> *<a name="line.27"></a>
31 <FONT color="green">028</FONT> * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $<a name="line.28"></a>
32 <FONT color="green">029</FONT> */<a name="line.29"></a>
33 <FONT color="green">030</FONT> public class ChiSquareTestImpl implements UnknownDistributionChiSquareTest {<a name="line.30"></a>
34 <FONT color="green">031</FONT> <a name="line.31"></a>
35 <FONT color="green">032</FONT> /** Distribution used to compute inference statistics. */<a name="line.32"></a>
36 <FONT color="green">033</FONT> private ChiSquaredDistribution distribution;<a name="line.33"></a>
37 <FONT color="green">034</FONT> <a name="line.34"></a>
38 <FONT color="green">035</FONT> /**<a name="line.35"></a>
39 <FONT color="green">036</FONT> * Construct a ChiSquareTestImpl<a name="line.36"></a>
40 <FONT color="green">037</FONT> */<a name="line.37"></a>
41 <FONT color="green">038</FONT> public ChiSquareTestImpl() {<a name="line.38"></a>
42 <FONT color="green">039</FONT> this(new ChiSquaredDistributionImpl(1.0));<a name="line.39"></a>
43 <FONT color="green">040</FONT> }<a name="line.40"></a>
44 <FONT color="green">041</FONT> <a name="line.41"></a>
45 <FONT color="green">042</FONT> /**<a name="line.42"></a>
46 <FONT color="green">043</FONT> * Create a test instance using the given distribution for computing<a name="line.43"></a>
47 <FONT color="green">044</FONT> * inference statistics.<a name="line.44"></a>
48 <FONT color="green">045</FONT> * @param x distribution used to compute inference statistics.<a name="line.45"></a>
49 <FONT color="green">046</FONT> * @since 1.2<a name="line.46"></a>
50 <FONT color="green">047</FONT> */<a name="line.47"></a>
51 <FONT color="green">048</FONT> public ChiSquareTestImpl(ChiSquaredDistribution x) {<a name="line.48"></a>
52 <FONT color="green">049</FONT> super();<a name="line.49"></a>
53 <FONT color="green">050</FONT> setDistribution(x);<a name="line.50"></a>
54 <FONT color="green">051</FONT> }<a name="line.51"></a>
55 <FONT color="green">052</FONT> /**<a name="line.52"></a>
56 <FONT color="green">053</FONT> * {@inheritDoc}<a name="line.53"></a>
57 <FONT color="green">054</FONT> * &lt;p&gt;&lt;strong&gt;Note: &lt;/strong&gt;This implementation rescales the<a name="line.54"></a>
58 <FONT color="green">055</FONT> * &lt;code&gt;expected&lt;/code&gt; array if necessary to ensure that the sum of the<a name="line.55"></a>
59 <FONT color="green">056</FONT> * expected and observed counts are equal.&lt;/p&gt;<a name="line.56"></a>
60 <FONT color="green">057</FONT> *<a name="line.57"></a>
61 <FONT color="green">058</FONT> * @param observed array of observed frequency counts<a name="line.58"></a>
62 <FONT color="green">059</FONT> * @param expected array of expected frequency counts<a name="line.59"></a>
63 <FONT color="green">060</FONT> * @return chi-square test statistic<a name="line.60"></a>
64 <FONT color="green">061</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.61"></a>
65 <FONT color="green">062</FONT> * or length is less than 2<a name="line.62"></a>
66 <FONT color="green">063</FONT> */<a name="line.63"></a>
67 <FONT color="green">064</FONT> public double chiSquare(double[] expected, long[] observed)<a name="line.64"></a>
68 <FONT color="green">065</FONT> throws IllegalArgumentException {<a name="line.65"></a>
69 <FONT color="green">066</FONT> if (expected.length &lt; 2) {<a name="line.66"></a>
70 <FONT color="green">067</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.67"></a>
71 <FONT color="green">068</FONT> "expected array length = {0}, must be at least 2",<a name="line.68"></a>
72 <FONT color="green">069</FONT> expected.length);<a name="line.69"></a>
73 <FONT color="green">070</FONT> }<a name="line.70"></a>
74 <FONT color="green">071</FONT> if (expected.length != observed.length) {<a name="line.71"></a>
75 <FONT color="green">072</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.72"></a>
76 <FONT color="green">073</FONT> "dimension mismatch {0} != {1}", expected.length, observed.length);<a name="line.73"></a>
77 <FONT color="green">074</FONT> }<a name="line.74"></a>
78 <FONT color="green">075</FONT> checkPositive(expected);<a name="line.75"></a>
79 <FONT color="green">076</FONT> checkNonNegative(observed);<a name="line.76"></a>
80 <FONT color="green">077</FONT> double sumExpected = 0d;<a name="line.77"></a>
81 <FONT color="green">078</FONT> double sumObserved = 0d;<a name="line.78"></a>
82 <FONT color="green">079</FONT> for (int i = 0; i &lt; observed.length; i++) {<a name="line.79"></a>
83 <FONT color="green">080</FONT> sumExpected += expected[i];<a name="line.80"></a>
84 <FONT color="green">081</FONT> sumObserved += observed[i];<a name="line.81"></a>
85 <FONT color="green">082</FONT> }<a name="line.82"></a>
86 <FONT color="green">083</FONT> double ratio = 1.0d;<a name="line.83"></a>
87 <FONT color="green">084</FONT> boolean rescale = false;<a name="line.84"></a>
88 <FONT color="green">085</FONT> if (Math.abs(sumExpected - sumObserved) &gt; 10E-6) {<a name="line.85"></a>
89 <FONT color="green">086</FONT> ratio = sumObserved / sumExpected;<a name="line.86"></a>
90 <FONT color="green">087</FONT> rescale = true;<a name="line.87"></a>
91 <FONT color="green">088</FONT> }<a name="line.88"></a>
92 <FONT color="green">089</FONT> double sumSq = 0.0d;<a name="line.89"></a>
93 <FONT color="green">090</FONT> for (int i = 0; i &lt; observed.length; i++) {<a name="line.90"></a>
94 <FONT color="green">091</FONT> if (rescale) {<a name="line.91"></a>
95 <FONT color="green">092</FONT> final double dev = observed[i] - ratio * expected[i];<a name="line.92"></a>
96 <FONT color="green">093</FONT> sumSq += dev * dev / (ratio * expected[i]);<a name="line.93"></a>
97 <FONT color="green">094</FONT> } else {<a name="line.94"></a>
98 <FONT color="green">095</FONT> final double dev = observed[i] - expected[i];<a name="line.95"></a>
99 <FONT color="green">096</FONT> sumSq += dev * dev / expected[i];<a name="line.96"></a>
100 <FONT color="green">097</FONT> }<a name="line.97"></a>
101 <FONT color="green">098</FONT> }<a name="line.98"></a>
102 <FONT color="green">099</FONT> return sumSq;<a name="line.99"></a>
103 <FONT color="green">100</FONT> }<a name="line.100"></a>
104 <FONT color="green">101</FONT> <a name="line.101"></a>
105 <FONT color="green">102</FONT> /**<a name="line.102"></a>
106 <FONT color="green">103</FONT> * {@inheritDoc}<a name="line.103"></a>
107 <FONT color="green">104</FONT> * &lt;p&gt;&lt;strong&gt;Note: &lt;/strong&gt;This implementation rescales the<a name="line.104"></a>
108 <FONT color="green">105</FONT> * &lt;code&gt;expected&lt;/code&gt; array if necessary to ensure that the sum of the<a name="line.105"></a>
109 <FONT color="green">106</FONT> * expected and observed counts are equal.&lt;/p&gt;<a name="line.106"></a>
110 <FONT color="green">107</FONT> *<a name="line.107"></a>
111 <FONT color="green">108</FONT> * @param observed array of observed frequency counts<a name="line.108"></a>
112 <FONT color="green">109</FONT> * @param expected array of expected frequency counts<a name="line.109"></a>
113 <FONT color="green">110</FONT> * @return p-value<a name="line.110"></a>
114 <FONT color="green">111</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.111"></a>
115 <FONT color="green">112</FONT> * @throws MathException if an error occurs computing the p-value<a name="line.112"></a>
116 <FONT color="green">113</FONT> */<a name="line.113"></a>
117 <FONT color="green">114</FONT> public double chiSquareTest(double[] expected, long[] observed)<a name="line.114"></a>
118 <FONT color="green">115</FONT> throws IllegalArgumentException, MathException {<a name="line.115"></a>
119 <FONT color="green">116</FONT> distribution.setDegreesOfFreedom(expected.length - 1.0);<a name="line.116"></a>
120 <FONT color="green">117</FONT> return 1.0 - distribution.cumulativeProbability(<a name="line.117"></a>
121 <FONT color="green">118</FONT> chiSquare(expected, observed));<a name="line.118"></a>
122 <FONT color="green">119</FONT> }<a name="line.119"></a>
123 <FONT color="green">120</FONT> <a name="line.120"></a>
124 <FONT color="green">121</FONT> /**<a name="line.121"></a>
125 <FONT color="green">122</FONT> * {@inheritDoc}<a name="line.122"></a>
126 <FONT color="green">123</FONT> * &lt;p&gt;&lt;strong&gt;Note: &lt;/strong&gt;This implementation rescales the<a name="line.123"></a>
127 <FONT color="green">124</FONT> * &lt;code&gt;expected&lt;/code&gt; array if necessary to ensure that the sum of the<a name="line.124"></a>
128 <FONT color="green">125</FONT> * expected and observed counts are equal.&lt;/p&gt;<a name="line.125"></a>
129 <FONT color="green">126</FONT> *<a name="line.126"></a>
130 <FONT color="green">127</FONT> * @param observed array of observed frequency counts<a name="line.127"></a>
131 <FONT color="green">128</FONT> * @param expected array of expected frequency counts<a name="line.128"></a>
132 <FONT color="green">129</FONT> * @param alpha significance level of the test<a name="line.129"></a>
133 <FONT color="green">130</FONT> * @return true iff null hypothesis can be rejected with confidence<a name="line.130"></a>
134 <FONT color="green">131</FONT> * 1 - alpha<a name="line.131"></a>
135 <FONT color="green">132</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.132"></a>
136 <FONT color="green">133</FONT> * @throws MathException if an error occurs performing the test<a name="line.133"></a>
137 <FONT color="green">134</FONT> */<a name="line.134"></a>
138 <FONT color="green">135</FONT> public boolean chiSquareTest(double[] expected, long[] observed,<a name="line.135"></a>
139 <FONT color="green">136</FONT> double alpha) throws IllegalArgumentException, MathException {<a name="line.136"></a>
140 <FONT color="green">137</FONT> if ((alpha &lt;= 0) || (alpha &gt; 0.5)) {<a name="line.137"></a>
141 <FONT color="green">138</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.138"></a>
142 <FONT color="green">139</FONT> "out of bounds significance level {0}, must be between {1} and {2}",<a name="line.139"></a>
143 <FONT color="green">140</FONT> alpha, 0, 0.5);<a name="line.140"></a>
144 <FONT color="green">141</FONT> }<a name="line.141"></a>
145 <FONT color="green">142</FONT> return chiSquareTest(expected, observed) &lt; alpha;<a name="line.142"></a>
146 <FONT color="green">143</FONT> }<a name="line.143"></a>
147 <FONT color="green">144</FONT> <a name="line.144"></a>
148 <FONT color="green">145</FONT> /**<a name="line.145"></a>
149 <FONT color="green">146</FONT> * @param counts array representation of 2-way table<a name="line.146"></a>
150 <FONT color="green">147</FONT> * @return chi-square test statistic<a name="line.147"></a>
151 <FONT color="green">148</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.148"></a>
152 <FONT color="green">149</FONT> */<a name="line.149"></a>
153 <FONT color="green">150</FONT> public double chiSquare(long[][] counts) throws IllegalArgumentException {<a name="line.150"></a>
154 <FONT color="green">151</FONT> <a name="line.151"></a>
155 <FONT color="green">152</FONT> checkArray(counts);<a name="line.152"></a>
156 <FONT color="green">153</FONT> int nRows = counts.length;<a name="line.153"></a>
157 <FONT color="green">154</FONT> int nCols = counts[0].length;<a name="line.154"></a>
158 <FONT color="green">155</FONT> <a name="line.155"></a>
159 <FONT color="green">156</FONT> // compute row, column and total sums<a name="line.156"></a>
160 <FONT color="green">157</FONT> double[] rowSum = new double[nRows];<a name="line.157"></a>
161 <FONT color="green">158</FONT> double[] colSum = new double[nCols];<a name="line.158"></a>
162 <FONT color="green">159</FONT> double total = 0.0d;<a name="line.159"></a>
163 <FONT color="green">160</FONT> for (int row = 0; row &lt; nRows; row++) {<a name="line.160"></a>
164 <FONT color="green">161</FONT> for (int col = 0; col &lt; nCols; col++) {<a name="line.161"></a>
165 <FONT color="green">162</FONT> rowSum[row] += counts[row][col];<a name="line.162"></a>
166 <FONT color="green">163</FONT> colSum[col] += counts[row][col];<a name="line.163"></a>
167 <FONT color="green">164</FONT> total += counts[row][col];<a name="line.164"></a>
168 <FONT color="green">165</FONT> }<a name="line.165"></a>
169 <FONT color="green">166</FONT> }<a name="line.166"></a>
170 <FONT color="green">167</FONT> <a name="line.167"></a>
171 <FONT color="green">168</FONT> // compute expected counts and chi-square<a name="line.168"></a>
172 <FONT color="green">169</FONT> double sumSq = 0.0d;<a name="line.169"></a>
173 <FONT color="green">170</FONT> double expected = 0.0d;<a name="line.170"></a>
174 <FONT color="green">171</FONT> for (int row = 0; row &lt; nRows; row++) {<a name="line.171"></a>
175 <FONT color="green">172</FONT> for (int col = 0; col &lt; nCols; col++) {<a name="line.172"></a>
176 <FONT color="green">173</FONT> expected = (rowSum[row] * colSum[col]) / total;<a name="line.173"></a>
177 <FONT color="green">174</FONT> sumSq += ((counts[row][col] - expected) *<a name="line.174"></a>
178 <FONT color="green">175</FONT> (counts[row][col] - expected)) / expected;<a name="line.175"></a>
179 <FONT color="green">176</FONT> }<a name="line.176"></a>
180 <FONT color="green">177</FONT> }<a name="line.177"></a>
181 <FONT color="green">178</FONT> return sumSq;<a name="line.178"></a>
182 <FONT color="green">179</FONT> }<a name="line.179"></a>
183 <FONT color="green">180</FONT> <a name="line.180"></a>
184 <FONT color="green">181</FONT> /**<a name="line.181"></a>
185 <FONT color="green">182</FONT> * @param counts array representation of 2-way table<a name="line.182"></a>
186 <FONT color="green">183</FONT> * @return p-value<a name="line.183"></a>
187 <FONT color="green">184</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.184"></a>
188 <FONT color="green">185</FONT> * @throws MathException if an error occurs computing the p-value<a name="line.185"></a>
189 <FONT color="green">186</FONT> */<a name="line.186"></a>
190 <FONT color="green">187</FONT> public double chiSquareTest(long[][] counts)<a name="line.187"></a>
191 <FONT color="green">188</FONT> throws IllegalArgumentException, MathException {<a name="line.188"></a>
192 <FONT color="green">189</FONT> checkArray(counts);<a name="line.189"></a>
193 <FONT color="green">190</FONT> double df = ((double) counts.length -1) * ((double) counts[0].length - 1);<a name="line.190"></a>
194 <FONT color="green">191</FONT> distribution.setDegreesOfFreedom(df);<a name="line.191"></a>
195 <FONT color="green">192</FONT> return 1 - distribution.cumulativeProbability(chiSquare(counts));<a name="line.192"></a>
196 <FONT color="green">193</FONT> }<a name="line.193"></a>
197 <FONT color="green">194</FONT> <a name="line.194"></a>
198 <FONT color="green">195</FONT> /**<a name="line.195"></a>
199 <FONT color="green">196</FONT> * @param counts array representation of 2-way table<a name="line.196"></a>
200 <FONT color="green">197</FONT> * @param alpha significance level of the test<a name="line.197"></a>
201 <FONT color="green">198</FONT> * @return true iff null hypothesis can be rejected with confidence<a name="line.198"></a>
202 <FONT color="green">199</FONT> * 1 - alpha<a name="line.199"></a>
203 <FONT color="green">200</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.200"></a>
204 <FONT color="green">201</FONT> * @throws MathException if an error occurs performing the test<a name="line.201"></a>
205 <FONT color="green">202</FONT> */<a name="line.202"></a>
206 <FONT color="green">203</FONT> public boolean chiSquareTest(long[][] counts, double alpha)<a name="line.203"></a>
207 <FONT color="green">204</FONT> throws IllegalArgumentException, MathException {<a name="line.204"></a>
208 <FONT color="green">205</FONT> if ((alpha &lt;= 0) || (alpha &gt; 0.5)) {<a name="line.205"></a>
209 <FONT color="green">206</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.206"></a>
210 <FONT color="green">207</FONT> "out of bounds significance level {0}, must be between {1} and {2}",<a name="line.207"></a>
211 <FONT color="green">208</FONT> alpha, 0.0, 0.5);<a name="line.208"></a>
212 <FONT color="green">209</FONT> }<a name="line.209"></a>
213 <FONT color="green">210</FONT> return chiSquareTest(counts) &lt; alpha;<a name="line.210"></a>
214 <FONT color="green">211</FONT> }<a name="line.211"></a>
215 <FONT color="green">212</FONT> <a name="line.212"></a>
216 <FONT color="green">213</FONT> /**<a name="line.213"></a>
217 <FONT color="green">214</FONT> * @param observed1 array of observed frequency counts of the first data set<a name="line.214"></a>
218 <FONT color="green">215</FONT> * @param observed2 array of observed frequency counts of the second data set<a name="line.215"></a>
219 <FONT color="green">216</FONT> * @return chi-square test statistic<a name="line.216"></a>
220 <FONT color="green">217</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.217"></a>
221 <FONT color="green">218</FONT> * @since 1.2<a name="line.218"></a>
222 <FONT color="green">219</FONT> */<a name="line.219"></a>
223 <FONT color="green">220</FONT> public double chiSquareDataSetsComparison(long[] observed1, long[] observed2)<a name="line.220"></a>
224 <FONT color="green">221</FONT> throws IllegalArgumentException {<a name="line.221"></a>
225 <FONT color="green">222</FONT> <a name="line.222"></a>
226 <FONT color="green">223</FONT> // Make sure lengths are same<a name="line.223"></a>
227 <FONT color="green">224</FONT> if (observed1.length &lt; 2) {<a name="line.224"></a>
228 <FONT color="green">225</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.225"></a>
229 <FONT color="green">226</FONT> "observed array length = {0}, must be at least 2",<a name="line.226"></a>
230 <FONT color="green">227</FONT> observed1.length);<a name="line.227"></a>
231 <FONT color="green">228</FONT> }<a name="line.228"></a>
232 <FONT color="green">229</FONT> if (observed1.length != observed2.length) {<a name="line.229"></a>
233 <FONT color="green">230</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.230"></a>
234 <FONT color="green">231</FONT> "dimension mismatch {0} != {1}",<a name="line.231"></a>
235 <FONT color="green">232</FONT> observed1.length, observed2.length);<a name="line.232"></a>
236 <FONT color="green">233</FONT> }<a name="line.233"></a>
237 <FONT color="green">234</FONT> <a name="line.234"></a>
238 <FONT color="green">235</FONT> // Ensure non-negative counts<a name="line.235"></a>
239 <FONT color="green">236</FONT> checkNonNegative(observed1);<a name="line.236"></a>
240 <FONT color="green">237</FONT> checkNonNegative(observed2);<a name="line.237"></a>
241 <FONT color="green">238</FONT> <a name="line.238"></a>
242 <FONT color="green">239</FONT> // Compute and compare count sums<a name="line.239"></a>
243 <FONT color="green">240</FONT> long countSum1 = 0;<a name="line.240"></a>
244 <FONT color="green">241</FONT> long countSum2 = 0;<a name="line.241"></a>
245 <FONT color="green">242</FONT> boolean unequalCounts = false;<a name="line.242"></a>
246 <FONT color="green">243</FONT> double weight = 0.0;<a name="line.243"></a>
247 <FONT color="green">244</FONT> for (int i = 0; i &lt; observed1.length; i++) {<a name="line.244"></a>
248 <FONT color="green">245</FONT> countSum1 += observed1[i];<a name="line.245"></a>
249 <FONT color="green">246</FONT> countSum2 += observed2[i];<a name="line.246"></a>
250 <FONT color="green">247</FONT> }<a name="line.247"></a>
251 <FONT color="green">248</FONT> // Ensure neither sample is uniformly 0<a name="line.248"></a>
252 <FONT color="green">249</FONT> if (countSum1 == 0) {<a name="line.249"></a>
253 <FONT color="green">250</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.250"></a>
254 <FONT color="green">251</FONT> "observed counts are all 0 in first observed array");<a name="line.251"></a>
255 <FONT color="green">252</FONT> }<a name="line.252"></a>
256 <FONT color="green">253</FONT> if (countSum2 == 0) {<a name="line.253"></a>
257 <FONT color="green">254</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.254"></a>
258 <FONT color="green">255</FONT> "observed counts are all 0 in second observed array");<a name="line.255"></a>
259 <FONT color="green">256</FONT> }<a name="line.256"></a>
260 <FONT color="green">257</FONT> // Compare and compute weight only if different<a name="line.257"></a>
261 <FONT color="green">258</FONT> unequalCounts = countSum1 != countSum2;<a name="line.258"></a>
262 <FONT color="green">259</FONT> if (unequalCounts) {<a name="line.259"></a>
263 <FONT color="green">260</FONT> weight = Math.sqrt((double) countSum1 / (double) countSum2);<a name="line.260"></a>
264 <FONT color="green">261</FONT> }<a name="line.261"></a>
265 <FONT color="green">262</FONT> // Compute ChiSquare statistic<a name="line.262"></a>
266 <FONT color="green">263</FONT> double sumSq = 0.0d;<a name="line.263"></a>
267 <FONT color="green">264</FONT> double dev = 0.0d;<a name="line.264"></a>
268 <FONT color="green">265</FONT> double obs1 = 0.0d;<a name="line.265"></a>
269 <FONT color="green">266</FONT> double obs2 = 0.0d;<a name="line.266"></a>
270 <FONT color="green">267</FONT> for (int i = 0; i &lt; observed1.length; i++) {<a name="line.267"></a>
271 <FONT color="green">268</FONT> if (observed1[i] == 0 &amp;&amp; observed2[i] == 0) {<a name="line.268"></a>
272 <FONT color="green">269</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.269"></a>
273 <FONT color="green">270</FONT> "observed counts are both zero for entry {0}", i);<a name="line.270"></a>
274 <FONT color="green">271</FONT> } else {<a name="line.271"></a>
275 <FONT color="green">272</FONT> obs1 = observed1[i];<a name="line.272"></a>
276 <FONT color="green">273</FONT> obs2 = observed2[i];<a name="line.273"></a>
277 <FONT color="green">274</FONT> if (unequalCounts) { // apply weights<a name="line.274"></a>
278 <FONT color="green">275</FONT> dev = obs1/weight - obs2 * weight;<a name="line.275"></a>
279 <FONT color="green">276</FONT> } else {<a name="line.276"></a>
280 <FONT color="green">277</FONT> dev = obs1 - obs2;<a name="line.277"></a>
281 <FONT color="green">278</FONT> }<a name="line.278"></a>
282 <FONT color="green">279</FONT> sumSq += (dev * dev) / (obs1 + obs2);<a name="line.279"></a>
283 <FONT color="green">280</FONT> }<a name="line.280"></a>
284 <FONT color="green">281</FONT> }<a name="line.281"></a>
285 <FONT color="green">282</FONT> return sumSq;<a name="line.282"></a>
286 <FONT color="green">283</FONT> }<a name="line.283"></a>
287 <FONT color="green">284</FONT> <a name="line.284"></a>
288 <FONT color="green">285</FONT> /**<a name="line.285"></a>
289 <FONT color="green">286</FONT> * @param observed1 array of observed frequency counts of the first data set<a name="line.286"></a>
290 <FONT color="green">287</FONT> * @param observed2 array of observed frequency counts of the second data set<a name="line.287"></a>
291 <FONT color="green">288</FONT> * @return p-value<a name="line.288"></a>
292 <FONT color="green">289</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.289"></a>
293 <FONT color="green">290</FONT> * @throws MathException if an error occurs computing the p-value<a name="line.290"></a>
294 <FONT color="green">291</FONT> * @since 1.2<a name="line.291"></a>
295 <FONT color="green">292</FONT> */<a name="line.292"></a>
296 <FONT color="green">293</FONT> public double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2)<a name="line.293"></a>
297 <FONT color="green">294</FONT> throws IllegalArgumentException, MathException {<a name="line.294"></a>
298 <FONT color="green">295</FONT> distribution.setDegreesOfFreedom((double) observed1.length - 1);<a name="line.295"></a>
299 <FONT color="green">296</FONT> return 1 - distribution.cumulativeProbability(<a name="line.296"></a>
300 <FONT color="green">297</FONT> chiSquareDataSetsComparison(observed1, observed2));<a name="line.297"></a>
301 <FONT color="green">298</FONT> }<a name="line.298"></a>
302 <FONT color="green">299</FONT> <a name="line.299"></a>
303 <FONT color="green">300</FONT> /**<a name="line.300"></a>
304 <FONT color="green">301</FONT> * @param observed1 array of observed frequency counts of the first data set<a name="line.301"></a>
305 <FONT color="green">302</FONT> * @param observed2 array of observed frequency counts of the second data set<a name="line.302"></a>
306 <FONT color="green">303</FONT> * @param alpha significance level of the test<a name="line.303"></a>
307 <FONT color="green">304</FONT> * @return true iff null hypothesis can be rejected with confidence<a name="line.304"></a>
308 <FONT color="green">305</FONT> * 1 - alpha<a name="line.305"></a>
309 <FONT color="green">306</FONT> * @throws IllegalArgumentException if preconditions are not met<a name="line.306"></a>
310 <FONT color="green">307</FONT> * @throws MathException if an error occurs performing the test<a name="line.307"></a>
311 <FONT color="green">308</FONT> * @since 1.2<a name="line.308"></a>
312 <FONT color="green">309</FONT> */<a name="line.309"></a>
313 <FONT color="green">310</FONT> public boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2,<a name="line.310"></a>
314 <FONT color="green">311</FONT> double alpha) throws IllegalArgumentException, MathException {<a name="line.311"></a>
315 <FONT color="green">312</FONT> if ((alpha &lt;= 0) || (alpha &gt; 0.5)) {<a name="line.312"></a>
316 <FONT color="green">313</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.313"></a>
317 <FONT color="green">314</FONT> "out of bounds significance level {0}, must be between {1} and {2}",<a name="line.314"></a>
318 <FONT color="green">315</FONT> alpha, 0.0, 0.5);<a name="line.315"></a>
319 <FONT color="green">316</FONT> }<a name="line.316"></a>
320 <FONT color="green">317</FONT> return chiSquareTestDataSetsComparison(observed1, observed2) &lt; alpha;<a name="line.317"></a>
321 <FONT color="green">318</FONT> }<a name="line.318"></a>
322 <FONT color="green">319</FONT> <a name="line.319"></a>
323 <FONT color="green">320</FONT> /**<a name="line.320"></a>
324 <FONT color="green">321</FONT> * Checks to make sure that the input long[][] array is rectangular,<a name="line.321"></a>
325 <FONT color="green">322</FONT> * has at least 2 rows and 2 columns, and has all non-negative entries,<a name="line.322"></a>
326 <FONT color="green">323</FONT> * throwing IllegalArgumentException if any of these checks fail.<a name="line.323"></a>
327 <FONT color="green">324</FONT> *<a name="line.324"></a>
328 <FONT color="green">325</FONT> * @param in input 2-way table to check<a name="line.325"></a>
329 <FONT color="green">326</FONT> * @throws IllegalArgumentException if the array is not valid<a name="line.326"></a>
330 <FONT color="green">327</FONT> */<a name="line.327"></a>
331 <FONT color="green">328</FONT> private void checkArray(long[][] in) throws IllegalArgumentException {<a name="line.328"></a>
332 <FONT color="green">329</FONT> <a name="line.329"></a>
333 <FONT color="green">330</FONT> if (in.length &lt; 2) {<a name="line.330"></a>
334 <FONT color="green">331</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.331"></a>
335 <FONT color="green">332</FONT> "invalid row dimension: {0} (must be at least 2)",<a name="line.332"></a>
336 <FONT color="green">333</FONT> in.length);<a name="line.333"></a>
337 <FONT color="green">334</FONT> }<a name="line.334"></a>
338 <FONT color="green">335</FONT> <a name="line.335"></a>
339 <FONT color="green">336</FONT> if (in[0].length &lt; 2) {<a name="line.336"></a>
340 <FONT color="green">337</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.337"></a>
341 <FONT color="green">338</FONT> "invalid column dimension: {0} (must be at least 2)",<a name="line.338"></a>
342 <FONT color="green">339</FONT> in[0].length);<a name="line.339"></a>
343 <FONT color="green">340</FONT> }<a name="line.340"></a>
344 <FONT color="green">341</FONT> <a name="line.341"></a>
345 <FONT color="green">342</FONT> checkRectangular(in);<a name="line.342"></a>
346 <FONT color="green">343</FONT> checkNonNegative(in);<a name="line.343"></a>
347 <FONT color="green">344</FONT> <a name="line.344"></a>
348 <FONT color="green">345</FONT> }<a name="line.345"></a>
349 <FONT color="green">346</FONT> <a name="line.346"></a>
350 <FONT color="green">347</FONT> //--------------------- Private array methods -- should find a utility home for these<a name="line.347"></a>
351 <FONT color="green">348</FONT> <a name="line.348"></a>
352 <FONT color="green">349</FONT> /**<a name="line.349"></a>
353 <FONT color="green">350</FONT> * Throws IllegalArgumentException if the input array is not rectangular.<a name="line.350"></a>
354 <FONT color="green">351</FONT> *<a name="line.351"></a>
355 <FONT color="green">352</FONT> * @param in array to be tested<a name="line.352"></a>
356 <FONT color="green">353</FONT> * @throws NullPointerException if input array is null<a name="line.353"></a>
357 <FONT color="green">354</FONT> * @throws IllegalArgumentException if input array is not rectangular<a name="line.354"></a>
358 <FONT color="green">355</FONT> */<a name="line.355"></a>
359 <FONT color="green">356</FONT> private void checkRectangular(long[][] in) {<a name="line.356"></a>
360 <FONT color="green">357</FONT> for (int i = 1; i &lt; in.length; i++) {<a name="line.357"></a>
361 <FONT color="green">358</FONT> if (in[i].length != in[0].length) {<a name="line.358"></a>
362 <FONT color="green">359</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.359"></a>
363 <FONT color="green">360</FONT> "some rows have length {0} while others have length {1}",<a name="line.360"></a>
364 <FONT color="green">361</FONT> in[i].length, in[0].length);<a name="line.361"></a>
365 <FONT color="green">362</FONT> }<a name="line.362"></a>
366 <FONT color="green">363</FONT> }<a name="line.363"></a>
367 <FONT color="green">364</FONT> }<a name="line.364"></a>
368 <FONT color="green">365</FONT> <a name="line.365"></a>
369 <FONT color="green">366</FONT> /**<a name="line.366"></a>
370 <FONT color="green">367</FONT> * Check all entries of the input array are &gt; 0.<a name="line.367"></a>
371 <FONT color="green">368</FONT> *<a name="line.368"></a>
372 <FONT color="green">369</FONT> * @param in array to be tested<a name="line.369"></a>
373 <FONT color="green">370</FONT> * @exception IllegalArgumentException if one entry is not positive<a name="line.370"></a>
374 <FONT color="green">371</FONT> */<a name="line.371"></a>
375 <FONT color="green">372</FONT> private void checkPositive(double[] in) throws IllegalArgumentException {<a name="line.372"></a>
376 <FONT color="green">373</FONT> for (int i = 0; i &lt; in.length; i++) {<a name="line.373"></a>
377 <FONT color="green">374</FONT> if (in[i] &lt;= 0) {<a name="line.374"></a>
378 <FONT color="green">375</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.375"></a>
379 <FONT color="green">376</FONT> "element {0} is not positive: {1}",<a name="line.376"></a>
380 <FONT color="green">377</FONT> i, in[i]);<a name="line.377"></a>
381 <FONT color="green">378</FONT> }<a name="line.378"></a>
382 <FONT color="green">379</FONT> }<a name="line.379"></a>
383 <FONT color="green">380</FONT> }<a name="line.380"></a>
384 <FONT color="green">381</FONT> <a name="line.381"></a>
385 <FONT color="green">382</FONT> /**<a name="line.382"></a>
386 <FONT color="green">383</FONT> * Check all entries of the input array are &gt;= 0.<a name="line.383"></a>
387 <FONT color="green">384</FONT> *<a name="line.384"></a>
388 <FONT color="green">385</FONT> * @param in array to be tested<a name="line.385"></a>
389 <FONT color="green">386</FONT> * @exception IllegalArgumentException if one entry is negative<a name="line.386"></a>
390 <FONT color="green">387</FONT> */<a name="line.387"></a>
391 <FONT color="green">388</FONT> private void checkNonNegative(long[] in) throws IllegalArgumentException {<a name="line.388"></a>
392 <FONT color="green">389</FONT> for (int i = 0; i &lt; in.length; i++) {<a name="line.389"></a>
393 <FONT color="green">390</FONT> if (in[i] &lt; 0) {<a name="line.390"></a>
394 <FONT color="green">391</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.391"></a>
395 <FONT color="green">392</FONT> "element {0} is negative: {1}",<a name="line.392"></a>
396 <FONT color="green">393</FONT> i, in[i]);<a name="line.393"></a>
397 <FONT color="green">394</FONT> }<a name="line.394"></a>
398 <FONT color="green">395</FONT> }<a name="line.395"></a>
399 <FONT color="green">396</FONT> }<a name="line.396"></a>
400 <FONT color="green">397</FONT> <a name="line.397"></a>
401 <FONT color="green">398</FONT> /**<a name="line.398"></a>
402 <FONT color="green">399</FONT> * Check all entries of the input array are &gt;= 0.<a name="line.399"></a>
403 <FONT color="green">400</FONT> *<a name="line.400"></a>
404 <FONT color="green">401</FONT> * @param in array to be tested<a name="line.401"></a>
405 <FONT color="green">402</FONT> * @exception IllegalArgumentException if one entry is negative<a name="line.402"></a>
406 <FONT color="green">403</FONT> */<a name="line.403"></a>
407 <FONT color="green">404</FONT> private void checkNonNegative(long[][] in) throws IllegalArgumentException {<a name="line.404"></a>
408 <FONT color="green">405</FONT> for (int i = 0; i &lt; in.length; i ++) {<a name="line.405"></a>
409 <FONT color="green">406</FONT> for (int j = 0; j &lt; in[i].length; j++) {<a name="line.406"></a>
410 <FONT color="green">407</FONT> if (in[i][j] &lt; 0) {<a name="line.407"></a>
411 <FONT color="green">408</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.408"></a>
412 <FONT color="green">409</FONT> "element ({0}, {1}) is negative: {2}",<a name="line.409"></a>
413 <FONT color="green">410</FONT> i, j, in[i][j]);<a name="line.410"></a>
414 <FONT color="green">411</FONT> }<a name="line.411"></a>
415 <FONT color="green">412</FONT> }<a name="line.412"></a>
416 <FONT color="green">413</FONT> }<a name="line.413"></a>
417 <FONT color="green">414</FONT> }<a name="line.414"></a>
418 <FONT color="green">415</FONT> <a name="line.415"></a>
419 <FONT color="green">416</FONT> /**<a name="line.416"></a>
420 <FONT color="green">417</FONT> * Modify the distribution used to compute inference statistics.<a name="line.417"></a>
421 <FONT color="green">418</FONT> *<a name="line.418"></a>
422 <FONT color="green">419</FONT> * @param value<a name="line.419"></a>
423 <FONT color="green">420</FONT> * the new distribution<a name="line.420"></a>
424 <FONT color="green">421</FONT> * @since 1.2<a name="line.421"></a>
425 <FONT color="green">422</FONT> */<a name="line.422"></a>
426 <FONT color="green">423</FONT> public void setDistribution(ChiSquaredDistribution value) {<a name="line.423"></a>
427 <FONT color="green">424</FONT> distribution = value;<a name="line.424"></a>
428 <FONT color="green">425</FONT> }<a name="line.425"></a>
429 <FONT color="green">426</FONT> }<a name="line.426"></a>
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490 </PRE>
491 </BODY>
492 </HTML>