3.9.2.2.5 Fit on one data with one implicit function

Version Info

Minimum Origin Version Required: OriginPro 9.0 SR0

Examples

The following code shows how to use NLFit to fit with ellipse data.

  1. Create a new worksheet and import the data <Origin Installation Directory>\Samples\Curve Fitting\Ellipse.dat.
  2. Copy and compile the following codes in Code Builder, and then run "NLFit_Implicit_example1" in Command Window.
//////////////////////////////////////////////////////////////////////////////////////
// Implicit function fitting, fitting a ellipse f(x,y) = 1 - ((x - xc)/a)^2 - ((y-yc)/b)^2
//////////////////////////////////////////////////////////////////////////////////////
#include <Origin.h>
#include <FDFTree.h>
#include <ONLSF.h>

void	NLFit_Implicit_example1()
{
	string			strFDF =  okutil_get_origin_path(ORIGIN_PATH_SYSTEM, "FitFunc") + "ellipse.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;
	}
	
	vector vX = wks.Columns(0).GetDataObject();
	vector vY = wks.Columns(1).GetDataObject();
	vector vWx = wks.Columns(2).GetDataObject();
	vector vWy = wks.Columns(3).GetDataObject();
	
	NLSFONEDATA     stIndep[2];
	stIndep[0].pdData = vX;
	stIndep[1].pdData = vY;	
	stIndep[0].nSize = stIndep[1].nSize = vX.GetSize();
	
	ONEDATAWEIGHT   stWeightIndep[2];
	stWeightIndep[0].stWeightData.pdData  = vWx;
	stWeightIndep[0].stWeightData.nSize = vWx.GetSize();
	stWeightIndep[0].method = WEIGHT_DIRECT;
	stWeightIndep[0].a = stWeightIndep[0].b = stWeightIndep[0].c = 0;
	
	stWeightIndep[1].stWeightData.pdData  = vWy;
	stWeightIndep[1].stWeightData.nSize = vWy.GetSize();
	stWeightIndep[1].method = WEIGHT_DIRECT;
	stWeightIndep[1].a = stWeightIndep[1].b = stWeightIndep[1].c = 0;
		
	nn = fit.SetData(1, NULL, &stIndep, NULL, &stWeightIndep);
	if(nn != 0)
	{
		out_str("SetData() failed!");
		return;
	}
	
	// 3. Setting paramaters //////////////////////////////////////////////////
	int				nNumParams = 4;	
	vector			vParams(nNumParams);	// this vector should be initialized to the total number of paramaters
	// This vector will be used both to set initial paramater values, and to receive the parameter values after fitting:
	vParams[0] = 1;		//xc
	vParams[1] = 2;		//yc
	vParams[2] = 3;		//a
	vParams[3] = 2;		//b
	nn = fit.SetParams(nNumParams, vParams);
	if ( 0 != nn )
	{
		out_str("Invalid paramater setting!");
		return;
	}
 
 
	///////////////////////////////////////////////////////////////////////////
	// 4. Fitting /////////////////////////////////////////////////////////////
	int				nMaxNumIterations = 100;
	nn = fit.Fit(nMaxNumIterations, NULL, NULL, NULL, FITMETH_ORTHOGONAL_DISTANCE_REGRESSION);
	printf("Fit(%ld) returned: %ld\n", nMaxNumIterations, nn);
	if( 0 == nn )
		printf("Fit Done!\n");	
 
	/////////////////////////////////////////////////////////////////////////////
	// 5. Dump all the results and compare with what was expected /////////////
	for (int iparam = 0; iparam < nNumParams; iparam++)
	{
		printf("param index = %d   value obtained = %lf\n", iparam + 1, vParams[iparam]);
	}
 
	return;	
}