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