Matlab gamma function: I get Inf for large values - matlab

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.

Related

I wrote a function for a math formula, may I ask you please check my code?

For my research, I needed to calculate some formula. I create a function for it. This is the very first time for me to write a function and also the first time to write a math formula in Matlab language. May I please ask you to check if where I do wrong?
Here is formula
And here is the function I wrote (P is x and P^ is y):
function biass = BIASS(x,y)
%This function calculates biass error
% Detailed explanation goes here
H = sum(y-x)/sum(y)
biass = H * 100
end
I'm not sure about results because I believe they are not reasonable.
If y is P^, then you should write H = sum(y-x)/sum(x), not H = sum(y-x)/sum(y).
A slightly more efficient way to compute this is
100 * (sum(y) / sum(x) - 1)
since your expression can be simplified.

matlab help in finding dimensions

Can anybody help me with this assignment please?
I am new to matlab, and passing this year depends on this assignment, i don't have much time to explore matlab and i already wasted alot of time trying to do this assignment in my way.
I have already wrote the equations on the paper, but transfering the equations into matlab codes is really hard for me.
All i have for now is:
syms h
l = (0.75-h.^2)/(3*sqrt((5*h.^2)/4)); %h is h_max
V_default = (h.^2/2)*l;
dv = diff(V_default); %it's max. when the derivative is max.
h1 = solve( dv ==0);
h_max = (h1>0);
l_max = (0.75-h_max.^2)/(3*sqrt((h_max/2).^2+(h_max.^2)));
V_max = ((h_max.^2)./(2.*l_max));
but it keep give me error "Error using ./
Matrix dimensions must agree.
Error in triangle (line 9)
V_max = ((h_max.^2)./(2.*l_max)); "
Not really helping with the assignment here, but with the Matlab syntax. In the following line:
l_max = (0.75-h_max.^2)/(3*sqrt((h_max/2).^2+(h_max.^2)));
you're using / that is a matrix divide. You might want to use ./ which will divide the terms element by element. If I do this
l_max = (0.75-h_max.^2) ./ (3*sqrt((h_max/2).^2+(h_max.^2)));
then your code doesn't return any error. But I have no idea if it's the correct solution of your assignment, I'll leave that to you!
In line 5, the result h1 is a vector of two values but the variable itself remains symbolic, from the Symbolic Math Toolbox. MATLAB treats such variables slightly different. For that reason, the line h_max = (h1>0) doesn't really do what you expect. As I think from this point, you are interested in one value h_max, I would convert h1 to a regular MATLAB variable and change your code to the following:
h1 = double(solve( dv ==0)); % converts symbolic to regular vectors
h_max = h1(h1>0); % filters out all negative and zero values
l_max = (0.75-h_max.^2)/(3*sqrt((h_max/2).^2+(h_max.^2)));
V_max = ((h_max.^2)./(2.*l_max));
EDIT.
If you still have error, it means solve( ...) returns more than 1 positive values. In this case, as suggested, use dotted operations, such as ./ but the results in l_max and V_max will not be a single value but vectors of the same size as h_max. Which means you don't have one max Volume.

Writing a function in matlab syntax

I wrote a function named "Maximizing Gross margin" that is used in agriculture. The formula is like this:
max sigma(i=1 to n) sigma(j=1 to nc) (Pij * Yij - SDij ... (and so on) ) ...
full formula in this link:
http://i.stack.imgur.com/fMSiU.jpg
I think it doesn't have the real matlab's syntax and it is not really calculates the maximum. And there are two other formulas that I want to mix with this and link them to the evolutionary algorithm (NSGA-II) and I really don't know how, although I confused myself searching for it.
This is my function in matlab:
function gx = costfunction( p,y,sd,fer,lb,oc,a,wp,Q,ma)
SigmaQNC = zeros(5,3);
SigmaNC = zeros(5,3);
for i=1:5
for j=1:3
SigmaQNC(i,j) = SigmaQNC(i,j) + Q(i,1);
SigmaNC(i,j) = (p(i,j).*y(i,j))-(sd(i,j)-fer(i,j)-lb(i,j)-oc(i,j)-ma(i,j)).*a(i,j)-wp(i,j).*SigmaQNC(i,j);
sort(SigmaNC);
end
end
gx=SigmaNC;
end
The question is, how to really write it in matlab syntax and how to link these three formulas to NSGA-II with the limitations (like min Aij <= percentage Aij <= max Aij )
Any kind of help would be appreciated.
Yes, your formula is not in MATLAB syntax. If I understood correctly, you want to maximize this objective function which is done by NSGA-II with other objective functions. For optimization max f = -min f.

Solve equation with exponential term

I have the equation 1 = ((π r2)n) / n! ∙ e(-π r2)
I want to solve it using MATLAB. Is the following the correct code for doing this? The answer isn't clear to me.
n= 500;
A= 1000000;
d= n / A;
f= factorial( n );
solve (' 1 = ( d * pi * r^2 )^n / f . exp(- d * pi * r^2) ' , 'r')
The answer I get is:
Warning: The solutions are parametrized by the symbols:
k = Z_ intersect Dom::Interval([-(PI/2 -
Im(log(`fexp(-PI*d*r^2)`)/n)/2)/(PI*Re(1/n))], (PI/2 +
Im(log(`fexp(-PI*d*r^2)`)/n)/2)/(PI*Re(1/n)))
> In solve at 190
ans =
(fexp(-PI*d*r^2)^(1/n))^(1/2)/(pi^(1/2)*d^(1/2)*exp((pi*k*(2*i))/n)^(1/2))
-(fexp(-PI*d*r^2)^(1/n))^(1/2)/(pi^(1/2)*d^(1/2)*exp((pi*k*(2*i))/n)^(1/2))
You have several issues with your code.
1. First, you're evaluating some parts in floating-point. This isn't always bad as long as you know the solution will be exact. However, factorial(500) overflows to Inf. In fact, for factorial, anything bigger than 170 will overflow and any input bigger than 21 is potentially inexact because the result will be larger than flintmax. This calculation should be preformed symbolically via sym/factorial:
n = sym(500);
f = factorial(n);
which returns an integer approximately equal to 1.22e1134 for f.
2. You're using a period ('.') to specify multiplication. In MuPAD, upon which most of the symbolic math functions are based, a period is shorthand for concatenation.
Additionally, as is stated in the R2015a documentation (and possibly earlier):
String inputs will be removed in a future release. Use syms to declare the variables instead, and pass them as a comma-separated list or vector.
If you had not used a string, I don't think that it would have been possible for your command to get misinterpreted and return such a confusing result. Here is how you could use solve with symbolic variables:
syms r;
n = sym(500);
A = sym(1000000);
d = n/A;
s = solve(1==(d*sym(pi)*r^2)^n/factorial(n)*exp(-d*sym(pi)*r^2),r)
which, after several minutes, returns a 1,000-by-1 vector of solutions, all of which are complex. As #BenVoigt suggests, you can try the 'Real' option for solve. However, in R2015a at least, the four solutions returned in terms of lambertw don't appear to actually be real.
A couple things to note:
MATLAB is not using the values of A, d, and f from your workspace.
f . exp is not doing at all what you wanted, which was multiplication. It's instead becoming an unknown function fexp
Passing additional options of 'Real', true to solve gets rid of most of these extraneous conditions.
You probably should avoid calling the version of solve which accepts a string, and use the Symbolic Toolbox instead (syms 'r')

Evaluate Matlab symbolic function

I have a problem with symbolic functions. I am creating function of my own whose first argument is a string. Then I am converting that string to symbolic function:
f = syms(func)
Lets say my string is sin(x). So now I want to calculate it using subs.
a = subs(f, 1)
The result is sin(1) instead of number.
For 0 it works and calculates correctly. What should I do to get the actual result, not only sin(1) or sin(2), etc.?
You can use also use eval() to evaluate the function that you get by subs() function
f=sin(x);
a=eval(subs(f,1));
disp(a);
a =
0.8415
syms x
f = sin(x) ;
then if you want to assign a value to x , e.g. pi/2 you can do the following:
subs(f,x,pi/2)
ans =
1
You can evaluate functions efficiently by using matlabFunction.
syms s t
x =[ 2 - 5*t - 2*s, 9*s + 12*t - 5, 7*s + 2*t - 1];
x=matlabFunction(x);
then you can type x in the command window and make sure that the following appears:
x
x =
#(s,t)[s.*-2.0-t.*5.0+2.0,s.*9.0+t.*1.2e1-5.0,s.*7.0+t.*2.0-1.0]
you can see that your function is now defined by s and t. You can call this function by writing x(1,2) where s=1 and t=1. It should generate a value for you.
Here are some things to consider: I don't know which is more accurate between this method and subs. The precision of different methods can vary. I don't know which would run faster if you were trying to generate enormous matrices. If you are not doing serious research or coding for speed then these things probably do not matter.