Is there equivalent function to fminbnd for maximum value? - matlab

I am doing homework in Matlab, calculating numeric integration using different methods like simpson, etc. I need to find value n from formulas for error of method like this one for rectangle method
E = (b-a)/24 * max f''(x) * ((b-a)/n)^2
n = sqrt(((b-a)^3 * max f''(x)) / 24 * E)
problem is finding function for finding maximum value of f''(x) in range a to b.
I have only found fminbnd, which calculates minimum value of function in range. Is there function which would calculate maximum value?

Look for the minimum of -f''(x) (the negative of the function you want to maximize).

Related

Finding minimum of max function, subject to constraint, in MATLAB

Ok, so I have a function that takes the maximum of a 16 different functions. I want to find the minimum of this function subject to the condition that this function is equal to another function. This is what the code looks like, (H1,...,H16 are all column vectors):
function f = opt(a,b,c)
F1 = a*mean(H1) + b*var(H1)+ c*skewness(H1);
...*more functions here*...
F15 = a*mean(H15) + b*var(H15)+ c*skewness(H15);
F16 = a*mean(H16) + b*var(H16)+ c*skewness(H16);
FVEC = [F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,F14,F15,F16];
[ max, max_index ] = max(FVEC);
f = max;
end
The constraint I want it basically that the above function should be equal to the first one in the list:
opt(a,b,c) = a*mean(H1) + b*var(H1)+ c*skewness(H1)
I think I'm supposed to use fmincon, but despite my repeated attempts, I seem to be running into issues, plus it does not look like it supports constraints depending on another function (although I might be misreading the docs). Is this the right function to use? What is the best way to approach this problem? I am very new to MATLAB and, so, I'm not familiar with what a typical approach would look like.
The max function is non-differentiable. Most solvers expect smooth functions (including fmincon). Luckily there is a simple linear formulation:
min y
y >= v(i) for all i
y will automatically assume the largest value of the v(i).
Your constraint would be
y = v(1)
In this case we can even drop the min y.
This would enforce the first set of observations to be the maximum v. I am not sure, but this could lead to an infeasible model (if it cannot arrange a,b,c in such a way).

Calculating a definite integral results in a really complex numerical expression instead of a numerical value

I am trying to calculate the percentage of sun radiation that is in the visible spectrum.
My code is:
h=6.626e-34; %planck constant
c=3e8; %speed of light
k=1.38066e-23; %boltzman constant
T1=5777; %temperature in surface of sun
syms f
J1 =(2*pi*h/(c^2))*((f^3)/(exp((h*f)/(k*T1))-1)); %planck radiation law
hold on;
ezplot(J1,[0,1.5e15])
a=int(J1,f,0,inf) %total energy radiated
b=int(J1,f,4e14,8e14) %energy between 400-800Thz (visible radiation spectrum)
Vp = (b/a)*100 %percentage of visible/total radiation
While the plot is exactly as it was expected to be, meaning i haven't totally messed it up, the result of the integrals is like this:
Vp = -1888568826285205004703258735621345426367059580820393216707788800000000000*((73396718487075910602267519716779133887030184268951416015625*log(1 - exp(23642358029674224853515625/7114894705749824515342336)))/205953985278202888163058116890711980917418253877248 - (73396718487075910602267519716779133887030184268951416015625*log(1 - exp(23642358029674224853515625/3557447352874912257671168)))/25744248159775361020382264611338997614677281734656 - (2390487322005187985890576650155251369405251302897930145263671875*polylog(2, exp(23642358029674224853515625/3557447352874912257671168)))/1857466834100924357302864708366291649120175241251782656 + (25952248522181378144831874533777514511468878135769288445192954296875*polylog(3, exp(23642358029674224853515625/3557447352874912257671168)))/67008813354583054015095330308295397033299967000474002915328 - (110058495767576691259417256590823904271799518678985866399923893187011219092083*polylog(4, exp(23642358029674224853515625/3557447352874912257671168)))/1888568826285205004703258735621345426367059580820393216707788800000000 + (2390487322005187985890576650155251369405251302897930145263671875*polylog(2, exp(23642358029674224853515625/7114894705749824515342336)))/7429867336403697429211458833465166596480700965007130624 - (25952248522181378144831874533777514511468878135769288445192954296875*polylog(3, exp(23642358029674224853515625/7114894705749824515342336)))/134017626709166108030190660616590794066599934000948005830656 + (110058495767576691259417256590823904271799518678985866399923893187011219092083*polylog(4, exp(23642358029674224853515625/7114894705749824515342336)))/1888568826285205004703258735621345426367059580820393216707788800000000 + 101409666798338314597227594049400067888200283050537109375/22835963083295358096932575511191922182123945984))/(12228721751952965695490806287869322696866613186553985155547099243001246565787*pi^4)
It is just a numerical expression (does not contain any constants) but i was expecting (and I am trying to find) a single value.
Any ideas how to overcome this?
Thanks in advance
double(Vp)
returns 44.3072 which is exactly what I was looking for while
vpa(Vp)
returns 44.307238264260285485868531074049 + 1.5008384323384489567473242679822e-35*i which is overcomed by
norm(vpa(Vp))
giving the same result as double(Vp)
However when i added a few more lines of code:
d=int(J1,f,0,4e14); %infrared energy
e=int(J1,f,8e14,inf); %ultraviolet energy
Ir = (d/a)*100; %percentage of infrared radiation
Uv = (e/a)*100; %percentage of ultraviolet radiation
double(Ir) gives this error:
Error using mupadmex
Error in MuPAD command: DOUBLE cannot convert the input expression into a double array.
If the input expression contains a symbolic variable, use the VPA function instead.
Error in sym/double (line 514)
Xstr = mupadmex('symobj::double', S.s, 0);
Error in symplanckradlaw (line 21)
Infrared=double(Ir)
While vpa(Ir) and even norm(vpa(Ir)) are given complicated complex numerical expressions like this
(abs(7.3340024900713941224341547032249e-56*limit((652255981594442743874468745505068648842285814001516463259648*f^2*polylog(2, exp((3873563939581825*f)/466281739436020499437475332096)))/15004497594028668398955870330625 - (608270107310811468411217054651916403272252179121058584901915330886243977872955782952124416*f*polylog(3, exp((3873563939581825*f)/466281739436020499437475332096)))/58120880811771703455030054556291506586990890625 - f^4/4 + (466281739436020499437475332096*f^3*log(1 - exp((3873563939581825*f)/466281739436020499437475332096)))/3873563939581825 + (283625243683820020974472587101002022201492492463545426687503953676410023626686775978867575742611811818507908158310055936*polylog(4, exp((3873563939581825*f)/466281739436020499437475332096)))/225134948049212098682315198853176286979563186266469146812890625, f == 0, Right) - 146.24549829953781858190522266202 - 2.501397387230748261245540446637e-36*i)^2)^(1/2)
You can convert it to a double using, well: double:
Vp_double = double(Vp)
You can also use vpa if you want to choose the precision:
Vp_vpa = vpa(Vp)
The reason why you get that immensely long expression is because MATLAB managed to find a "closed form definite integral". I.e. MATLAB managed to find an expression that accurately calculate the integral with no rounding errors. This is not always possible, and you'll get an error:
Warning: Explicit integral could not be found.
If that happens then you should try the approach given in this answer.
For some reason Matlab while was able to evaluate the limits in this integral
a=int(J1,f,0,inf)
it had problems evaluating limit to 0 in this integral
d=int(J1,f,0,4e14);
and limit to infinite in this integral
e=int(J1,f,8e14,inf);
I worked around this by putting instead of 0 a very low value (1e-45) and instead of infinite a very large one (1e22).
I got very good results for my purposes but I still find it really strange that matlab can evaluate the limits in one case but cannot evaluate the same limits in another case.

what is the correct way to calculate the "double's range"?

In 64 bits platform, the double's range are following:
-2.22507e-308 ~ +2.22507e-308
-1.79769e+308 ~ +1.79769e+308
and I followed the IEEE754 standard and tried to calculate the double's range by following equation,
x = (-1)^s * (1+fraction) * 2^(exponent-bias)
So I tried to calculate in 64 bits platform, but I am not sure the following whether it is right?
Since the bias is 1024, the max value of double can be calculated by following:
(1-2^-52) * 2^(2^11 - 1024) = 2.22507e-308
It seems right...
but when I calculate the min value of double by the same way
(1-2^-52) * 2^-(1024-1)) = 1.1125369292536007e-308,
1024 -1 (minus 1 is for zero bit?))
the result is not correct... so I wonder what is correct way to calculate double's range by hand.
Thank in advance.
Max (substitute any sensible type):
std::numeric_limits<double>::max()
Min (called "lowest" in C++11 because min meant something else, see comments):
std::numeric_limits<double>::lowest()

Matlab gamma function: I get Inf for large values

I am writing my own code for the pdf of the multivariate t-distribution in Matlab.
There is a piece of code that includes the gamma function.
gamma((nu+D)/2) / gamma(nu/2)
The problem is that nu=1000, and so I get Inf from the gamma function.
It seems I will have to use some mathematical property of the gamma
function to rewrite it in a different way.
Thanks for any suggestions
You can use the function gammaln(x), which is the equivalent of log(gamma(x)) but avoids the overflow issue. The function you wrote is equivalent to:
exp(gammaln((nu+D)/2) - gammaln(nu/2))
The number gamma(1000/2) is larger than the maximum number MATLAB support. Thus it shows 'inf'. To see the maximum number in MATLAB, check realmax. For your case, if D is not very large, you will have to rewrite your formula. Let us assume that in your case 'D' is an even number. Then the formula you have will be: nu/2 * (nu/2 -1) * ....* (nu/2 - D/2 + 1).
sum1 = 1
for i = 1:D/2
sum1 = sum1*(nu/2 - i+1);
end
Then sum1 will be the result you want.

Matlab, graphing functions

I have a homework problem, I think I did it correctly but need to make sure 100%. Can anyone check for me, before I hand it in?
Thank you.
Question:
Plot the function given by f (x) = 2 sin(2x) − 3 cos(x/2) over the in-
terval [0, 2π] using steps of length .001 (How?). Use the commands max and min to estimate the maximum and minimum points. Include the maximum and minimum points as tick marks on the x-axis and the maximum and minimum values as tick marks on the y-axis.
My code:
x=linspace(0,2*pi,6280);
f=#(x)...
2.*sin(2.*x)-3.*cos(x./2);
%f = #(x)2.*sin(2.*x)-3.*cos(x./2)
g=#(x)...
-1*(2.*sin(2.*x)-3.*cos(x./2));
%g = #(x)-1*(2.*sin(2.*x)-3.*cos(x./2))
[x3,y5]=fminbnd(g,0,2*pi);
%x3 = 4.0968
%y3 = -3.2647
[x2,y4]=fminbnd(f,0,2*pi);
%x2 =2.1864
%y2 = -3.2647
y2=max(f(x));
y3=min(f(x));
plot(x,f(x));
set(gca,'XTick',[x2 x3]);
set(gca,'YTick',[y2 y3]);
(*after I paste this code here, it appeared not as nice as I had it in my program, don't know why)
To create a vector with certain step do
x=0:0.001:2*pi;
Why do you have g(x) function and why are you using fminbind? Use MIN and MAX, return index of those values and find related x values.
[ymin, minindex] = min(f(x));
xmin = x(minindex);
For general case if you have multiple min/max values, index will contain only the first occurrence. Instead you can do:
minindex = find(y==ymin);
Or for real values to avoid precision error:
minindex = find(abs(y-ymin)<=eps);
Also your last statement returns error Values must be monotonically increasing. To avoid it sort your tick values.
set(gca,'XTick',sort([xmin xmax]));
set(gca,'YTick',sort([ymin ymax]));