I'm having difficulty with a fitting problem. From the errors that I get I imagine that the boundaries are not defined correctly and I haven't managed to find a solution. Any help would be very much appreciated.
Alternative methods for the solution of the same problem are also accepted.
I have to estimate the parameters of a non-linear function of the type:
A*y(x) + B*EXP(C*y(x)) + g(x,D) = 0
subjected to the parameters PAR = [A,B,C,D]
being within the range
LB < PAR < UB
To solve the problem I'm using the Matlab functions lsqnonlin
and fzero
. The simplified code used is reported below.
The problem is divided in four functions:
parameterEstimation
- (a wrapper for the lsqnonlin function)objectiveFunction_lsq
- (the objective function for the param estimation)yFun
- (the function returing the value of the variable y)objectiveFunction_zero
- (the objective function of the non-linear equation used to calculate y)Running the code on the data I get the this waring
Warning: Length of lower bounds is > length(x); ignoring extra bounds
and this error
Failure in initial user-supplied objective function evaluation. LSQNONLIN cannot continue
This makes me to think that the boundaries are not correctly used or not correctly called, but maybe the problem is elsewhere.
function Done = parameterEstimation()
%read inputs
Xmeas = xlsread('filepath','worksheet','range');
Ymeas = xlsread('filepath','worksheet','range');
%inital values and boundary conditions
initialGuess = [1,1,1,1]; %model parameters initial guess
LB = [0,0,0,0]; %model parameters lower boundaries
UB = [2,2,2,2]; %model parameters upper boundaries
%parameter estimation
calcParam = lsqnonlin(@objectiveFunction_lsq_2,initialGuess,LB,UB,[],Xmeas,Ymeas);
Done = calcParam;
function diff = objectiveFunction_lsq_2(PAR,Xmeas,Ymeas)
y_calculated = yFun(PAR,Xmeas);
diff = y_calculated-Ymeas;
function result = yFun(PAR,X)
y_0 = 2;
val = fzero(@(y)objfun_y(y,PAR,X),y_0);
result = val;
function result = objfun_y(y,PAR,X)
A = PAR(1);
B = PAR(2);
A = PAR(3);
C = PAR(4);
D = PAR(5);
val = A*y+B*exp(y*C)+g(D,X);
result = val;
I don't have the optimization toolbox, but are you sure you can pass the constants like that?
I would do this instead:
calcParam = lsqnonlin(@(PAR) objectiveFunction_lsq_2(PAR,Xmeas,Ymeas),initialGuess,LB,UB);