How to find the minimum value of the function of two variables e.g sin(x)*cos(y), and plot it with surf?

8 views (last 30 days)
How to find the minimum value of the function of two variables e.g sin(x)*cos(y), and plot it with surf? I must use fminsearch. I tried to do it alone:
clear all
clc
clear
f = @(x)sin(x(1)*cos(x(2)))
x0 = [rand,rand];
[xmin, fval] = fminsearch(f,x0)
x = linspace(-10,10,10);
y = linspace(-10,10,10);
[X,Y] = meshgrid(x,y)
fun = sin(X)*cos(Y);
surf(X,Y,fun)
hold on
plot3(xmin(1),xmin(2), f(xmin), 'g*', 'MarkerSize', 5)
but it works bad. Any ideas to help me? :(

Accepted Answer

Star Strider
Star Strider on 19 Oct 2017
Your code just needs a bit of tweaking to do what you want:
f = @(x,y) sin(x).*cos(y);
x0 = [rand,rand];
[xmin, fval] = fminsearch(@(x)f(x(1),x(2)), x0)
x = linspace(-10,10,50);
y = linspace(-10,10,50);
[X,Y] = meshgrid(x,y);
surf(X,Y,f(X,Y), 'EdgeColor','none', 'FaceAlpha',0.5)
hold on
plot3(xmin(1),xmin(2), f(xmin(1),xmin(2)), 'gp', 'MarkerSize', 10, 'MarkerFaceColor','g')
hold off
xlabel('X')
ylabel('Y')
You have essentially the correct approach. Your ‘f’ function needs to easily accommodate two arguments in order to do the surface plot. The marker plots below the surface plot, so I made it a bit more visible, and I eliminated the edges and increased the transparency of the surface in order to see it.
  2 Comments
Harvester
Harvester on 19 Oct 2017
Thank you very much, all works properly! But I dont know one thing, would be great if u can explain:
in 3rd line of your code:
3. [xmin, fval] = fminsearch(@(x)f(x(1),x(2)), x0)
9. plot3(xmin(1),xmin(2), f(xmin(1),xmin(2))
Why must be:
@(x)f(x(1),x(2))
not just f? and same in the plot 3 - why:
f(xmin(1),xmin(2))
Just tell me why it must work like that.
Star Strider
Star Strider on 19 Oct 2017
My pleasure.
In order to use ‘f’ to both plot the surf plot and use in fminsearch (creating one function instead of two), I created it to have two arguments. (Your original code would have worked had you not also wanted to do a surface plot.)
Then to use it in fminsearch, I did essentially what you did originally and called it as ‘@(x)f(x(1),x(2))’.
Because it now has two arguments, I had to use two arguments in every other call to it in surf and plot3.
Your original code for ‘f’ using a vector ‘x’ works correctly for fminsearch and plot3, but will not work with matrix arguments in the surf call. That is the reason I re-wrote it as I did.

Sign in to comment.

More Answers (1)

Harvester
Harvester on 22 Oct 2017
Okay, I understand, thanks :) And have last question: what i need to do to plot maximum instead of minimum?
  1 Comment
Star Strider
Star Strider on 22 Oct 2017
My pleasure.
The easiest way is to negate the function argument to fminsearch:
[xmax, fval] = fminsearch(@(x) -f(x(1),x(2)), x0)
That creates the minimum as a maximum (negative minimum), and will find the minimum (or maximum) closest to your starting parameter estimates.
You might want to change all the variable names incorporating ‘min’ to names incorporating ‘max’ for clarity instead, as I did with the first output from fminsearch here, changing ‘xmin’ to ‘xmax’. That is your choice.
Note that if you want all the maxima or minima, you will need to run your code for each one in your parameter space. This requires choosing the appropriate initial parameter estimates, likely running your code in a loop (or nested loops) for each region.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!