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)
Show older comments
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? :(
0 Comments
Accepted Answer
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
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.
More Answers (1)
Harvester
on 22 Oct 2017
1 Comment
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.
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!