MATLAB Answers

0

Problem optimizing anonymous function using fzero

Asked by George Katoufas on 10 Jun 2019
Latest activity Answered by Alan Weiss
on 12 Jun 2019
I have a bunch of functions that i am trying to find an optimum solution to using the fzero tool. All the functions are like this one:
fun=@(t) (-10+1/size(t,1)*sum((t-o).^2-10*cos(2*pi*(t-o))+10)), meaning they have sum or prod in them and some trigonometric functions like sin or cos, with t and o taking values from matrixes of 30 values. What i am trying to do is exclude one of the values of the t matrix (for example the 5th) and make it an uknown value in order to tend the function to 0. I have tried a lot of ways with using symbolic variables and functions being the most promising until now. The program goes like this:
fun=@(t) (-10+1/size(t,1)*sum((t-o).^2-10*cos(2*pi*(t-o))+10))
k=x(5);
symx= sym(x(:));
symx(5)=sym('y');
funzero=matlabFunction(fun(symx));
t(5)= fzero(funzero,k);
This code works for the easier functions but doesn't woth for harder functions like the one above. The problem that fzero pops is this:
Exiting fzero: aborting search for an interval containing a sign change
because NaN or Inf function value encountered during search.
(Function value at 1.03725e+154 is -Inf.)
Check function or try again with a different starting value.
I have tried multiple codes and tried to alter the values of matrix t in order to have a better starting value. Changing the way the function is written isn't a solution as this code is a piece of a very larger program and although i can be sure that the function will be the way it is described above i cannot interact with it.

  2 Comments

Plot the function.
It may not have any real roots, and fzero cannot find complex roots.
I have run a test by putting all the values of the matrix and setting one of them as unknown to test whether it was a problem of coding or there was no real roots. fzero found the value i was looking for so i came to the conclusion that there is a root but i am having trouble coding it right in order to find it!

Sign in to comment.

2 Answers

Answer by John D'Errico
on 10 Jun 2019

There is no need to use symbolic tools to solve problems via fzero, merely understanding how to use functions. However, your question is confusing.
I think you are saying, you want to perform a minimization that uses existing variables s and t. (I won't use o as a variable name. That is a terrible programming pattern to employ, as it will lead to bugs, when you mistake the variable o with the number 0.) Then, I'll replace element 5 of the variable t with an unknown. Again, ABSOLUTELY no need to use symbolic tools.
One little helper function, that will on the fly replace a specific element or elements of a vector or array.
function vec = replace_elem(vec,newelem,replaceind)
% return the vector of array in vec, but with the specified element(s)
% replaced by newelem. This works for vectors or arrays, and it will
% handle multiple replacements.
vec(replaceind) = newelem;
end
I could probably have done that using a function handle, but an m-file is easy too.
s = rand(1,30);
t = rand(1,30);
replind = 5;
fun=@(tnew) sum(replace_elem(t,tnew,replind) - s);
[tnew,fv,exitflag] = fzero(fun,1)
tnew =
1.06426863686432
fv =
-1.11022302462516e-16
exitflag =
1
The function I created was a trivial one. But you were asking a generic question.

  1 Comment

Hello and thanks for the answer.
I have tried doing what you suggested with the test function i wrote above. As i said before i can't rewrite the function so i altered what you suggested like this:
fun=@(t) (-10+1/size(t,1)*sum((t-s).^2-10*cos(2*pi*(t-s))+10))
funzero=@(tnew) fun(replace_elem(t,tnew,replind))
When i called the fzero like there was the same NaN problem poping up. I used it to some other functions i am trying to minimize but yet again the same problem came up.

Sign in to comment.


Answer by Alan Weiss
on 12 Jun 2019

The way that fzero works is it first tries to bracket a root (find points on either side of the root having different function signs) and then close in on the root. Clearly, what is happening is that in its search for points with differing function signs, fzero encounters a point where the function is not defined or is complex.
The solution is for you to do some prework for fzero. Instead of giving it initial points, give it initial intervals, where the endpoints of the intervals have different function signs. I understand, it is not always easy to come up with such initial intervals, but I believe that is what you need to do to get a successful, robust method of finding roots.
Good luck,
Alan Weiss
MATLAB mathematical toolbox documentation

  0 Comments

Sign in to comment.