001package com.hfg.math; 002 003import java.util.Collection; 004import java.util.Map; 005 006 007//------------------------------------------------------------------------------ 008/** 009 Lightweight sample statistics. The individual values are not retained. 010 011 @author J. Alex Taylor, hairyfatguy.com 012 */ 013//------------------------------------------------------------------------------ 014// com.hfg XML/HTML Coding Library 015// 016// This library is free software; you can redistribute it and/or 017// modify it under the terms of the GNU Lesser General Public 018// License as published by the Free Software Foundation; either 019// version 2.1 of the License, or (at your option) any later version. 020// 021// This library is distributed in the hope that it will be useful, 022// but WITHOUT ANY WARRANTY; without even the implied warranty of 023// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 024// Lesser General Public License for more details. 025// 026// You should have received a copy of the GNU Lesser General Public 027// License along with this library; if not, write to the Free Software 028// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 029// 030// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 031// jataylor@hairyfatguy.com 032//------------------------------------------------------------------------------ 033 034public class SimpleSampleStats 035{ 036 037 //************************************************************************** 038 // PRIVATE FIELDS 039 //************************************************************************** 040 041 private long mSampleSize; 042 private double mSumX; 043 private double mSumX2; 044 private Double mMax; 045 private Double mMin; 046 047 048 //************************************************************************** 049 // PUBLIC FUNCTIONS 050 //************************************************************************** 051 052 //-------------------------------------------------------------------------- 053 public void add(SimpleSampleStats inStats) 054 { 055 mSampleSize += inStats.mSampleSize; 056 mSumX += inStats.mSumX; 057 mSumX2 += inStats.mSumX2; 058 if (inStats.mMax > mMax) mMax = inStats.mMax; 059 if (inStats.mMin < mMin) mMin = inStats.mMin; 060 } 061 062 //-------------------------------------------------------------------------- 063 public void addAll(Collection<? extends Number> inValues) 064 { 065 for (Number value : inValues) 066 { 067 add(value.doubleValue()); 068 } 069 } 070 071 //-------------------------------------------------------------------------- 072 public void addAll(int[] inValues) 073 { 074 for (double value : inValues) 075 { 076 add(value); 077 } 078 } 079 080 //-------------------------------------------------------------------------- 081 public void addAll(double[] inValues) 082 { 083 for (double value : inValues) 084 { 085 add(value); 086 } 087 } 088 089 //-------------------------------------------------------------------------- 090 public void addAll(Map<Number, Integer> inValueCountMap) 091 { 092 for (Number value : inValueCountMap.keySet()) 093 { 094 Integer count = inValueCountMap.get(value); 095 if (count != null 096 && count != 0) 097 { 098 double doubleValue = value.doubleValue(); 099 100 if (null == mMin 101 || doubleValue < mMin) 102 { 103 mMin = doubleValue; 104 } 105 106 if (null == mMax 107 || doubleValue > mMax) 108 { 109 mMax = doubleValue; 110 } 111 112 mSampleSize += count; 113 mSumX += doubleValue * count; 114 mSumX2 += (doubleValue * doubleValue) * count; 115 } 116 } 117 } 118 119 //-------------------------------------------------------------------------- 120 public void add(Number inValue) 121 { 122 add(inValue.doubleValue()); 123 } 124 125 //-------------------------------------------------------------------------- 126 public void add(int inValue) 127 { 128 add((double) inValue); 129 } 130 131 //-------------------------------------------------------------------------- 132 public void add(double inValue) 133 { 134 if (null == mMin 135 || inValue < mMin) 136 { 137 mMin = inValue; 138 } 139 140 if (null == mMax 141 || inValue > mMax) 142 { 143 mMax = inValue; 144 } 145 146 mSampleSize++; 147 mSumX += inValue; 148 mSumX2 += (inValue * inValue); 149 } 150 151 //-------------------------------------------------------------------------- 152 public void clear() 153 { 154 mSampleSize = 0; 155 mSumX = 0; 156 mSumX2 = 0; 157 mMax = null; 158 mMin = null; 159 } 160 161 //-------------------------------------------------------------------------- 162 public double getMin() 163 { 164 return mMin; 165 } 166 167 //-------------------------------------------------------------------------- 168 public double getMax() 169 { 170 return mMax; 171 } 172 173 //-------------------------------------------------------------------------- 174 public double getMean() 175 { 176 return mSumX / mSampleSize; 177 } 178 179 //-------------------------------------------------------------------------- 180 public long getSampleSize() 181 { 182 return mSampleSize; 183 } 184 185 //-------------------------------------------------------------------------- 186 public double getSampleStandardDeviation() 187 { 188 // The preferred equation is StdDev = Sqrt(Sum(X[i] - Xmean)^2 / (N-1) ) 189 // but since we don't keep all the values in this version and can't calculate the 190 // mean until the end, we need to use this somewhat less precise version: 191 // StdDev = Sqrt( (N SumX2 - SumX^2) / (N (N-1)) ) 192 return Math.sqrt((mSampleSize * mSumX2 - (mSumX * mSumX))/ (mSampleSize * (mSampleSize - 1))); 193 } 194 195 //-------------------------------------------------------------------------- 196 public StandardNormalDistribution getStandardNormalDistribution() 197 { 198 return new StandardNormalDistribution().setMean(getMean()).setSampleStandardDeviation(getSampleStandardDeviation()); 199 } 200 201 202 203 204}