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