I met this problem when I was using fmincon(). I try to optimize a function handle at starting point 8, but my function handle has structure "log(exp(-100*x))", this leads to -inf rather than -100*x. How can I overcome this problem?
조회 수: 1 (최근 30일)
이전 댓글 표시
In my case, I got "Error using barrier (line 22) Objective function is undefined at initial point. Fmincon cannot continue." It seems this problem can simply happen when, say, you do some operations and combinations and get a structure like log(exp(-100*x)). It seems how can I deal with extreme large number?
댓글 수: 0
채택된 답변
Walter Roberson
2016년 2월 4일
Face it, your users might be... mistaken... about the limits of computer mathematics, and might choose to include things like power(x^1000,1/1000), which algebraically is just abs(x) for real numbers but in finite precision computing is going to overflow.
Therefore for any user provided function which you have not stripped apart bit by bit and proven the validity of, you should turn on FunValCheck to catch that the user specified something that was unworkable in practice. And you try/catch and you make the user submit something valid instead. Which might require that they think and clean up log(exp(x)) themselves.
If you have the symbolic toolbox, you could also use simplify() on the given expression before you use it, which will catch at least some of the inefficiencies.
댓글 수: 3
Walter Roberson
2016년 2월 5일
If you are using matlabFunction from the Symbolic Toolbox, then look at the 'vars' option, as it allows you to package multiple named variable into a vector argument.
추가 답변 (2개)
Star Strider
2016년 2월 4일
Well, since log(exp(-100*x)) is (-100*x), why not just go with that?
댓글 수: 4
Star Strider
2016년 2월 4일
This code:
f='(x(1)^(p(1)-1)*exp(-x(1)/p(2)))/(p(2)^p(1)*gamma(p(1)))';
for i=1:n
eval(['L=@(p)L(p)+feval(@(x)log(',f,'),sample(i,:));']);
end
is really painful to look at! I can’t figure out what you’re doing in it (other than recursively calling your ‘L’ function, that is never a good idea), so I can’t suggest a better way to code it, other than to begin by creating an anonymous function for ‘f’:
f = @(p,x) (x(1).^(p(1)-1).*exp(-x(1)/p(2)))./(p(2)^p(1)*gamma(p(1)));
and then just calling it rather than using eval and feval.
Start by describing what you’re doing there. Then I might be able to suggest an alternative.
John D'Errico
2016년 2월 4일
편집: John D'Errico
2016년 2월 4일
First of all, you should almost NEVER optimize a likelihood function.
Always optimize the log of the likelihood. It will be better behaved. If you find an optimum of one, then you find the optimum of the other.
Your problem now goes away. So what is the problem?
Oh, gosh, it looks like you are taking the log of individual terms. However, I am fairly confident that the log of this expression can be written in simple form:
(x(1)^(p(1)-1)*exp(-x(1)/p(2)))/(p(2)^p(1)*gamma(p(1)))
Start here:
help gammaln
So as it turns out, you are taking the log likelihood, but then not making use of high school algebra. For god's sake, that is why you take the log!
Hint:
log(x(1))*(p(1)-1) - x(1)/p(2) - log(p(2))*p(1) - gammaln(p(1))
So really, where is the problem? You "overcome the problem" by not creating the problem in the first place! This is why you work with the log-likelihood function instead!
I won't even start on the unreadable code fragment that you do show in a comment. (I'm sorry, but the code frag you show looks like MATLAB gone wild. An obscene way to write what should be a simple expression. Whoever gave you that code fragment should be shot, and no reason to wait until dawn.)
You use eval and feval for some completely irrational and obscure reason. This will be incredible inefficient, impossible to read, buggy, & impossible to debug. Also it appears as if you are passing in an entire column (sample(i,:)) into the function, but then only using sample(i,1). Perhaps sample is only a vector, and you don't understand how indexing works. (From reading one of your comments, it appears that sample is indeed a vector.)
Learn to use function handles (properly). The one function handle that you create is inside an eval statement, where you use L twice in a seemingly recursive fashion. Shiver. I tried to read what you had done in that code fragment, but it makes my head hurt.
As a wild guess, this MIGHT do what that code fragment does, as a function handle with p as an argument, using the workspace variable sample indirectly.
fun = @(p ) sum(log(sample)*(p(1)-1) - sample/p(2) - log(p(2))*p(1) - gammaln(p(1)));
I would check it however, if I were you, since I had a terribly hard time reading your fragment.
댓글 수: 7
Walter Roberson
2016년 2월 4일
FunValCheck triggers an error(). It is basically a sanity check to allow you to exit early from a calculation that is already fatally tainted. Your linear and nonlinear constraints should already be blocking out all the places that your objective is invalid, and FunValCheck is to deal with the places you overlooked in your analysis. FunValCheck is not an additional constraint layer to allow you to avoid a particular point: it is a check to say "This calculation is FUBAR, just stop already".
참고 항목
카테고리
Help Center 및 File Exchange에서 Whos에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!