Fit on multiple datasets with one function, parameters shared
Version Info
Minimum Origin Version Required: Origin 8.1 SR0
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:
run.LoadOC(Originlab\nlsf_utils.c);
Examples
- New a worksheet and import \Samples\Curve Fitting\Gaussian.dat.
- Copy the following example codes to a c file and compile.
- Run test_NLFitSession in Command Window. The fitting Y data will be putted to worksheet new columns and will print out the fitting result to Command Window.
#include <..\Originlab\NLFitSession.h>
#define ERR_RETURN(_ERR_MSG) { \
out_str(_ERR_MSG); \
return; \
}
void test_NLFitSession()
{
Worksheet wks = Project.ActiveLayer();
if( !wks )
return;
XYRange drInput;
drInput.Add(wks, 0, "X");
drInput.Add(wks, 1, "Y");
drInput.Add();
drInput.Add(wks, 0, "X");
drInput.Add(wks, 2, "Y");
int nNumData = drInput.GetNumData(DRR_GET_DEPENDENT);
vector vX1, vY1, vX2, vY2;
drInput.GetData(vY1, vX1, NULL, 0);
drInput.GetData(vY2, vX2, NULL, 1);
NLFitSession nlfSession;
// Set Function
if ( !nlfSession.SetFunction("Gauss") )
ERR_RETURN("Fail to set function!");
// Set Data and only need to set the last dataset with global fit mode, as to allow share parameters
if ( !nlfSession.SetData(vY1, vX1, NULL, 0, nNumData) )
ERR_RETURN("Fail to set data for the first dataset!")
if ( !nlfSession.SetData(vY2, vX2, NULL, 1, nNumData, DATA_MODE_GLOBAL) )
ERR_RETURN("Fail to set data for the second dataset!")
// Parameter initialization
if ( !nlfSession.ParamsInitValues() )
ERR_RETURN("Fail to init parameters values!")
// Share xc parameter
int nSharedParamIndex = 1; // 1, the index of xc in function, must be DATA_MODE_GLOBAL datamode, or else will fail to share parameters
nlfSession.SetParamShare(nSharedParamIndex);
// Show parameters before fitting
nlfSession.GetChiSqr(); // call GetChiSqr order to set parameter settings on internal fit object
show_params(nlfSession, nNumData, "Before ftting");
// Set lower bound for the second dataset "Y0" parameter - "Y0 >= 3"
// NLFitSession::SetParamBounds supported from Origin 8.5.1 version
int nParam = 0; // Y0
int nLimitControl = 0; // 0 for "<="
double dLimitValue = 3;
bool bIsLower = true; // lower bound
int nDataset = 1; // the second dataset
nlfSession.SetParamBounds(nParam, nLimitControl, dLimitValue, bIsLower, nDataset);
// Do fit
int nFitOutcome;
bool bRet = nlfSession.Fit(&nFitOutcome); //if success
string strOutcome = nlfSession.GetFitOutCome(nFitOutcome);
out_str("Outcome of the fitting session : " + strOutcome);
if( bRet )
{
// Show parameters after fitting
show_params(nlfSession, nNumData, "After ftting");
// Get fit parameter results
vector vFitY1(vX1.GetSize()), vFitY2(vX2.GetSize());
nlfSession.GetYFromX(vX1, vFitY1, vX1.GetSize(), 0);
nlfSession.GetYFromX(vX2, vFitY2, vX1.GetSize(), 1);
// Put fitting data into new column in worksheet
append_column_data(wks, vFitY1, "Fit 1");
append_column_data(wks, vFitY2, "Fit 2");
}
}
void append_column_data(Worksheet& wks, vector& vData, LPCSTR lpcstrLongName)
{
int nCol = wks.AddCol();
if( NULL != lpcstrLongName )
wks.Columns(nCol).SetLongName(lpcstrLongName);
Dataset ds(wks, nCol);
ds = vData;
}
void show_params(NLFitSession& nlfSession, int nNumData, LPCSTR lpcscTitle)
{
vector<double> vParamValues;
vector<int> vParamOffsets;
vector<string> vsParamNames;
//get parameters values and names
nlfSession.GetParamValuesAndOffsets(vParamValues, vParamOffsets);
nlfSession.GetParamNamesInFunction(vsParamNames);
//output paramter values with names;
for ( int iData = 0; iData < nNumData; iData++ )
{
printf("%s, parameters of the Dataset%d:\n", lpcscTitle, iData + 1);
for ( int nParam = vParamOffsets[iData], ii = 0; nParam < vParamOffsets[iData + 1]; nParam++, ii++ )
{
printf("%s = %lf\n", vsParamNames[ii], vParamValues[nParam]);
}
}
}
|