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