2.1.17.8.10 ocmath_group_xy_by_x


Description

This function separates XY data to groups according to their X values.

Syntax

int ocmath_group_xy_by_x( int nPts, double * pX, double * pY, int nPtCntrl, double * pXCntrl, int * pGrpEnd )

Parameters

nPts
[Input] the number of XY pairs.
pX
[Modify] the X values of the XY pairs.
pY
[Modify] the Y values of the XY pairs.
nPtCntrl
[Input] the number of control points.
pXCntrl
[Input] the X valus of the control points.
pGrpEnd
[Output] the indices of the end points of each group. Notice the size of array pGrpEnd[] should be no less than (nPtCntrl+1).

Return

0 on success or

-1 on invalid number of points or

-2 on invalid array pointer or

-3 if the elements in array pXCntrl[] are not strictly monotonic.

Examples

EX1

void ocmath_group_xy_by_x_ex1()
{
    int nPts = 10; 
    vector vx = {1,2,6,4,5,3,7,8,9,10};
    vector vy = {2,3,5,1,6,7,2,3,5,7};
    
    int nCtl = 4;
    vector vCheck = {2,4,6,8};
    
    vector<int> vEnd(nCtl + 1);
    ocmath_group_xy_by_x(nPts, vx, vy, nCtl, vCheck, vEnd);
    
    // Calculate mean values of all groups
    
    vector vMean(nCtl+1);
    int ii, index = 0;
    
    for (ii = 0; ii < nCtl+1; ii++)
    {
        int nSize = 0;

        if(ii == 0)
            nSize = vEnd[ii] - 0 + 1;
        else
            nSize = vEnd[ii] - vEnd[ii - 1];

        if (nSize == 0)
            vMean[ii] = NANUM;
        else
        {
            vMean[ii] = 0;
            for (; index <= vEnd[ii]; index++)
                vMean[ii] += vy[index];
            vMean[ii] /= nSize;
        }
    }
}

EX2

bool subgroup_ave(double dbinW, vector& vx, vector& vy, vector& vxAve, vector& vyAve, vector& vySD, vector<int>& vnCount)
{
    int nSize = vx.GetSize();
    if(vy.GetSize() != nSize)
        return error_report("subgroup_ave found inconsistency in input x y data");
    double xmin, xmax;
    vx.GetMinMax(xmin, xmax);
    int npts = RoundLimits(&xmin, &xmax, &dbinW, 0);

    // bin centers
    vxAve.Data(xmin + dbinW*0.5, xmax - dbinW*0.5, dbinW); 
    if(npts != vxAve.GetSize())
        return error_report("subgroup_ave found inconsistency in bin center calculation");
    // bins
    vector vBins;
    vBins.Data(xmin + dbinW, xmax - dbinW, dbinW);
    if(npts != vBins.GetSize()+1)
        return error_report("subgroup_ave found inconsistency in bins calculation");
    
    vector<int> vEnd(npts);
    int nErr = ocmath_group_xy_by_x(nSize, vx, vy, npts-1, vBins, vEnd);
    if(nErr != 0)
        return error_report("subgroup_ave found ocmath_group_xy_by_x error");
    
    // do averaging
    vyAve.SetSize(vxAve.GetSize());
    if(vySD)
        vySD.SetSize(vxAve.GetSize());
    if(vnCount)
        vnCount.SetSize(vxAve.GetSize());
    
    double ave, sd;
    for (int ii = 0; ii < npts; ii++)
    {
        int n0 = ii>0? vEnd[ii-1]:0;
        int n1 = vEnd[ii];
        int nn = n1 - n0;
        if(vnCount)
            vnCount[ii] = nn;
        
        if (nn == 0)
        {
            ave = NANUM;
            sd = NANUM;
        }
        else
        {
            vector vTemp;
            vy.GetSubVector(vTemp, n0, n1);
            DescStatResults dsr;
            ocmath_desc_stats(vTemp, vTemp.GetSize(), &dsr);
            ave = dsr.Mean;
            sd = dsr.SD;
        }
        vyAve[ii] = ave;
        if(vySD)
            vySD[ii] = sd;
    }
    return true;
}
    
void ocmath_group_xy_by_x_ex2(double dStep = 2)
{
    //assume the active window is a workbook
    Worksheet wks = Project.ActiveLayer();
    wks.SetSize(-1, 6);
    // assume data in col A and B
    DataRange dr;
    dr.Add("X", wks, 0, 0, -1, 0);
    dr.Add("X", wks, 0, 1, -1, 1);
    // put results into other cols
    dr.Add("X", wks, 0, 2, -1, 2);
    dr.Add("X", wks, 0, 3, -1, 3);
    dr.Add("X", wks, 0, 4, -1, 4);
    dr.Add("X", wks, 0, 5, -1, 5);
    vector vx, vy;
    dr.GetData(&vx, 0);
    dr.GetData(&vy, 1);

    vector vxAve, vyAve, vySD;
    vector<int> vn;
    if(subgroup_ave(dStep, vx, vy, vxAve, vyAve, vySD, vn))
    {
        vector vnTemp;
        vnTemp = vn;
        dr.SetData(vxAve, false, 2);
        dr.SetData(vyAve, false, 3);
        dr.SetData(vySD, false, 4);
        dr.SetData(vnTemp, false, 5);
        //dr.SetData(&vn, &vySD, &vyAve, true, 3);
    }
        
}

Remark

This function separates XY data to groups according to their X values. The original XY pairs will be sorted in the same order of the control points. That is, if the X values of the control points are in a ascending order, the XY pairs will be sorted in ascending and divided into groups of their X being: x<pXCntrl[0], pXCntrl[0]<=x<pXCntrl[1],..., pXCntrl[n-2]<=x<pXCntrl[n-1], x>=pXCntrl[n-1]; On the contrary, the XY pairs will be sorted in descending and divided into groups of their X values being: x>pXCntrl[0], pXCntrl[0]>=x>pXCntrl[1],..., pXCntrl[n-2]>=x>pXCntrl[n-1], x<=pXCntrl[n-1].

See Also

Header to Include

origin.h

Reference