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    import org.apache.commons.math.TestUtils;
020    import org.apache.commons.math.stat.descriptive.moment.SecondMoment;
021    
022    /**
023     * Test cases for {@link StorelessUnivariateStatistic} classes.
024     * @version $Revision: 780541 $ $Date: 2009-05-31 20:47:02 -0400 (Sun, 31 May 2009) $
025     */
026    public abstract class StorelessUnivariateStatisticAbstractTest
027        extends UnivariateStatisticAbstractTest {
028    
029        public StorelessUnivariateStatisticAbstractTest(String name) {
030            super(name);
031        }
032        
033        /** Small sample arrays */
034        protected double[][] smallSamples = {{}, {1}, {1,2}, {1,2,3}, {1,2,3,4}};
035    
036        /** Return a new instance of the statistic */
037        @Override
038        public abstract UnivariateStatistic getUnivariateStatistic();
039    
040        /**Expected value for  the testArray defined in UnivariateStatisticAbstractTest */
041        @Override
042        public abstract double expectedValue();
043        
044        /** 
045         *  Verifies that increment() and incrementAll work properly. 
046         */
047        public void testIncrementation() throws Exception {
048    
049            StorelessUnivariateStatistic statistic =
050                (StorelessUnivariateStatistic) getUnivariateStatistic();
051            
052            // Add testArray one value at a time and check result
053            for (int i = 0; i < testArray.length; i++) {
054                statistic.increment(testArray[i]);
055            }
056            
057            assertEquals(expectedValue(), statistic.getResult(), getTolerance());
058            assertEquals(testArray.length, statistic.getN());
059    
060            statistic.clear();
061            
062            // Add testArray all at once and check again
063            statistic.incrementAll(testArray);
064            assertEquals(expectedValue(), statistic.getResult(), getTolerance());
065            assertEquals(testArray.length, statistic.getN());
066            
067            statistic.clear();
068            
069            // Cleared
070            assertTrue(Double.isNaN(statistic.getResult()));
071            assertEquals(0, statistic.getN());
072    
073        }
074    
075        public void testSerialization() throws Exception {
076    
077            StorelessUnivariateStatistic statistic =
078                (StorelessUnivariateStatistic) getUnivariateStatistic();
079            
080            TestUtils.checkSerializedEquality(statistic);
081    
082            statistic.clear();
083    
084            for (int i = 0; i < testArray.length; i++) {
085                statistic.increment(testArray[i]);
086                if(i % 5 == 0)
087                    statistic = (StorelessUnivariateStatistic)TestUtils.serializeAndRecover(statistic); 
088            }
089            
090            TestUtils.checkSerializedEquality(statistic);
091            
092            assertEquals(expectedValue(), statistic.getResult(), getTolerance());
093    
094            statistic.clear();
095    
096            assertTrue(Double.isNaN(statistic.getResult()));
097    
098        }
099        
100        public void testEqualsAndHashCode() {
101            StorelessUnivariateStatistic statistic =
102                (StorelessUnivariateStatistic) getUnivariateStatistic();
103            StorelessUnivariateStatistic statistic2 = null;
104            
105            assertTrue("non-null, compared to null", !statistic.equals(statistic2));
106            assertTrue("reflexive, non-null", statistic.equals(statistic));
107            
108            int emptyHash = statistic.hashCode();
109            statistic2 = (StorelessUnivariateStatistic) getUnivariateStatistic();
110            assertTrue("empty stats should be equal", statistic.equals(statistic2));
111            assertEquals("empty stats should have the same hashcode", 
112                    emptyHash, statistic2.hashCode());
113            
114            statistic.increment(1d);
115            assertTrue("reflexive, non-empty", statistic.equals(statistic));
116            assertTrue("non-empty, compared to empty", !statistic.equals(statistic2));
117            assertTrue("non-empty, compared to empty", !statistic2.equals(statistic));
118            assertTrue("non-empty stat should have different hashcode from empty stat",
119                    statistic.hashCode() != emptyHash);
120            
121            statistic2.increment(1d);
122            assertTrue("stats with same data should be equal", statistic.equals(statistic2));
123            assertEquals("stats with same data should have the same hashcode", 
124                    statistic.hashCode(), statistic2.hashCode());
125            
126            statistic.increment(Double.POSITIVE_INFINITY);
127            assertTrue("stats with different n's should not be equal", !statistic2.equals(statistic));
128            assertTrue("stats with different n's should have different hashcodes",
129                    statistic.hashCode() != statistic2.hashCode());
130            
131            statistic2.increment(Double.POSITIVE_INFINITY);
132            assertTrue("stats with same data should be equal", statistic.equals(statistic2));
133            assertEquals("stats with same data should have the same hashcode", 
134                    statistic.hashCode(), statistic2.hashCode()); 
135            
136            statistic.clear();
137            statistic2.clear();
138            assertTrue("cleared stats should be equal", statistic.equals(statistic2));
139            assertEquals("cleared stats should have thashcode of empty stat", 
140                    emptyHash, statistic2.hashCode());
141            assertEquals("cleared stats should have thashcode of empty stat", 
142                    emptyHash, statistic.hashCode());
143            
144        }
145        
146        public void testMomentSmallSamples() {
147            UnivariateStatistic stat = getUnivariateStatistic();
148            if (stat instanceof SecondMoment) {
149                SecondMoment moment = (SecondMoment) getUnivariateStatistic();
150                assertTrue(Double.isNaN(moment.getResult()));
151                moment.increment(1d);
152                assertEquals(0d, moment.getResult(), 0);
153            }
154        }
155        
156        /** 
157         * Make sure that evaluate(double[]) and inrementAll(double[]), 
158         * getResult() give same results.
159         */
160        public void testConsistency() {
161            StorelessUnivariateStatistic stat = (StorelessUnivariateStatistic) getUnivariateStatistic();
162            stat.incrementAll(testArray);
163            assertEquals(stat.getResult(), stat.evaluate(testArray), getTolerance());
164            for (int i = 0; i < smallSamples.length; i++) {
165                stat.clear();
166                for (int j =0; j < smallSamples[i].length; j++) {
167                    stat.increment(smallSamples[i][j]);
168                }
169                TestUtils.assertEquals(stat.getResult(), stat.evaluate(smallSamples[i]), getTolerance());
170            }
171        }
172        
173        /**
174         * Verifies that copied statistics remain equal to originals when
175         * incremented the same way.
176         *
177         */
178        public void testCopyConsistency() {
179            
180            StorelessUnivariateStatistic master =
181                (StorelessUnivariateStatistic) getUnivariateStatistic();
182            
183            StorelessUnivariateStatistic replica = null;
184            
185            // Randomly select a portion of testArray to load first
186            long index = Math.round((Math.random()) * testArray.length);
187            
188            // Put first half in master and copy master to replica
189            master.incrementAll(testArray, 0, (int) index);
190            replica = master.copy();
191            
192            // Check same
193            assertTrue(replica.equals(master));
194            assertTrue(master.equals(replica));
195            
196            // Now add second part to both and check again
197            master.incrementAll(testArray, 
198                    (int) index, (int) (testArray.length - index));
199            replica.incrementAll(testArray, 
200                    (int) index, (int) (testArray.length - index));
201            assertTrue(replica.equals(master));
202            assertTrue(master.equals(replica));
203        }
204        
205        public void testSerial() {
206            StorelessUnivariateStatistic s =
207                (StorelessUnivariateStatistic) getUnivariateStatistic();
208            assertEquals(s, TestUtils.serializeAndRecover(s));
209        }
210    }