3.9.2.2.2 Fit on multiple datasets with one function with parameters shared
Version Info
Minimum Origin Version Required: Origin 8 SR0
Examples
Fit on two datasets with Gauss function, parameter xc is shared.
// before running this function, import \Samples\Curve Fitting\Gaussian.dat to worksheet.
#include <Origin.h>
#include <FDFTree.h>
#include <ONLSF.h>
void NLFit_example2()
{
string strFDF = okutil_get_origin_path(ORIGIN_PATH_SYSTEM, "FitFunc") + "Gauss.FDF";
Tree trFF;
if( !nlsf_FDF_to_tree( strFDF, &trFF ))
{
out_str("Fail to load FDF function file");
return;
}
//////////////////////////////////////////////////////////////////////////////
// 1. Setting the fitting function //
// The fit object:
NLFit fit;
int nn = fit.SetFunction(trFF);
if (nn <= 0)
{
out_str("Failed setting fitting function!");
return;
}
///////////////////////////////////////////////////////////////////////////
// 2. Setting data for fitting ////////////////////////////////////////////
Worksheet wks = Project.ActiveLayer();
if( !wks )
{
out_str("No active worksheet to get input data");
return;
}
DataRange dr;
dr.Add(wks, 0, "X");
dr.Add(wks, 1, "Y");
dr.Add();
dr.Add(wks, 0, "X");
dr.Add(wks, 2, "Y");
DWORD dwRules = DRR_GET_DEPENDENT | DRR_NO_FACTORS;
int nNumData = dr.GetNumData(dwRules);
ASSERT( 2 == nNumData );
if( nNumData <= 0 || nNumData > 2)
{
out_str("Not proper input data to do fit");
return;
}
NLSFONEDATA stDep[2], stIndep[2];
DWORD dwPlotID;
vector vX1, vY1;
dr.GetData( dwRules, 0, &dwPlotID, NULL, &vY1, &vX1);
stIndep[0].pdData = vX1;
stIndep[0].nSize = vX1.GetSize();
stDep[0].pdData = vY1;
stDep[0].nSize = vY1.GetSize();
vector vX2, vY2;
dr.GetData( dwRules, 1, &dwPlotID, NULL, &vY2, &vX2);
stIndep[1].pdData = vX2;
stIndep[1].nSize = vX2.GetSize();
stDep[1].pdData = vY2;
stDep[1].nSize = vY2.GetSize();
nn = fit.SetData(nNumData, &stDep, &stIndep);
if (nn != 0)
{
out_str("SetData() failed!");
return;
}
///////////////////////////////////////////////////////////////////////////
// 3. Set the initial paramater values and the sharing information/////////
int numParamsInFunction = 4; // there are this many paramaters in the function. y0, xc, W, A
int nTotalParams = nNumData * numParamsInFunction;
int nNumParamsIgnoreShared = nTotalParams - 1;
vector<int> vbSharing;
vbSharing.SetSize(nNumParamsIgnoreShared);
vbSharing = 0;
vbSharing[1] = 1; //xc shared
vector vFitParams;
vFitParams.SetSize(nNumParamsIgnoreShared);
vFitParams[0] = 5.58; //y0 for 1st data
vFitParams[1] = 26; //xc shared for 1st data and 2nd data
vFitParams[2] = 8.6; // W for 1st data
vFitParams[3] = 976; // A for 1st data
vFitParams[4] = 2.4; // y0 for 2nd data
vFitParams[5] = 9.8; // W for 2nd data
vFitParams[6] = 95; // A for 2nd data
nn = fit.SetParams(nNumParamsIgnoreShared, vFitParams, vbSharing);
out_int("SetParams() returned: ", nn);
if ( 0 != nn )
{
out_str("Invalid paramater setting!");
return;
}
///////////////////////////////////////////////////////////////////////////
// 4. Perform fitting//////////////////////////////////////////////////////
int nMaxNumIterations = 100;
nn = fit.Fit(nMaxNumIterations);
printf("Fit(%ld) returned: %ld\n", nMaxNumIterations, nn);
if( 0 == nn )
printf("Fit Done!\n");
// Dump results:
for (int iparam = 0; iparam < nNumParamsIgnoreShared; iparam++)
{
printf("param index = %d value value is = %lf\n", iparam + 1, vFitParams[iparam]);
}
return;
}
|