Effectiently evaluate symbolic expression in Matlab 2013 - matlab

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().

Related

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.

How to get Gamma function in Mathematica using 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

Why is Matlab saving values as symbolic variables with massive fractions instead of decimal approximations?

I'm currently working on a rudimentary optimization algorithm in Matlab, and I'm running into issues with Matlab saving variables at ridiculous precision. Within a few iterations the variables are so massive that it's actually triggering some kind of infinite loop in sym.m.
Here's the line of code that's starting it all:
SLine = (m * (X - P(1))) + P(2);
Where P = [2,2] and m = 1.2595. When I type this line of code into the command line manually, SLine is saved as the symbolic expression (2519*X)/2000 - 519/1000. I'm not sure why it isn't using a decimal approximation, but at least these fractions have the correct value. When this line of code runs in my program, however, it saves SLine as the expression (2836078626493975*X)/2251799813685248 - 584278812808727/1125899906842624, which when divided out isn't even precise to four decimals. These massive fractions are getting carried through my program, growing with each new line of code, and causing it to grind to a halt.
Does anyone have any idea why Matlab is behaving in this way? Is there a way to specify what precision it should use while performing calculations? Thanks for any help you can provide.
You've told us what m and P are, but what is X? X is apparently a symbolic variable. So further computations are all done symbolically.
Welcome to the Joys of Symbolic Computing!
Most Symbolic Algebra systems represent numbers as rationals, $(p,q) = \frac{p}{q}$, and perform rational arithmetic operations (+,-,*,/) on these numbers, which produce rational results. Generally, these results are exact (also called infinite precision).
It is well-known that the sizes of the rationals generated by rationals operations on rationals grow exponentially. Hence, if you try to solve a realistic problem with any Symbolic Algebra system, you eventually run out of space or time.
Here is the last word on this topic, where Nick Trefethen FRS shows why floating point arithmetic is absolutely vital for solving realistic numeric problems.
http://people.maths.ox.ac.uk/trefethen/publication/PDF/2007_123.pdf
Try this in Matlab:
function xnew = NewtonSym(xstart,niters);
% Symbolic Newton on simple polynomial
% Derek O'Connor 2 Dec 2012. derekroconnor#eircom.net
x = sym(xstart,'f');
for iter = 1:niters
xnew = x - (x^5-2*x^4-3*x^3+3*x^2-2*x-1)/...
(5*x^4-8*x^3-9*x^2+6*x-2);
x = xnew;
end
function xnew = TestNewtonSym(maxits);
% Test the running time of Symbolic Newton
% Derek O'Connor 2 Dec 2012.
time=zeros(maxits,1);
for niters=1:maxits
xstart=0;
tic;
xnew = NewtonSym(xstart,niters);
time(niters,1)=toc;
end;
semilogy((1:maxits)',time)
So, from MATLAB reference documentation on Symbolic computations, the symbolic representation will always be in exact rational form, as opposed to decimal approximation of a floating-point number [1]. The reason this is done, apparently, is to "to help avoid rounding errors and representation errors" [2].
The exact representation is something that cannot be overcome by just doing symbolic arithmetic. However, you can use Variable-Precision Arithmetic (vpa) in Matlab to get the same precision [3].
For example
>> sym(pi)
ans =
0
>> vpa(sym(pi))
ans =
3.1415926535897932384626433832795
References
[1] http://www.mathworks.com/help/symbolic/create-symbolic-numbers-variables-and-expressions.html
[2]https://en.wikibooks.org/wiki/MATLAB_Programming/Advanced_Topics/Toolboxes_and_Extensions/Symbolic_Toolbox
[3]http://www.mathworks.com/help/symbolic/vpa.html

matlab genetic algorithm solver complex input and output

My Matlab program has multiple inputs as a struct (in.a, in.b, etc.)
and multiple outputs (out.a, out.b, etc.)
I would like to use the genetic algorithm solver from teh optimization toolbox to find the best input in.a, while all the other inputs are constant. The fitness is one of the outputs, e.g. out.b(2,3).
How do I "tell" the solver this?
Thanks
Daniel
It is not uncommon in programming to have a situation where what is most convenient for your function and what some library call expects of it don't agree. The normal resolution to such a problem is to write a small layer in between that allows the two to talk; an interface.
From help ga:
X = GA(FITNESSFCN,NVARS) finds a local unconstrained minimum X to the
FITNESSFCN using GA. [...] FITNESSFCN accepts a vector X of size
1-by-NVARS, and returns a scalar evaluated at X.
So, ga expects vector input, scalar output, whereas you have a structure going in and out. You would have to write the following (sub)function:
function Y = wrapper_Objfun(X, in)
in.a = X; %# variable being optimized
out = YOUR_REAL_FUNCTION(in); %# call to your actual function
Y = out.b(2,3); %# objective value
end
and then the call to ga will look like
X = ga(#(x) wrapper_Objfun(x,in), N);
where N is however large in.a should be.
Also have a read about it in Matlab's own documentation on the subject.

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.