The Origin Forum
File Exchange
Try Origin for Free
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
Username:
Password:
Save Password
Forgot your Password? | Admin Options

 All Forums
 Origin Forum for Programming
 Forum for Origin C
 Fitting with NLFitSession
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

couturier

France
291 Posts

Posted - 07/09/2020 :  11:20:54 AM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
Origin Ver. and Service Release (Select Help-->About Origin): 2020b
Operating System:win10 64bit

Hi,

I have some troubles fixing parameters with PWL3 fit function.
Here's my code:
bool ASP_VO2_fit_PWL3(vector vX, vector vY, vector& vParam, double dXval, int fix)
{
	NLFitSession nlfS;
	nlfS.SetFunction("PWL3");
	nlfS.SetData(vY, vX);
	
	// Initialisation
	vector vParamValues(6);
    vector<int> vnParamsOffsets(6); // the begin index of one group of parameters, normally one group for one dataset
    
	nlfS.ParamsInitValues();
	nlfS.GetParamValuesAndOffsets(vParamValues, vnParamsOffsets);
	
	if (fix > 0) // if fix xi1 or xi2
	{
		if (fix == 1) // fix xi1
		{
			vParamValues[2] = dXval;
			nlfS.SetParamFix(2, true);
		}
		if (fix == 2) // fix xi2
		{
			vParamValues[4] = dXval;
			nlfS.SetParamFix(4, true);
		}
		nlfS.SetParamValues(vParamValues);
	}
    
    // Fit
    vector vErr(6);
    
	if (nlfS.Fit())
	{
		nlfS.GetFitResultsParams(vParam, vErr);
		return true;
	}
	
	return false;
}


if fix = 0, fitting should be free
if fix = 1, I want to fix xi1 (3rd parameter) as dXval
if fix = 2, I want to fix xi2 (4th parameter) as dXval

When fix > 0, I get different result than fix = 0, but xi1 or xi2 are not fixed to dXval

What am I doing wrong ?

Bonus question:
I tried NLFit Class and got results 10 times faster.
But I couldn't find how to fix parameters.
Is it possible ?

Castiel

343 Posts

Posted - 07/10/2020 :  01:28:34 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by couturier

Origin Ver. and Service Release (Select Help-->About Origin): 2020b
Operating System:win10 64bit

Hi,

I have some troubles fixing parameters with PWL3 fit function.
Here's my code:
bool ASP_VO2_fit_PWL3(vector vX, vector vY, vector& vParam, double dXval, int fix)
{
	NLFitSession nlfS;
	nlfS.SetFunction("PWL3");
	nlfS.SetData(vY, vX);
	
	// Initialisation
	vector vParamValues(6);
    vector<int> vnParamsOffsets(6); // the begin index of one group of parameters, normally one group for one dataset
    
	nlfS.ParamsInitValues();
	nlfS.GetParamValuesAndOffsets(vParamValues, vnParamsOffsets);
	
	if (fix > 0) // if fix xi1 or xi2
	{
		if (fix == 1) // fix xi1
		{
			vParamValues[2] = dXval;
			nlfS.SetParamFix(2, true);
		}
		if (fix == 2) // fix xi2
		{
			vParamValues[4] = dXval;
			nlfS.SetParamFix(4, true);
		}
		nlfS.SetParamValues(vParamValues);
	}
    
    // Fit
    vector vErr(6);
    
	if (nlfS.Fit())
	{
		nlfS.GetFitResultsParams(vParam, vErr);
		return true;
	}
	
	return false;
}


if fix = 0, fitting should be free
if fix = 1, I want to fix xi1 (3rd parameter) as dXval
if fix = 2, I want to fix xi2 (4th parameter) as dXval

When fix > 0, I get different result than fix = 0, but xi1 or xi2 are not fixed to dXval

What am I doing wrong ?

Bonus question:
I tried NLFit Class and got results 10 times faster.
But I couldn't find how to fix parameters.
Is it possible ?


In NLFitSession, you should have called SetParamValues() before SetParamFix(), for example:

if(fix == 1)
{
    vParamValues[2] = dXval;
    nlfS.SetParamValues(vParamValues);
    nlfS.SetParamFix(2, true);
}


In NLFit, you can have parameters fixed by calling
int NLFit::SetParams(int nNumParamValues, double *pdParamValues, int *pbShared = NULL, bool *pbFixed = NULL, bool bLoadBoundsFromFunctions = true);


For example:

int nNumParamValues = vParamValues.GetSize();
vector<bool> vbFixed(nNumParamValues);
vbFixed = false;
if(fix == 1)
{
    vParamValues[2] = dXval;
    vbFixed[2] = true;
}
fit.SetParams(nNumParamValues, &vParamValues[0], NULL, &vbFixed[0], true);



                                          &&&&&&&&&
                                        &&&
                                       &&
                                      &  _____ ___________
                                     II__|[] | |   I I   |
                                    |        |_|_  I I  _|
                                   < OO----OOO   OO---OO
**********************************************************
Go to Top of Page

couturier

France
291 Posts

Posted - 07/11/2020 :  09:14:14 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Thanx a lot Castiel, it works great now

I switched to NLFit and it is MUCH faster than NLFitSession

That brings another question:
I have another function for fitting 2 datasets, with some fixed parameters and parameters sharing.

I have no idea on how to use ParamInit() for such a case.
Only examples I could find where like
int nErr;
fn.ParamInit( vParams, vX, vY, nErr );

For now, I'm using my previous function ASP_VO2_fit_PWL3() on each dataset to get initial values, but I guess I could use ParamInit() ?

thanx
Go to Top of Page

couturier

France
291 Posts

Posted - 07/12/2020 :  09:44:37 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
And one last thing (hopefully ):
How to set constraints ?
I want to keep my parameters within a given range
Go to Top of Page

Castiel

343 Posts

Posted - 07/13/2020 :  05:57:42 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by couturier

Thanx a lot Castiel, it works great now

I switched to NLFit and it is MUCH faster than NLFitSession

That brings another question:
I have another function for fitting 2 datasets, with some fixed parameters and parameters sharing.

I have no idea on how to use ParamInit() for such a case.
Only examples I could find where like
int nErr;
fn.ParamInit( vParams, vX, vY, nErr );

For now, I'm using my previous function ASP_VO2_fit_PWL3() on each dataset to get initial values, but I guess I could use ParamInit() ?

thanx



Yes, you could use that method:
BOOL NumericFunction::ParamInit(vector& vParams, vector& vIndependent, vector& vDependent, int& nErr = NULL, ParamInitContext& ctxt = NULL);


There are many examples in <exe>\OriginC\system\ONLSF.h you could follow (unless there are mutiple indeps/deps.)

To set constraints, call
BOOL NLFit::SetParametersBounds(BOOL bUpper, double *pdBoundsValues, bool *pbExclusive, int nNumBounds);



                                          &&&&&&&&&
                                        &&&
                                       &&
                                      &  _____ ___________
                                     II__|[] | |   I I   |
                                    |        |_|_  I I  _|
                                   < OO----OOO   OO---OO
**********************************************************
Go to Top of Page

couturier

France
291 Posts

Posted - 07/13/2020 :  09:21:08 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
There are many examples in <exe>\OriginC\system\ONLSF.h you could follow (unless there are mutiple indeps/deps.)

Yes, I had seen them
quote:
you could use that method:
BOOL NumericFunction::ParamInit(vector& vParams, vector& vIndependent, vector& vDependent, int& nErr = NULL, ParamInitContext& ctxt = NULL);

The thing is I have 2 dependent vectors.
Didn't see any example about that

quote:
To set constraints, call

BOOL NLFit::SetParametersBounds(BOOL bUpper, double *pdBoundsValues, bool *pbExclusive, int nNumBounds);

\OriginC\system\ONLSF.h is quite cryptic to me
How pdBoundsValues are arranged ? all lowers and the all uppers, uppers - lowers ?

In the function initially posted, how could I set xi1 to be greater than Xmin+value1, and lower than Xmax-value2, and xi2 to be greater than Xmin+value3, and lower than Xmax-value3 ?


Go to Top of Page

Castiel

343 Posts

Posted - 07/14/2020 :  05:11:05 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Originally posted by couturier

quote:
There are many examples in <exe>\OriginC\system\ONLSF.h you could follow (unless there are mutiple indeps/deps.)

Yes, I had seen them
quote:
you could use that method:
BOOL NumericFunction::ParamInit(vector& vParams, vector& vIndependent, vector& vDependent, int& nErr = NULL, ParamInitContext& ctxt = NULL);

The thing is I have 2 dependent vectors.
Didn't see any example about that

quote:
To set constraints, call

BOOL NLFit::SetParametersBounds(BOOL bUpper, double *pdBoundsValues, bool *pbExclusive, int nNumBounds);

\OriginC\system\ONLSF.h is quite cryptic to me
How pdBoundsValues are arranged ? all lowers and the all uppers, uppers - lowers ?

In the function initially posted, how could I set xi1 to be greater than Xmin+value1, and lower than Xmax-value2, and xi2 to be greater than Xmin+value3, and lower than Xmax-value3 ?






For multiple independents/dependents, to initialize parametes:
BOOL NumericFunction::ParamInit(vector& vParams, vector *pvIndeps, vector *pvDeps, int& nErr = NULL, ParamInitContext& ctxt = NULL);

to set fitting data:
int NLFit::SetData(int nNumberDatasetSets, NLSFONEDATA *pstDependentData, NLSFONEDATA *pstdIndependentData, ONEDATAWEIGHT *pWeightDep = NULL, ONEDATAWEIGHT* pWeightIndep = NULL);


Say, the fitting function has 2 independent (x1 & x2) and 2 dependents (y1, y2),

Step-1: initialize parameters in NumericFunction

/*
vector x1, x2;  // independents
vector y1, y2;  // dependents
*/

vector vIndeps[2];
vIndeps[0] = x1;
vIndeps[1] = x2;

vector vDeps[2];
vDeps[0] = y1;
vDeps[1] = y2;

vector vParams;
BOOL bRet = nf.ParamInit(vParams, &vIndeps[0], &vDeps[0], NULL, NULL);


Step-2: set data to NLFit

/*
NLFit fit;
*/

NLSFONEDATA stIndependentData[2], stDependentData[2];
stIndependentData[0].pdData = &x1[0];
stIndependentData[0].nSize = x1.GetSize();
stIndependentData[1].pdData = &x2[0];
stIndependentData[1].nSize = x2.GetSize();
stDependentData[0].pdData = &y1[0];
stDependentData[0].nSize = y1.GetSize();
stDependentData[1].pdData = &y2[0];
stDependentData[1].nSize = y2.GetSize();

int nDatasets = 1;
int nRet = fit.SetData(nDatasets, &stDependentData[0], &stIndependentData[0], NULL, NULL);



Regarding the parameters bounds, you can call the following method twice to setup upper bounds and lower bounds respectively, depending on the value of the first parameter "bUpper":
BOOL NLFit::SetParametersBounds(BOOL bUpper, double *pdBoundsValues, bool *pbExclusive, int nNumBounds);
;


                                          &&&&&&&&&
                                        &&&
                                       &&
                                      &  _____ ___________
                                     II__|[] | |   I I   |
                                    |        |_|_  I I  _|
                                   < OO----OOO   OO---OO
**********************************************************
Go to Top of Page

couturier

France
291 Posts

Posted - 07/14/2020 :  08:35:40 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
struggled a bit, but it works

thanks a lot, you're da boss !!!
Go to Top of Page
  Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000