MATLAB Answers

pietro
0

problems in passing parameters to fminsearchbnd.

Asked by pietro
on 27 Mar 2015
Latest activity Commented on by pietro
on 28 Mar 2015
Hi all,
I have to fit some data and I'm using fminsearchbnd. Unfortunately the solver doesn't convergence and I have discovered that at the first iteration the design variable of myfunFitting function are different than the one supplied through the starting point. How may it be possible? Below you can find my code.
Thank you
Regards
Pietro
x1=[76.2; 766.0; 842.5; 842.5; 1044.0; 1044.0; 1070.3; 987.0; ...
99.2;996.2;1095.7;1081.1;1182.8;1090.8;1070.3;987.0;1315.5;1213.1;...
117.3;1081.1;1182.8;1090.8;1070.3;987.0];
y2=[1845.697674; 2255;1845.697674;2255;1845.697674;2255;1845.697674;...
2255;1845.697674;2255;1845.697674;2255;1845.697674;2255;1845.697674;...
Target=[18196;13906;8209;6274;1913;1462;1444;1900;3054;2334;1377;1053;732;963;1444; ...
1900;360;173;778;1024;732;963;1444;1900];
x0=[1.790851e10,3];
lb=[1 0];
ub=[1e40 20];
x0a=(x0-lb)./(ub-lb);
lba=zeros(size(lb));
uba=ones(size(ub));
f=@(x)myfunFitting(x,Target,x1,x2,lb,ub);
Aeq=zeros(2,2);
beq=zeros(2,1);
[xout fval,exitflag]=fminsearchbnd(f,x0a,lba,uba)

  3 Comments

You forgot to include myfunFitting. Also, the creation of the variable 'TargetLife' is not shown.
So many things strange or even just flat out bad in this code.
Why are you passing in bounds into your objective function?
Why are you defining a variable named exp in your code? This is just a flat out bad idea, as it will cause you to have a nasty bug one day, when you try to use the useful function exp, so your next question will be to ask why the exponential function no longer works in your code.
Next, setting bounds so wide will surely cause a problem. Do you really expect to see parameter values that are as large as 1e40?
Do you appreciate that the difference between the numbers ub-lb when one of them is 1e40, and the second is 1, is not well computed in double precision arithmetic?
I can probably go on and on, those are just a few things I noticed after a very quick glance. However without seeing what model you are actually trying to fit, I must stop at some point.
(Oh, as for fminsearchbnd changing the parameter from your starting values, that is due to the obscenely wide bounds you have set. Double precision arithmetic fails when you try to use dynamic ranges of 40 powers of 10. Sorry, but if you can make a better guess than that for your parameters about what they are, then expect code to have problems.)
The problem here is not fminsearchbnd, but some of the many strange things you are doing.
Thanks for your kind replies.
there were few mistakes in the code and I fixed them. exp and a are two flag variables and they can be deleted in the part of included code .
The design variables are scaled so both of them ranges from 0 to 1. For this reason I pass the bounds arrays inside the objective function.
Here the objective function:
function f=myfunFitting(xa,Target,x1,x2,lb,ub)
x=xa.*(ub-lb)+lb;
Calc=x(1)./(x2.*(x1).^x(2));
f=sum(Calc-Target).^2;
end

Sign in to comment.

1 Answer

Answer by John D'Errico
on 27 Mar 2015

So now we know why it is that your optimization is not working well. Here is your objective function.
function f=myfunFitting(xa,Target,x1,x2,lb,ub)
x=xa.*(ub-lb)+lb;
Calc=x(1)./(x(2).*(x1).^x(2));
f=sum(Calc-Target).^2;
end
So you are trying to fit a model of the form
z = A/(B*y*x^B)
Where A and B are unknowns, and x and y are the independent variables.
Claim 1: Models with a single term that are the product of multiple variables like this almost ALWAYS need to be logged. The estimation is always easier, in fact, often trivial.
Claim 2: Whenever you have problems with huge orders of magnitudes involved, you should ALWAYS consider if you should be working with logs instead.
Lets see how that works here.
log(z) = log(A) - (log(B) + log(y) + B*log(x))
Rewrite this to look like...
log(z) + log(y) = log(A) - log(B) - B*log(x)
Now, think about it. Do you know the value of A? Do you know the value of B? Of course not. You are estimating them. So trivially, we can use the transformation
C = log(A) - log(B)
Putting it in a classic form...
log(z) - log(y) = C + B*(-log(x))
Use polyfit to determine B and C.
Here, we have x1 as x as I wrote it, y2 as y, and Target as z.
BC = polyfit(-log(x1),log(Target) + log(y2),1);
B = BC(1);
A = exp(BC(2) + log(B));
Sadly, I can't actually test this out on your data, because while you gave 24 elements in the vectors x1 and Target, there are only 15 in y2. The best that I can do is this:
BC = polyfit(-log(x1(1:15)),log(Target(1:15)) + log(y2),1)
BC =
0.61077 19.467
B = BC(1);
A = exp(BC(2) + log(B))
A =
1.7393e+08
That your data seems not to fit this model terribly well? Hey, it is your data and your choice of model.
Regardless, you should see that never did I need anything sophisticated to solve your problem. In fact, no serious optimization was ever needed. If you truly wanted to do an optimization, the above scheme would in the very least allow good starting values to be employed, but IF I actually wanted to do this as an optimization, the hugely wide bounds you have used would make that optimization totally unworkable even with the incredibly good starting values you will get from polyfit.
And finally, I would point out that had you defined exp as a variable in your workspace, the last line as I wrote it would now fail. Again, this is why that is a bad thing.

  1 Comment

Hi John,
Thanks for your reply, I did it as you suggested and it worked great. Just two question, is it fine how I have scaled the two variables? Why in my optimization at the first iteration the design variables are different than the starting point?
Thanks
Cheers

Sign in to comment.