I should point out that these tools use fminsearch as the optimizer, just providing an overlay on top to implement constraints. That means that any parameters that fminsearch ignores are ignored here too. So diffminchange and diffmaxchange are completely irrelevant.
I can't really test out what is happening since I don't have any data. But I looked at the code, and usually when you get a nan as a result, it comes from some parameter going into a bad place.
So I'd put some debugging effort into the code, letting you drop in with the debugger as soon as a nan gets generated. Do one of these before you execute the code:
dbstop if naninf
I'm a bit confused why you are calling det on a diagonal matrix too. That would be far more efficiently done as simply the product of the elements. And since you are then computing the log of the determinant, do it as the sum of the logs of the elements, avoiding potential underflows or overflows.
Anyway, before you do any optimizations, always test your objective function. Make sure that it does what you expect, that it yields valid results, and that the results change when you perturb the parameters. Next, when you run an optimizer and you see strange things happening, set the "Display" option in the optimizer to 'iter'. In fact, I always do this on every optimization the first time I run one for any problem. Verify that it is doing something intelligent. Are the parameters changing? (Note that fminsearchbnd transforms the parameters, so that fminsearch is working with different numbers than you expect.)
And, finally, 9 parameters is at the very upper limit of what I'd ever recommend for a Nelder-Mead based tool, but it should run, albeit a bit slowly.
Dear John, very nice function! It worked very well. I have used it in my optimization problems. However, in my last code I get a problem. The output is NaN and the function parameters seem not optimized. Perhaps you you may help me... Here is my code. I get the necessary data from an excel table.
I cannot realize where the problem is. Thanks in advance! Cheers
function [H,par,output]=mygarch()
format short
data=xlsread('select3stocks.xlsx',2,'A1:D249');
data1=data(1:149,:);
data2=data(150:199,:);
[L1, L2]=size(data2);
C0=[0.01,0.02,0.03]';
A0=[0.04,0.02,0.06]';
B0=[0.05,0.09,0.03]';
matr=[C0,A0,B0];
par0=reshape(matr,1,9);
X=zeros(L1-1,L2);
m=mean(data2);
X(1,:)=data2(1,:)-m;
s=0;
H=zeros(L1-1,L2);
H(1,:)=(std(data1)).^2;
lb=zeros(1,9);
ub=ones(1,9);
options =optimset('MaxIter',50000,'TolX',1e-10,'DiffMaxChange',0.00005,'DiffMinChange',0.00001,'MaxFunEvals',10000000);
[par,output]=fminsearchbnd(@maxlikelyhood,par0,lb,ub,options);
function y=maxlikelyhood(par)
C=par(1:3); A=par(4:6); B=par(7:9);
for i=2:L1
for j=1:L2
H(i,j)=C(j)+A(j)*X(i-1,j)^2+B(j)*H(i-1,j);
end
X(i,:)=data2(i,:)-m;
D=diag(H(i,:));
s=s+3*log(2*pi)+log(det(D))+X(i,:)*D.^(-2)*X(i,:)';
end
y=s;
end
end
(I've fixed the bug about the outputfcn problem and re-posted it. The new version should appear sometime this morning.)
As far as Stefan's problem goes, anytime you throw problems with variables that vary by 20 to 30 powers of 10 at ANY numerical optimizer, expect serious things to go wrong. This is a no-no for literally ANY numerical tool. And setting a convergence tolerance (TolX) to eps is just as silly, especially when your parameters vary by that many orders of magnitude.
Essentially, you are asking that one variable, which can apparently vary somewhere between 1 and 1e30, must be computed to an absolute accuracy of roughly 2e-16.
A common solution is to normalize your variables, so that both are at least of similar orders of magnitude. If you were trying to solve a problem where one variable had bounds of 1e20 to 5e20, and a second variable was bounded in the interval 1e-6 to 1e-5, then normalizing the variables to both be of order 1 would make complete sense. But your variables each vary by many powers of 10!
One thing all novices need to learn about computing, is that when things vary by that many powers of 10, is to use logs! Let fminsearch vary the log10 of your variables, so they now have bound vectors that look like [0, -6] for the lower bounds, and [30, 0] for the upper bound. Now, inside your function, take the parameters and raise 10 to that power BEFORE they are used. Do the same with the output when it is returned. As far as fminsearch is concerned, your numbers are perfectly normal looking, but your objective sees the numbers in their proper scales.
You will find that any optimizer runs much more happily when you do this, as now the variables are very nicely normalized. All of the mathematics works more simply when you work in the log space. In fact, this is surely the natural way to work with variables that vary by many powers of 10. A nice consequence is the tolerances in TolX become relative tolerances on the variables, something that surely makes much more sense.
And DON'T use eps as a convergence tolerance. Fminsearch will never be able to give you even a reasonable shot at convergence in even 10000 function evals with that fine of a tolerance. So what happens is fminsearch will keep on iterating until it runs out of function evaluations. Use a meaningful, realistic tolerance. You were probably only setting that fine of a tolerance because of the ridiculous variable scaling anyway.
Comment only