3.9.1.2 Movavg

Version Info

Minimum Origin Version Required: Origin 9.0

Moving Average

This example shows for a specific cell, how to compute average in a specific range. Then, with transversing along the whole column, each cell is set to the mean of the same of adjacent range.

#include <origin.h>
{
Worksheet wkstmp = Project.ActiveLayer();
Column colA, colB;
if(wkstmp){
colA = wkstmp.Columns(0);
colB = wkstmp.Columns(1);
}

vector vcInput = colA.GetDataObject();

Dataset dsOutput;
dsOutput.Attach(colB);

if(dsOutput.GetSize()!=vcInput.GetSize())
dsOutput.SetSize(vcInput.GetSize());
//iBack: the backward offset respect to current position
//iForw: the forward offset respect to current position
int iBack = -1;
int iForw = 1;

dsOutput = movavg1(vcInput, iBack, iForw);
}

vector  movavg1(const vector& vdInput,  int iBack, int iForw)
{
vector vdOutput(vdInput.GetSize());

for (int ii=0; ii<vdOutput.GetSize(); ++ii)
//The row index passed from SetColumnValues is 1 offset.
vdOutput[ii] = movavg1(vdInput, iBack, iForw, ii+1);

return vdOutput;
}

double movavg1(vector& vdInput, int iBack, int iForw,
int nInd, int bPerio=0)
//iBack: the backward offset respect to current position
//iForw: the forward offset respect to current position
//bPero: Specifiy the periodicity of the vector.
// 0: non-periodic: cells beyond the vector range are ignored.
// 1: periodic:v[i] = v[(i+n*K)%n] where n is the length of the vector

{
//The row index is 1 offset respect to the vector.

--nInd;
int lower = nInd+iBack;
int upper = nInd+iForw;
int nStart = min(lower, upper);
int nEnd   = max(lower, upper);

// Periodic Vector.  vec[-1]=vec[n-1] vec[-2] = vec[n-2]
if( bPerio ){

double sum = 0;
for( int ii=nStart; ii<=nEnd; ++ii )
sum += vdInput[indPerio1(ii, vdInput.GetSize())];

double avg = sum/(double)(iBack+iForw+1);
return avg;
}
// Nonperiodic Vector. To be comptable with Excel, exceeded cells are truncatated.
else{
if( nStart > vdInput.GetSize()-1 || nEnd < 0)
return NANUM;

if( nStart < 0 )
nStart = 0;
if( nEnd > vdInput.GetSize()-1 )
nEnd = vdInput.GetSize()-1;
int nLen = nEnd - nStart+1;
double sum = 0;
for( int ii=nStart; ii<=nEnd; ++ii )
sum += vdInput[ii];
double avg = sum/(double)nLen;
return avg;
}
}

int indPerio1(int ind, int nSize)
{
return (ind%nSize+nSize)%nSize;

}

// This function allows passing column number (labtalk 1-based counting)
// and the backward and forward points
void getadjavg(int iColIn, int iColOut, int iBack, int iForw)
{
Worksheet wks = Project.ActiveLayer();
if( !wks ) return;
Column colIn, colOut;
colIn = wks.Columns(iColIn-1);
colOut = wks.Columns(iColOut-1);
if( !colIn || !colOut) return;

vector vcInput = colIn.GetDataObject();
Dataset dsOutput;
dsOutput.Attach(colOut);

if(dsOutput.GetSize()!=vcInput.GetSize())
dsOutput.SetSize(vcInput.GetSize());
//iBack: the backward offset respect to current position
//iForw: the forward offset respect to current position

dsOutput = movavg1(vcInput, iBack, iForw);
}