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>
void GetAdjAvg()
{
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;
}
//This overloaded function is designed to get adjacent average through
//SetColumnValues menu.
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);
}
|