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!