001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.math.stat.descriptive; 018 019 020 import junit.framework.Test; 021 import junit.framework.TestCase; 022 import junit.framework.TestSuite; 023 024 import org.apache.commons.math.TestUtils; 025 import org.apache.commons.math.stat.descriptive.moment.Mean; 026 import org.apache.commons.math.stat.descriptive.summary.Sum; 027 /** 028 * Test cases for the {@link SummaryStatistics} class. 029 * 030 * @version $Revision: 720030 $ $Date: 2008-11-23 13:47:50 -0500 (Sun, 23 Nov 2008) $ 031 */ 032 033 public class SummaryStatisticsTest extends TestCase { 034 035 private double one = 1; 036 private float twoF = 2; 037 private long twoL = 2; 038 private int three = 3; 039 private double mean = 2; 040 private double sumSq = 18; 041 private double sum = 8; 042 private double var = 0.666666666666666666667; 043 private double std = Math.sqrt(var); 044 private double n = 4; 045 private double min = 1; 046 private double max = 3; 047 private double tolerance = 10E-15; 048 049 public static Test suite() { 050 TestSuite suite = new TestSuite(SummaryStatisticsTest.class); 051 suite.setName("SummaryStatistics tests"); 052 return suite; 053 } 054 055 public SummaryStatisticsTest(String name) { 056 super(name); 057 } 058 059 protected SummaryStatistics createSummaryStatistics() { 060 return new SummaryStatistics(); 061 } 062 063 /** test stats */ 064 public void testStats() { 065 SummaryStatistics u = createSummaryStatistics(); 066 assertEquals("total count",0,u.getN(),tolerance); 067 u.addValue(one); 068 u.addValue(twoF); 069 u.addValue(twoL); 070 u.addValue(three); 071 assertEquals("N",n,u.getN(),tolerance); 072 assertEquals("sum",sum,u.getSum(),tolerance); 073 assertEquals("sumsq",sumSq,u.getSumsq(),tolerance); 074 assertEquals("var",var,u.getVariance(),tolerance); 075 assertEquals("std",std,u.getStandardDeviation(),tolerance); 076 assertEquals("mean",mean,u.getMean(),tolerance); 077 assertEquals("min",min,u.getMin(),tolerance); 078 assertEquals("max",max,u.getMax(),tolerance); 079 u.clear(); 080 assertEquals("total count",0,u.getN(),tolerance); 081 } 082 083 public void testN0andN1Conditions() throws Exception { 084 SummaryStatistics u = createSummaryStatistics(); 085 assertTrue("Mean of n = 0 set should be NaN", 086 Double.isNaN( u.getMean() ) ); 087 assertTrue("Standard Deviation of n = 0 set should be NaN", 088 Double.isNaN( u.getStandardDeviation() ) ); 089 assertTrue("Variance of n = 0 set should be NaN", 090 Double.isNaN(u.getVariance() ) ); 091 092 /* n=1 */ 093 u.addValue(one); 094 assertTrue("mean should be one (n = 1)", 095 u.getMean() == one); 096 assertTrue("geometric should be one (n = 1) instead it is " + u.getGeometricMean(), 097 u.getGeometricMean() == one); 098 assertTrue("Std should be zero (n = 1)", 099 u.getStandardDeviation() == 0.0); 100 assertTrue("variance should be zero (n = 1)", 101 u.getVariance() == 0.0); 102 103 /* n=2 */ 104 u.addValue(twoF); 105 assertTrue("Std should not be zero (n = 2)", 106 u.getStandardDeviation() != 0.0); 107 assertTrue("variance should not be zero (n = 2)", 108 u.getVariance() != 0.0); 109 110 } 111 112 public void testProductAndGeometricMean() throws Exception { 113 SummaryStatistics u = createSummaryStatistics(); 114 u.addValue( 1.0 ); 115 u.addValue( 2.0 ); 116 u.addValue( 3.0 ); 117 u.addValue( 4.0 ); 118 119 assertEquals( "Geometric mean not expected", 2.213364, 120 u.getGeometricMean(), 0.00001 ); 121 } 122 123 public void testNaNContracts() { 124 SummaryStatistics u = createSummaryStatistics(); 125 assertTrue("mean not NaN",Double.isNaN(u.getMean())); 126 assertTrue("min not NaN",Double.isNaN(u.getMin())); 127 assertTrue("std dev not NaN",Double.isNaN(u.getStandardDeviation())); 128 assertTrue("var not NaN",Double.isNaN(u.getVariance())); 129 assertTrue("geom mean not NaN",Double.isNaN(u.getGeometricMean())); 130 131 u.addValue(1.0); 132 133 assertEquals( "mean not expected", 1.0, 134 u.getMean(), Double.MIN_VALUE); 135 assertEquals( "variance not expected", 0.0, 136 u.getVariance(), Double.MIN_VALUE); 137 assertEquals( "geometric mean not expected", 1.0, 138 u.getGeometricMean(), Double.MIN_VALUE); 139 140 u.addValue(-1.0); 141 142 assertTrue("geom mean not NaN",Double.isNaN(u.getGeometricMean())); 143 144 u.addValue(0.0); 145 146 assertTrue("geom mean not NaN",Double.isNaN(u.getGeometricMean())); 147 148 //FiXME: test all other NaN contract specs 149 } 150 151 public void testGetSummary() { 152 SummaryStatistics u = createSummaryStatistics(); 153 StatisticalSummary summary = u.getSummary(); 154 verifySummary(u, summary); 155 u.addValue(1d); 156 summary = u.getSummary(); 157 verifySummary(u, summary); 158 u.addValue(2d); 159 summary = u.getSummary(); 160 verifySummary(u, summary); 161 u.addValue(2d); 162 summary = u.getSummary(); 163 verifySummary(u, summary); 164 } 165 166 public void testSerialization() { 167 SummaryStatistics u = createSummaryStatistics(); 168 // Empty test 169 TestUtils.checkSerializedEquality(u); 170 SummaryStatistics s = (SummaryStatistics) TestUtils.serializeAndRecover(u); 171 StatisticalSummary summary = s.getSummary(); 172 verifySummary(u, summary); 173 174 // Add some data 175 u.addValue(2d); 176 u.addValue(1d); 177 u.addValue(3d); 178 u.addValue(4d); 179 u.addValue(5d); 180 181 // Test again 182 TestUtils.checkSerializedEquality(u); 183 s = (SummaryStatistics) TestUtils.serializeAndRecover(u); 184 summary = s.getSummary(); 185 verifySummary(u, summary); 186 187 } 188 189 public void testEqualsAndHashCode() { 190 SummaryStatistics u = createSummaryStatistics(); 191 SummaryStatistics t = null; 192 int emptyHash = u.hashCode(); 193 assertTrue("reflexive", u.equals(u)); 194 assertFalse("non-null compared to null", u.equals(t)); 195 assertFalse("wrong type", u.equals(Double.valueOf(0))); 196 t = createSummaryStatistics(); 197 assertTrue("empty instances should be equal", t.equals(u)); 198 assertTrue("empty instances should be equal", u.equals(t)); 199 assertEquals("empty hash code", emptyHash, t.hashCode()); 200 201 // Add some data to u 202 u.addValue(2d); 203 u.addValue(1d); 204 u.addValue(3d); 205 u.addValue(4d); 206 assertFalse("different n's should make instances not equal", t.equals(u)); 207 assertFalse("different n's should make instances not equal", u.equals(t)); 208 assertTrue("different n's should make hashcodes different", 209 u.hashCode() != t.hashCode()); 210 211 //Add data in same order to t 212 t.addValue(2d); 213 t.addValue(1d); 214 t.addValue(3d); 215 t.addValue(4d); 216 assertTrue("summaries based on same data should be equal", t.equals(u)); 217 assertTrue("summaries based on same data should be equal", u.equals(t)); 218 assertEquals("summaries based on same data should have same hashcodes", 219 u.hashCode(), t.hashCode()); 220 221 // Clear and make sure summaries are indistinguishable from empty summary 222 u.clear(); 223 t.clear(); 224 assertTrue("empty instances should be equal", t.equals(u)); 225 assertTrue("empty instances should be equal", u.equals(t)); 226 assertEquals("empty hash code", emptyHash, t.hashCode()); 227 assertEquals("empty hash code", emptyHash, u.hashCode()); 228 } 229 230 public void testCopy() throws Exception { 231 SummaryStatistics u = createSummaryStatistics(); 232 u.addValue(2d); 233 u.addValue(1d); 234 u.addValue(3d); 235 u.addValue(4d); 236 SummaryStatistics v = new SummaryStatistics(u); 237 assertEquals(u, v); 238 assertEquals(v, u); 239 assertTrue(v.geoMean == v.getGeoMeanImpl()); 240 assertTrue(v.mean == v.getMeanImpl()); 241 assertTrue(v.min == v.getMinImpl()); 242 assertTrue(v.max == v.getMaxImpl()); 243 assertTrue(v.sum == v.getSumImpl()); 244 assertTrue(v.sumsq == v.getSumsqImpl()); 245 assertTrue(v.sumLog == v.getSumLogImpl()); 246 assertTrue(v.variance == v.getVarianceImpl()); 247 248 // Make sure both behave the same with additional values added 249 u.addValue(7d); 250 u.addValue(9d); 251 u.addValue(11d); 252 u.addValue(23d); 253 v.addValue(7d); 254 v.addValue(9d); 255 v.addValue(11d); 256 v.addValue(23d); 257 assertEquals(u, v); 258 assertEquals(v, u); 259 260 // Check implementation pointers are preserved 261 u.clear(); 262 u.setSumImpl(new Sum()); 263 SummaryStatistics.copy(u,v); 264 assertEquals(u.sum, v.sum); 265 assertEquals(u.getSumImpl(), v.getSumImpl()); 266 267 } 268 269 private void verifySummary(SummaryStatistics u, StatisticalSummary s) { 270 assertEquals("N",s.getN(),u.getN()); 271 TestUtils.assertEquals("sum",s.getSum(),u.getSum(),tolerance); 272 TestUtils.assertEquals("var",s.getVariance(),u.getVariance(),tolerance); 273 TestUtils.assertEquals("std",s.getStandardDeviation(),u.getStandardDeviation(),tolerance); 274 TestUtils.assertEquals("mean",s.getMean(),u.getMean(),tolerance); 275 TestUtils.assertEquals("min",s.getMin(),u.getMin(),tolerance); 276 TestUtils.assertEquals("max",s.getMax(),u.getMax(),tolerance); 277 } 278 279 public void testSetterInjection() throws Exception { 280 SummaryStatistics u = createSummaryStatistics(); 281 u.setMeanImpl(new Sum()); 282 u.setSumLogImpl(new Sum()); 283 u.addValue(1); 284 u.addValue(3); 285 assertEquals(4, u.getMean(), 1E-14); 286 assertEquals(4, u.getSumOfLogs(), 1E-14); 287 assertEquals(Math.exp(2), u.getGeometricMean(), 1E-14); 288 u.clear(); 289 u.addValue(1); 290 u.addValue(2); 291 assertEquals(3, u.getMean(), 1E-14); 292 u.clear(); 293 u.setMeanImpl(new Mean()); // OK after clear 294 } 295 296 public void testSetterIllegalState() throws Exception { 297 SummaryStatistics u = createSummaryStatistics(); 298 u.addValue(1); 299 u.addValue(3); 300 try { 301 u.setMeanImpl(new Sum()); 302 fail("Expecting IllegalStateException"); 303 } catch (IllegalStateException ex) { 304 // expected 305 } 306 } 307 }