Fit Multiple XY Data in a loop

Version Info

Minimum Origin Version Required: Origin 8 SR6

Need to do before Running Examples

Prior to running the following example, the nlsf_utils.c file need to be loaded and compiled. This can be done from script with the following command or just add this file to your workspace.

run.LoadOC(Originlab\nlsf_utils.c);

Examples

The following code shows how to use the NLFitSesssion to fit many datasets to the same function.

#include <Origin.h>
#include <..\originlab\NLFitSession.h>
// assume active worksheet with XYYYY data, all with a single peak
// so we can fit all of them to gauss function and gnerate a new worksheet to hold the fitting results.
void test1()
{
        Worksheet wks = Project.ActiveLayer();
        if(!wks)
            return;
        
        Worksheet wksOut;
        wksOut.Create();
        
        fit_all_cols(wks, wksOut);
}

static bool fit_all_cols(Worksheet& wks, Worksheet& wksOutput, string strFunc = "Gauss")
{
        NLFitSession    FitSession;
        int             nDataIndex = 0; // only one set in our case
        DWORD           dwRules = DRR_GET_DEPENDENT | DRR_NO_FACTORS;
        
        // 1. Set fucntion
        if(!FitSession.SetFunction(strFunc, NULL)) // set function, category name can be ignore
            return error_report("invalid fit function");
        
        vector<string>  vsParamNames;
        int             nNumParamsInFunction = FitSession.GetParamNamesInFunction(vsParamNames);
        int                        nFitOutcome, nFitErr = -1;
        
        for(int nYCol = 1; nYCol < wks.GetNumCols(); nYCol++)
        {
            DataRange   drInputData;
            drInputData.Add(wks, 0, "X");
            drInputData.Add(wks, nYCol, "Y");
            int         nNumData = drInputData.GetNumData(dwRules);
            ASSERT(1==nNumData);
            
            //2 set the dataset
            vector  vX1, vY1;
            drInputData.GetData( dwRules, nDataIndex, NULL, NULL, &vY1, &vX1 );     
            if(!FitSession.SetData(vY1, vX1, NULL, nDataIndex, nNumData))  
                return error_report("err setting data");
        
            // 3. Call parameter init codes to init parameters
            if(!FitSession.ParamsInitValues())
                return error_report("err ParamsInitValues");
            // 4. Iterate with default settings
            if(!FitSession.Fit(&nFitOutcome))
            {
                string strOutcome = FitSession.GetFitOutCome(nFitOutcome);
                printf("fit failed:%d->%s\n", nFitErr, strOutcome);
                return false;
            }
                // 5. success, get results and put to wksOutput
                FitParameter    params[20];// whatever the max possible number of parameters in your function
                RegStats                fitStats;
                NLSFFitInfo             fitInfo;
                FitSession.GetFitResultsStats(&fitStats, &fitInfo, false, nDataIndex);
                FitSession.GetFitResultsParams(params, &fitStats);
                _append_fit_results(wksOutput, vsParamNames, params, fitStats, fitInfo);
        }
        
        return true;
}
static void _append_fit_results(Worksheet& wks, const vector<string>& vsParamNames, const FitParameter* pParams, const RegStats& fitStats, const NLSFFitInfo& fitInfo)
{
        Column  c0Time = wks.Columns(0);
        int                nR1 = c0Time.GetUpperBound();
        // check if empty, then setup cols
        if(nR1 < 0)
        {
                vector<string> vsExtraCols = {"Tick Count", "Adj Rsquare", "Iterations"};
                int nTotalCols = vsParamNames.GetSize() + vsExtraCols.GetSize();
                if(wks.GetNumCols() < nTotalCols)
                {
                        wks.SetSize(0, nTotalCols);
                        vector<string> vs;vs = vsExtraCols;
                        vs.Append(vsParamNames);         
                        for(int nCol = 0;nCol < vs.GetSize();nCol++)
                        {
                                Column cc = wks.Columns(nCol);
                                cc.SetLongName(vs[nCol]);
                        }
                }
        }
        nR1++; 
        wks.SetCell(nR1, 0, GetTickCount()/1000.0);
        wks.SetCell(nR1, 1, fitStats.AdjRSq);
        wks.SetCell(nR1, 2, fitInfo.Iterations);
        //fit parameters
        for(int ii = 0, nCol = 3; ii < vsParamNames.GetSize(); ii++, nCol++)
        {
                wks.SetCell(nR1, nCol, pParams[ii].Value);
        }
}