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>
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);
}