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 java.io.Serializable;
020    import java.util.ArrayList;
021    import java.util.List;
022    
023    import org.apache.commons.math.util.NumberTransformer;
024    import org.apache.commons.math.util.TransformerMap;
025    import junit.framework.Test;
026    import junit.framework.TestCase;
027    import junit.framework.TestSuite;
028    
029    /**
030     * Test cases for the {@link ListUnivariateImpl} class.
031     *
032     * @version $Revision: 777530 $ $Date: 2009-05-22 10:04:56 -0400 (Fri, 22 May 2009) $
033     */
034    
035    public final class MixedListUnivariateImplTest extends TestCase {
036        private double one = 1;
037        private float two = 2;
038        private int three = 3;
039    
040        private double mean = 2;
041        private double sumSq = 18;
042        private double sum = 8;
043        private double var = 0.666666666666666666667;
044        private double std = Math.sqrt(var);
045        private double n = 4;
046        private double min = 1;
047        private double max = 3;
048        private double tolerance = 10E-15;
049    
050        private TransformerMap transformers = new TransformerMap();
051        
052        public MixedListUnivariateImplTest(String name) {
053            super(name);
054            transformers = new TransformerMap();
055    
056            transformers.putTransformer(Foo.class, new FooTransformer());
057    
058            transformers.putTransformer(Bar.class, new BarTransformer());
059    
060        }
061    
062        public static Test suite() {
063            TestSuite suite = new TestSuite(MixedListUnivariateImplTest.class);
064            suite.setName("Mixed List Tests");
065            return suite;
066        }
067    
068        /** test stats */
069        public void testStats() {
070            List<Object> externalList = new ArrayList<Object>();
071    
072            DescriptiveStatistics u = new ListUnivariateImpl(externalList,transformers);
073    
074            assertEquals("total count", 0, u.getN(), tolerance);
075            u.addValue(one);
076            u.addValue(two);
077            u.addValue(two);
078            u.addValue(three);
079            assertEquals("N", n, u.getN(), tolerance);
080            assertEquals("sum", sum, u.getSum(), tolerance);
081            assertEquals("sumsq", sumSq, u.getSumsq(), tolerance);
082            assertEquals("var", var, u.getVariance(), tolerance);
083            assertEquals("std", std, u.getStandardDeviation(), tolerance);
084            assertEquals("mean", mean, u.getMean(), tolerance);
085            assertEquals("min", min, u.getMin(), tolerance);
086            assertEquals("max", max, u.getMax(), tolerance);
087            u.clear();
088            assertEquals("total count", 0, u.getN(), tolerance);
089        }
090    
091        public void testN0andN1Conditions() throws Exception {
092            DescriptiveStatistics u = new ListUnivariateImpl(new ArrayList<Object>(),transformers);
093    
094            assertTrue(
095                "Mean of n = 0 set should be NaN",
096                Double.isNaN(u.getMean()));
097            assertTrue(
098                "Standard Deviation of n = 0 set should be NaN",
099                Double.isNaN(u.getStandardDeviation()));
100            assertTrue(
101                "Variance of n = 0 set should be NaN",
102                Double.isNaN(u.getVariance()));
103    
104            u.addValue(one);
105    
106            assertTrue(
107                "Mean of n = 1 set should be value of single item n1, instead it is " + u.getMean() ,
108                u.getMean() == one);
109                
110            assertTrue(
111                "StdDev of n = 1 set should be zero, instead it is: "
112                    + u.getStandardDeviation(),
113                u.getStandardDeviation() == 0);
114            assertTrue(
115                "Variance of n = 1 set should be zero",
116                u.getVariance() == 0);
117        }
118    
119        public void testSkewAndKurtosis() {
120            ListUnivariateImpl u =
121                new ListUnivariateImpl(new ArrayList<Object>(), transformers);
122    
123            u.addObject("12.5");
124            u.addObject(Integer.valueOf(12));
125            u.addObject("11.8");
126            u.addObject("14.2");
127            u.addObject(new Foo());
128            u.addObject("14.5");
129            u.addObject(Long.valueOf(21));
130            u.addObject("8.2");
131            u.addObject("10.3");
132            u.addObject("11.3");
133            u.addObject(Float.valueOf(14.1f));
134            u.addObject("9.9");
135            u.addObject("12.2");
136            u.addObject(new Bar());
137            u.addObject("12.1");
138            u.addObject("11");
139            u.addObject(Double.valueOf(19.8));
140            u.addObject("11");
141            u.addObject("10");
142            u.addObject("8.8");
143            u.addObject("9");
144            u.addObject("12.3");
145    
146    
147            assertEquals("mean", 12.40455, u.getMean(), 0.0001);
148            assertEquals("variance", 10.00236, u.getVariance(), 0.0001);
149            assertEquals("skewness", 1.437424, u.getSkewness(), 0.0001);
150            assertEquals("kurtosis", 2.37719, u.getKurtosis(), 0.0001);
151        }
152    
153        public void testProductAndGeometricMean() throws Exception {
154            ListUnivariateImpl u = new ListUnivariateImpl(new ArrayList<Object>(),transformers);
155            u.setWindowSize(10);
156    
157            u.addValue(1.0);
158            u.addValue(2.0);
159            u.addValue(3.0);
160            u.addValue(4.0);
161    
162            assertEquals(
163                "Geometric mean not expected",
164                2.213364,
165                u.getGeometricMean(),
166                0.00001);
167    
168            // Now test rolling - StorelessDescriptiveStatistics should discount the contribution
169            // of a discarded element
170            for (int i = 0; i < 10; i++) {
171                u.addValue(i + 2);
172            }
173            // Values should be (2,3,4,5,6,7,8,9,10,11)
174            assertEquals(
175                "Geometric mean not expected",
176                5.755931,
177                u.getGeometricMean(),
178                0.00001);
179    
180        }
181    
182        public static final class Foo {
183            public String heresFoo() {
184                return "14.9";
185            }
186        }
187    
188        public static final class FooTransformer implements NumberTransformer, Serializable {
189            private static final long serialVersionUID = -4252248129291326127L;
190            public double transform(Object o) {
191                return Double.parseDouble(((Foo) o).heresFoo());
192            }
193        }
194    
195        public static final class Bar {
196            public String heresBar() {
197                return "12.0";
198            }
199        }
200    
201        public static final class BarTransformer implements NumberTransformer, Serializable {
202            private static final long serialVersionUID = -1768345377764262043L;
203            public double transform(Object o) {
204                return Double.parseDouble(((Bar) o).heresBar());
205            }
206        }
207    
208    }