NLFit is the new fitter starting with Origin version 8. This new fitter handles the fitting process with a copy of the data while performing iterations. This results in faster operation compared to older versions where the fitter directly accessed data repeatedly from the worksheet.
There are two classes available to perform nonlinear fitting:
Before you use the NLFitSession class, you need to include a specific header file:
#include <..\originlab\NLFitSession.h>
You also need to include and compile the OriginC\Originlab\nlsf_utils.c file to your current workspace. Run the Labtalk command below in the Command window, or from your script file, to programmatically add the file:
Run.LoadOC(Originlab\nlsf_utils.c, 16)
Define an NLFitSession object, and set the fitting function as Gauss:
// Set Function NLFitSession nlfSession; if ( !nlfSession.SetFunction("Gauss") ) { out_str("Fail to set function!"); return; } // Get parameter names and number: vector<string> vsParamNames; int nNumParamsInFunction = nlfSession.GetParamNamesInFunction(vsParamNames);
Set two XY datasets with DATA_MODE_GLOBAL mode, to perform global fitting with sharing of parameters:
int nNumData = 2; // Set the first dataset if ( !nlfSession.SetData(vY1, vX1, NULL, 0, nNumData) ) { out_str("Fail to set data for the first dataset!"); return; } // Set the second dataset if ( !nlfSession.SetData(vY2, vX2, NULL, 1, nNumData, DATA_MODE_GLOBAL) ) { out_str("Fail to set data for the second dataset!"); return; }
Run parameter initialization code to initialize parameter values:
// Parameter initialization if ( !nlfSession.ParamsInitValues() ) { out_str("Fail to init parameters values!"); return; }
Alternately, you can directly set parameter values one by one:
vector vParams(nNumParamsInFunction*nNumData); // set parameter value for the first dataset vParams[0] = 5.5; // y0 vParams[1] = 26; // A vParams[2] = 8; // xc vParams[3] = 976; // w // set parameter value for the second dataset vParams[4] = 2.3; // y0 vParams[5] = 26; // A vParams[6] = 10.3; // xc vParams[7] = 102; // w int nRet = nlfSession.SetParamValues(vParams); if(nRet != 0) // 0 means no error return;
Share xc parameter between the two datasets:
int nSharedParamIndex = 1; // 1, the index of xc in Gauss function nlfSession.SetParamShare(nSharedParamIndex);
Perform the fit and output status message:
// Do fit int nFitOutcome; nlfSession.Fit(&nFitOutcome); string strOutcome = nlfSession.GetFitOutCome(nFitOutcome); out_str("Outcome of the fitting session : " + strOutcome);
Get fit statistic result:
int nDataIndex = 0; RegStats fitStats; NLSFFitInfo fitInfo; nlfSession.GetFitResultsStats(&fitStats, &fitInfo, false, nDataIndex); printf("# Iterations=%d, Reduced Chisqr=%g\n", fitInfo.Iterations, fitStats.ReducedChiSq);
Get final fit parameter values:
vector vFittedParamValues, vErrors; nlfSession.GetFitResultsParams(vFittedParamValues, vErrors); // The parameter xc is shared in two input data. // So the value of xc is same for all data sets, and it only appears one time // in the fitted parameter values - vParamValues. // vsParamNames contains the parameter names in Gauss function - y0, xc, w, A. // The following to add parameter names for the second dataset without xc. vsParamNames.Add("y0"); vsParamNames.Add("w"); vsParamNames.Add("A"); for( int nParam = 0; nParam < vFittedParamValues.GetSize(); nParam++) { printf("%s = %f\n", vsParamNames[nParam], vFittedParamValues[nParam]); }
Calculate fit curve Y values using the final fit parameters:
vector vFitY1(vX1.GetSize()), vFitY2(vX2.GetSize()); // Get fitted Y for the first dataset nlfSession.GetYFromX(vX1, vFitY1, vX1.GetSize(), 0); // Get fitted Y for the second dataset nlfSession.GetYFromX(vX2, vFitY2, vX1.GetSize(), 1);
Fitting function settings stored in an FDF file can be loaded into a tree variable. You will need to include the OriginC\system\FDFTree.h file:
#include <FDFTree.h>
Then use the nlsf_FDF_to_tree function:
string strFile = GetOpenBox("*.FDF"); Tree tr; if(nlsf_FDF_to_tree(strFile, &tr)) { out_tree(tr); }