Boost logo

Boost Users :

From: Ray Burkholder (ray_at_[hidden])
Date: 2008-05-17 20:23:44


 
A general question about its capabilities. The library is excellent for
getting updated statistics as one adds values to an accumulator.

I have one wrinkle. I have long running time series, and wish to evaluate
statistics on a window of the data, say the last 100 values. Can the
Accumulator framework be used in a 'windowed' situation? For example, for a
similar smaller scale project, I used a queue ( to represent a specific time
frame) to to keep track of a series of values. As values are added to the
queue, they are added into a statistic. As the values are dropped from the
qeue, the values are removed from a statistic.

I understand that rounding errors may accumulate over time, but current
experiments indicate that the error magnitude by the end of the series is
not noticable.

If code helps to make sense, here is what I did on a smaller scale with
simple statistics (some may comment on the lack of getters and setters, but
at least the concept is there):

class CRunningStats {
public:
  CRunningStats(void);
  CRunningStats(double BBMultiplier);
  virtual ~CRunningStats(void);
  void SetBBMultiplier( double dbl ) { m_BBMultiplier = dbl; };
  double GetBBMultiplier( void ) { return m_BBMultiplier; };

  double b2; // acceleration
  double b1; // slope
  double b0; // offset

  double meanY;

  double RR;
  double R;

  double SD;

  double BBUpper, BBLower;

  void Add( double, double );
  void Remove( double, double );
  virtual void CalcStats( void );

protected:
  unsigned int nX, nY;

  double SumXX, SumX, SumXY, SumY, SumYY;
  double Sxx, Sxy, Syy;
  double SST, SSR, SSE;

  double m_BBMultiplier;

private:
};

CRunningStats::CRunningStats(void) :
  b2( 0 ), b1( 0 ), b0( 0 ),
  SumXX( 0 ), SumX( 0 ), SumXY( 0 ), SumY( 0 ), SumYY( 0 ),
  nX( 0 ), m_BBMultiplier( 2.0 )
{
}

CRunningStats::CRunningStats( double BBMultiplier ) :
  b2( 0 ), b1( 0 ), b0( 0 ),
  SumXX( 0 ), SumX( 0 ), SumXY( 0 ), SumY( 0 ), SumYY( 0 ),
  nX( 0 ), m_BBMultiplier( BBMultiplier )
{
}

CRunningStats::~CRunningStats(void) {
}

void CRunningStats::Add(double x, double y) {
  SumXX += x * x;
  SumX += x;
  SumXY += x * y;
  SumY += y;
  SumYY += y * y;
  nX++;
}

void CRunningStats::Remove(double x, double y) {
  SumXX -= x * x;
  SumX -= x;
  SumXY -= x * y;
  SumY -= y;
  SumYY -= y * y;
  nX--;
}

void CRunningStats::CalcStats() {

  if ( nX > 1 ) {

    double oldb1 = b1;

    Sxx = SumXX - ( SumX * SumX ) / nX;
    Sxy = SumXY - ( SumX * SumY ) / nX;
    Syy = SumYY - ( SumY * SumY ) / nX;

    SST = Syy;
    SSR = ( Sxy * Sxy ) / Sxx;
    SSE = SST - SSR;

    RR = SSR / SST;
    R = Sxy / sqrt(Sxx * Syy);

    //SD = Math.Sqrt(Syy / (Xcnt - 1));
    SD = sqrt(Syy / nX);

    meanY = SumY / nX;

    double BBOffset = m_BBMultiplier * SD;
    BBUpper = meanY + BBOffset;
    BBLower = meanY - BBOffset;

    b1 = ( nX > 1 ) ? Sxy / Sxx : 0;
    b0 = (1 / nX) * ( SumY - b1 * SumX );
    b2 = b1 - oldb1; // *** do this differently
  }
}

-- 
Scanned for viruses and dangerous content at 
http://www.oneunified.net and is believed to be clean.

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net