How to get Gamma function in Mathematica using Matlab - matlab

In Mathematica, Gamma[a, z] refers to the upper incomplete Gamma function whereas in Matlab, gammainc(z, a) refers to the regularized lower incomplete Gamma function. I want to know how I can obtain the Mathematica result using Matlab? In this link, the method for obtaining same Matlab result using Mathematica was explained, but I couldn't find a strategy of getting one via Matlab.

You have several options. In addition to the version offered by #MarkMcClure
y = (1-gammainc(z,a)).*gamma(a)
you can also use additional arguments to get the upper regularized gamma function directly:
y = gammainc(z,a,'upper').*gamma(a)
Note that the order of the arguments is opposite to that of Mathematica's function.
The above are strictly numeric functions, but Mathematica's Gamma evaluates symbolically. You can use Matlab's igamma in the symbolic toolbox. Note that this function is not regularized and used the same argument order as Mathematica's function – it's as close to a direct equivalent as you'll find (but obviously slower for numeric evaluation):
syms a z;
y = igamma(a,z)
In older versions of Matlab, this function may not be directly available. You can however, still access the MuPAD version via:
y = feval(symengine,'igamma',a,z)
or something like
y = evalin(symengine,['igamma(' char(a) ',' char(z) ')'])

According to Wikipedia,
Thus, in Mathematica you might have
Gamma[1, 2] // N
While in Matlab you could have
gamma(1)-gammainc(2,1)
Both return 0.135335

Related

Minimizing Function with vector valued input in MATLAB

I want to minimize a function like below:
Here, n can be 5,10,50 etc. I want to use Matlab and want to use Gradient Descent and Quasi-Newton Method with BFGS update to solve this problem along with backtracking line search. I am a novice in Matlab. Can anyone help, please? I can find a solution for a similar problem in that link: https://www.mathworks.com/help/optim/ug/unconstrained-nonlinear-optimization-algorithms.html .
But, I really don't know how to create a vector-valued function in Matlab (in my case input x can be an n-dimensional vector).
You will have to make quite a leap to get where you want to be -- may I suggest to go through some basic tutorial first in order to digest basic MATLAB syntax and concepts? Another useful read is the very basic example to unconstrained optimization in the documentation. However, the answer to your question touches only basic syntax, so we can go through it quickly nevertheless.
The absolute minimum to invoke the unconstraint nonlinear optimization algorithms of the Optimization Toolbox is the formulation of an objective function. That function is supposed to return the function value f of your function at any given point x, and in your case it reads
function f = objfun(x)
f = sum(100 * (x(2:end) - x(1:end-1).^2).^2 + (1 - x(1:end-1)).^2);
end
Notice that
we select the indiviual components of the x vector by matrix indexing, and that
the .^ notation effects that the operand is to be squared elementwise.
For simplicity, save this function to a file objfun.m in your current working directory, so that you have it available from the command window.
Now all you have to do is to call the appropriate optimization algorithm, say, the quasi Newton method, from the command window:
n = 10; % Use n variables
options = optimoptions(#fminunc,'Algorithm','quasi-newton'); % Use QM method
x0 = rand(n,1); % Random starting guess
[x,fval,exitflag] = fminunc(#objfun, x0, options); % Solve!
fprintf('Final objval=%.2e, exitflag=%d\n', fval, exitflag);
On my machine I see that the algorithm converges:
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the optimality tolerance.
Final objval=5.57e-11, exitflag=1

Evaluating hypergeometric function with a vector in Matlab

I am using the generalized hypergeometric function in Matlab by calling hypergeom(a,b,z).
This function produces for a = 1 and a = 2, b = 2 and z = 5:
>>hypergeom(1,2,5)
29.4826318205153
>>hypergeom(2,2,5)
148.413159102577
Now, I want to evaluate the hypergeometric over a vector of a values. So if I enter hypergeom(1:2,2,5) I would expect the output:
[29.4826318205153, 148.413159102577]
However, when I enter this in Matlab I get:
>>hypergeom(1:2,2,5)
-0.25
So a single value is returned, for a vector of input values for a. How do I correctly call hypergeom in Matlab so that I get the same lenght of the output vector as the length of the input vector of a?
EDIT:
In this specific calculation I am evaluating the so-called Confluent hypergeometric function (solution to Kummer's differential equation, see: https://en.wikipedia.org/wiki/Confluent_hypergeometric_function). This is the 1F1 function. This means that length(N) = 1 and length(D) = 1.
The standard built-in function hypergeom is the generalized hypergeometric function, which does not allow the computation of hypergeom(1:2,2,5) in the way I want it.
Patrick Mousaw uploaded his Matlab code for the confluent hypergeometric function(https://nl.mathworks.com/matlabcentral/fileexchange/29766-confluent-hypergeometric-function), which is the version of the hypergeometric function I am using. A slight adaptation to his code, allowing for elementwise multiplication, returns exactly what I want. :)
I'm not entirely familiar with the generalised hypergeometric function, but it seems to me you have the function arguments the other way round, in terms of what is a 'parameter' (in the mathematical sense) and what is an 'input'. From the documentation:
HYPERGEOM(N, D, Z) is the generalized hypergeometric function F(N, D, Z),
also known as the Barnes extended hypergeometric function and denoted by
jFk where j = length(N) and k = length(D). For scalar a, b and c,
HYPERGEOM([a,b],c,z) is the Gauss hypergeometric function 2F1(a,b;c;z).
From wikipedia, I see the formula is:
So, as far as I understand it, this function is a vectorised function of the array Z, for parameter vectors
and
. I.e. to evaluate the generalised hypergeometric function for appropriate parameter vectors N and D, such that length(N)=5 and length(D)=2 (i.e.
) on a vector
, you'll call hypergeom(N,D,Z), and you should get an output vector of M elements out, one for each element of Z.
In this specific calculation I am evaluating the so-called Confluent hypergeometric function (solution to Kummer's differential equation, see: https://en.wikipedia.org/wiki/Confluent_hypergeometric_function). This is the 1F1 function. This means that length(N) = 1 and length(D) = 1.
The standard built-in function hypergeom is the generalized hypergeometric function, which does not allow the computation of hypergeom(1:2,2,5) in the way I want it.
Patrick Mousaw uploaded his Matlab code for the confluent hypergeometric function(https://nl.mathworks.com/matlabcentral/fileexchange/29766-confluent-hypergeometric-function), which is the version of the hypergeometric function I am using. A slight adaptation to his code, allowing for elementwise multiplication, returns exactly what I want. :)

How to solve an equation with piecewise defined function in Matlab?

I have been working on solving some equation in a more complicated context. However, I want to illustrate my question through the following simple example.
Consider the following two functions:
function y=f1(x)
y=1-x;
end
function y=f2(x)
if x<0
y=0;
else
y=x;
end
end
I want to solve the following equation: f1(x)=f2(x). The code I used is:
syms x;
x=solve(f1(x)-f2(x));
And I got the following error:
??? Error using ==> sym.sym>notimplemented at 2621
Function 'lt' is not implemented for MuPAD symbolic objects.
Error in ==> sym.sym>sym.lt at 812
notimplemented('lt');
Error in ==> f2 at 3
if x<0
I know the error is because x is a symbolic variable and therefore I could not compare x with 0 in the piecewise function f2(x).
Is there a way to fix this and solve the equation?
First, make sure symbolic math is even the appropriate solution method for your problem. In many cases it isn't. Look at fzero and fsolve amongst many others. A symbolic method is only needed if, for example, you want a formula or if you need to ensure precision.
In such an old version of Matlab, you may want to break up your piecewise function into separate continuous functions and solve them separately:
syms x;
s1 = solve(1-x^2,x) % For x >= 0
s2 = solve(1-x,x) % For x < 0
Then you can either manually examine or numerically compare the outputs to determine if any or all of the solutions are valid for the chosen regime – something like this:
s = [s1(double(s1) >= 0);s2(double(s2) < 0)]
You can also take advantage of the heaviside function, which is available in much older versions.
syms x;
f1 = 1-x;
f2 = x*heaviside(x);
s = solve(f1-f2,x)
Yes, the Heaviside function is 0.5 at zero – this gives it the appropriate mathematical properties. You can shift it to compare values other than zero. This is a standard technique.
In Matlab R2012a+, you can take advantage of assumptions in addition to the normal relational operators. To add to #AlexB's comment, you should convert the output of any logical comparison to symbolic before using isAlways:
isAlways(sym(x<0))
In your case, x is obviously not "always" on one side or the other of zero, but you may still find this useful in other cases.
If you want to get deep into Matlab's symbolic math, you can create piecewise functions using MuPAD, which are accessible from Matlab – e.g., see my example here.

Effectiently evaluate symbolic expression in Matlab 2013

I have a problem in numerical evaluation of symbolic expression. To simplify my question. I write the follow lines for an example.
syms a b c d e f
x = [a+b*c+d^e,b+log(c+d);exp(c)*b/c+f,f*c+e^2];
a = 2;
b = 3;
c = 1.5;
d = 1;
e = -2;
f = -1;
fx = eval(x);
x is a matrix the elements of which are symbolic expressions. I need to evaluate x given different values of [a,b,c,d,e,f] to get a numerical matrix fx. In my real program, such evaluation needs to be implemented million times and both the size of matrix x and the number of parameters (a,b,...,d) are much larger.
In Matlab 7.1, my program runs well. However, when I run it in Matlab 2013b, it becomes quite slow. I find that "eval(x)" runs faster in 7.1 than in 2013b due to their difference in default symbolic computation packages (Maple for 7.1 and MuPAD for 2013b).
So my question is that is there any more efficient way to evaluate a symbolic expression than using function "eval" in Matlab 2013b?
For symbolic computation, I recommend using subs() instead of eval(). You get full power and symbolic accuracy if you use subs().
When you use eval(), the symbolic expression would be converted to a character string (such as is displayed) and then the MATLAB parser and full runtime would be applied to calculate the meaning of the character string, using normal MATLAB double precision (or appropriate MATLAB numeric type). This process involves MATLAB using its JIT analyzer and so on. It is a bit "heavy handed" computationally.
See the MATLAB documentation here for subs().

Using unspecified constants in matlab

I'm trying to solve a system of equations in the s-domain. So set up this system of equations in matrix form:
a=[.4*s+s+5 -5; -5 .5*s+5]
c=[3/s; 3/(2*s)]
(1/s)*a*b=c
I just get the error that s is undefined.
How can I solve for b in terms of s?
Matlab does not (naturally) do symbolic calculations --- which is what your code is trying to do. Matlab's variables need to be concrete numbers, or arrays, or structures, etc. They cannot just be placeholders for arbitrary numbers.
(UNLESS: You use the symbolic computing toolbox for Matlab. I haven't really used this because I prefer to do symbolic computing in environments such as Maple or Mathematica. You could even solve your problem on the Wolfram Alpha website)
But if you pick a specific value of s, computing what you want is easy:
s = 5;
a=[.4*s+s+5 -5; -5 .5*s+5];
c=[3/s; 3/(2*s)];
b = s*(a\c);
Where I have used the backslash operator for doing linear inversion.
You should now have that
(1/s)*a*b-c
is the zero vector.
EDIT: I looked into the symbolic toolbox. It looks like this is what you want (but you need to have the symbolic toolbox licensed and installed for it to work):
syms s;
a=[.4*s+s+5 -5; -5 .5*s+5];
c=[3/s; 3/(2*s)];
b = simple(s*(a\c))
The code to perform your calculation using symbolic operators is:
syms s; %This defines 's' as a symbolic token
a=[.4*s+s+5 -5; -5 .5*s+5]; %a and c inherit the symbolic properties from s
c=[3/s; 3/(2*s)];
result = solve('(1/s)*a*b=c','b') %Solve is the general symbolic toolbox algebraic solver.
This produces
result =
(c*s)/a
Generally speaking, Matlab performs best as a numerical toolbox. So depending on your application I would go with another approach, such as that demonstrated by Ian Hincks in another answer. But sometimes the situation demands a symbolic solution.