Author |
Topic |
|
couturier
France
291 Posts |
Posted - 07/09/2020 : 11:20:54 AM
|
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
|
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
**********************************************************
|
|
|
couturier
France
291 Posts |
Posted - 07/11/2020 : 09:14:14 AM
|
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 |
|
|
couturier
France
291 Posts |
Posted - 07/12/2020 : 09:44:37 AM
|
And one last thing (hopefully ): How to set constraints ? I want to keep my parameters within a given range |
|
|
Castiel
343 Posts |
Posted - 07/13/2020 : 05:57:42 AM
|
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
**********************************************************
|
|
|
couturier
France
291 Posts |
Posted - 07/13/2020 : 09:21:08 AM
|
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 ?
|
|
|
Castiel
343 Posts |
Posted - 07/14/2020 : 05:11:05 AM
|
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
**********************************************************
|
|
|
couturier
France
291 Posts |
Posted - 07/14/2020 : 08:35:40 AM
|
struggled a bit, but it works
thanks a lot, you're da boss !!! |
|
|
|
Topic |
|
|
|