How to use fminsearch to find local maximum? - matlab

I would like to use fminsearch in order to find the local maximum of a function.
Is it possible to find local maximum using fminsearch with "just" searching on the negative return value of the function.
for example:
function f = myfun(x,a)
f = x(1)^2 + a*x(2)^2;
a = 1.5;
x = fminsearch(#(x) -1 * myfun(x,a),[0,1]);
Is it possible?
Update1: In order to elaborate my question and making it clearer (following some comments below) - I'm adding this update:
By asking if it's possible to do so, I meant is it a proper use of fminsearch function - is it the intended use to find max using fminsearch?
Update2: for who ever concern with the same question - In addition to the correct answer below , here is the documentation from https://www.mathworks.com/help/matlab/math/optimizing-nonlinear-functions.html#bsgpq6p-10
Maximizing Functions
The fminbnd and fminsearch solvers attempt to minimize an objective function. If you have a maximization problem, that is, a problem of the form
max x f(x), then define g(x) = –f(x), and minimize g.
For example, to find the maximum of tan(cos(x)) near x = 5, evaluate:
[x fval] = fminbnd(#(x)-tan(cos(x)),3,8)
x = 6.2832
fval = -1.5574
The maximum is 1.5574 (the negative of the reported
fval), and occurs at x = 6.2832. This answer is correct since, to five
digits, the maximum is tan(1) = 1.5574, which occurs at x = 2π =
6.2832.

Yes you can, that's also why there is no fmaxsearch function:
For example:
func = #(x) sin(x);
sol = fminsearch(#(x) func(x),0)
% sol = pi/2
sol = fminsearch(#(x) func(x)*-1,0)
% sol = -pi/2

Related

Definite integration using int command

Firstly, I'm quite new to Matlab.
I am currently trying to do a definite integral with respect to y of a particular function. The function that I want to integrate is
(note that the big parenthesis is multiplying with the first factor - I can't get the latex to not make it look like power)
I have tried plugging the above integral into Desmos and it worked as intended. My plan was to vary the value of x and y and will be using for loop via matlab.
However, after trying to use the int function to calculate the definite integral with the code as follow:
h = 5;
a = 2;
syms y
x = 3.8;
p = 2.*x.^2+2.*a.*y;
q = x.^2+y.^2;
r = x.^2+a.^2;
f = (-1./sqrt(1-(p.^2./(4.*q.*r)))).*(2.*sqrt(q).*sqrt(r).*2.*a-p.*2.*y.*sqrt(r)./sqrt(q))./(4.*q.*r);
theta = int(f,y,a+0.01,h) %the integral is undefined at y=2, hence the +0.01
the result is not quite as expected
theta =
int(-((8*461^(1/2)*(y^2 + 361/25)^(1/2))/5 - (461^(1/2)*y*(8*y + 1444/25))/(5*(y^2 + 361/25)^(1/2)))/((1 - (4*y + 722/25)^2/((1844*y^2)/25 + 665684/625))^(1/2)*((1844*y^2)/25 + 665684/625)), y, 21/10, 5)
After browsing through various posts, the common mistake is the undefined interval but the +0.01 should have fixed it. Any guidance on what went wrong is much appreciated.
The Definite Integrals example in the docs shows exactly this type of output when a closed form cannot be computed. You can approximate it numerically using vpa, i.e.
F = int(f,y,a,h);
theta = vpa(F);
Or you can do a numerical computation directly
theta = vpaintegral(f,y,a,h);
From the docs:
The vpaintegral function is faster and provides control over integration tolerances.

Finding the maximum value from an expression using a loop in Matlab

I want to find the maximum value using the second derivative of the the expression when x is between 0 and 1. In other words I am taking the derivative of cox(x^2) twice to get the second derivative resulting in - 2*sin(x^2) - 4*x^2*cos(x^2), then I want to evaluate this second derivative at x = 0 to x = 1, and display the maximum value of the populated values.
I have:
syms x
f = cos(x^2);
secondD = diff(diff(f));
for i = 0:1
y = max(secondD(i))
end
Can someone help?
You can do it easily by subs and double:
syms x
f = cos(x^2);
secondD = diff(diff(f));
% instead of the for loop
epsilon = 0.01;
specified_range = 0:epsilon:1;
[max_val, max_ind] = max(double(subs(secondD, specified_range)));
Please note that it is a numerical approach to find the maximum and the returned answer is not completely correct all the time. However, by increasing the epsilon, you can expect a better result in general (again in some cases it is not completely correct).

How to resolve MATLAB trapz function error?

I am working on an assignment that requires me to use the trapz function in MATLAB in order to evaluate an integral. I believe I have written the code correctly, but the program returns answers that are wildly incorrect. I am attempting to find the integral of e^(-x^2) from 0 to 1.
x = linspace(0,1,2000);
y = zeros(1,2000);
for iCnt = 1:2000
y(iCnt) = e.^(-(x(iCnt)^2));
end
a = trapz(y);
disp(a);
This code currently returns
1.4929e+03
What am I doing incorrectly?
You need to just specify also the x values:
x = linspace(0,1,2000);
y = exp(-x.^2);
a = trapz(x,y)
a =
0.7468
More details:
First of all, in MATLAB you can use vectors to avoid for-loops for performing operation on arrays (vectors). So the whole four lines of code
y = zeros(1,2000);
for iCnt = 1:2000
y(iCnt) = exp(-(x(iCnt)^2));
end
will be translated to one line:
y = exp(-x.^2)
You defined x = linspace(0,1,2000) it means that you need to calculate the integral of the given function in range [0 1]. So there is a mistake in the way you calculate y which returns it to be in range [1 2000] and that is why you got the big number as the result.
In addition, in MATLAB you should use exp there is not function as e in MATLAB.
Also, if you plot the function in the range, you will see that the result makes sense because the whole page has an area of 1x1.

Solve Lognormal equation for mu and sigma given fixed y and x in Matlab

I have the equation of the lognormal:
y = 1/(3.14*x*sig)*exp(-(log(x)-mu)^2/(2*sig^2))
and for fixed
y = a
x = b
I need to find the values of mu and sig. I can set mu in Matlab like:
mu = [0 1 1.1 1.2...]
and find all the values corresponding sig values, but I can't make it with solve or subs. Any ideas please???
Thanks!
Here's a proof of concept to use fzero to numerically search for a sigma(x,y,mu) function.
Assuming you have x,y fixed, you can set
mu = 1; %or whatever
myfun = #(sig) y-1./(3.14*x*sig).*exp(-(log(x)-mu)^2./(2*sig.^2)); %x,y,mu from workspace
sigma = fzero(myfun,1);
This will solve the equation
y-1/(3.14*x*sig)*exp(-(log(x)-mu)^2/(2*sig^2))==0
for sig starting from sig==1 and return it into sigma.
You can generalize it to get a function of mu:
myfun2 = #(mu,sig) y-1./(3.14*x*sig).*exp(-(log(x)-mu).^2./(2*sig.^2));
sigmafun=#(mu) fzero(#(sig)myfun2(mu,sig),1);
then sigmafun will give you a sigma for each value of mu you put into it. The parameters x and y are assumed to be set before the first anonymous function declaration.
Or you could get reaaally general, and define
myfun3 = #(x,y,mu,sig) y-1./(3.14*x*sig).*exp(-(log(x)-mu).^2./(2*sig.^2));
sigmafun2 = #(x,y,mu) fzero(#(sig)myfun3(x,y,mu,sig),1);
The main difference here is that x and y are fed into the function of sigmafun2 each time, so they can change. In the earlier cases the values of x and y were fixed in the anonymous functions at the time of their definition, i.e. when we issued myfun = #(sig).... Depending on your needs you can find out what you want to use.
As a proof of concept, I didn't check how well it behaved for the actual problem. You should definitely have an initial idea of what kind of parameters you expect, since there will be many cases where there's no solution, and fzero will return a NaN.
Update by Oliver Amundsen: the resulting sig(mu) function with x=100, y=0.001 looks like this:

Finding unknown limit of integration in MATLAB

I have an equation of the form c = integral of f(t)dt limiting from a constant to a variable (I don't want to show the full equation because it is very long and complex). Is there any way to calculate in MATLAB what the value of that variable is (there are no other variables and the equation is too difficult to solve by hand)?
Assume your limit is from cons to t and g(t) as your function with variable t. Now,
syms t
f(t) = int(g(t),t);
This will give you the indefinite integral. Now f(t) will be
f(t) = f(t)+f(cons);
You have the value of f(t)=c. So just solve the equation
S = solve(f(t)==c,t,'Real',true);
eval(S) will give the answer i think
This is an extremely unclear question - if you do not want to post the full equation, post an example instead
I am assuming this is what you intend: you have an integrand f(x), which you know, and has been integrated to give some constant c which you know, over the limits of x = 0, to x = y, for example, where y may change, and you desire to find y
My advice would be to integrate f(x) manually, fill in the first limit, and subtract that portion from c. Next you could employ some technique such as the Newton-Ralphson method to iteratively search for the root to your equation, which should be in x only
You could use a function handle and the quad function for the integral
myFunc = #(t) exp(t*3); % or whatever
t0 = 0;
t1 = 3;
L = 50;
f = #(b) quad(#(t) myFunc(t,b),t0,t1);
bsolve = fzero(f,2);
Hope it help !