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}