Why does "pi" become symbolic in MATLAB? - matlab

In the Matlab command window I type:
syms f;
s = 2*pi*f*j;
s
which returns
s =
pi*f*2*j
Why is pi is not calculated as 3.141592...?What's wrong with the code I entered into the command window?

Welcome to symbolic math where you get exact answers as opposed to floating-point approximations. If you just want to "get a number" you can use non-symbolic functions and operations or you can convert symbolic results back to floating-point.
For example:
syms f
s = pi*f*2*j
s2 = subs(s,f,2)
s3 = double(s2)
Alternatively, you can use variable precision arithmetic to represent pi as a decimal approximation of a specified level in a symbolic expression:
syms f
s = vpa(pi)*f*j
See the documentation for vpa for further details. You can also use the sym function to achieve similar things.
However, you can lose some of the power of symbolic math if you convert to a decimal or floating point representation too soon. For example, compare the difference between the following expressions:
sin(pi) % 1.224646799147353e-16
sin(vpa(pi)) % -3.2101083013100396069547145883568e-40
sin(sym(pi)) % 0, sin(sym(1)*pi) and sin(sym(pi,'r')) also return zero
Only the last one will be fully cancelled out of an expression, thus simplifying it.

Related

Indefinite integration with Matlab's Symbolic Toolbox - complex solution

I'm using Matlab 2014b. I've tried:
clear all
syms x real
assumeAlso(x>=5)
This returned:
ans =
[ 5 <= x, in(x, 'real')]
Then I tried:
int(sqrt(x^2-25)/x,x)
But this still returned a complex answer:
(x^2 - 25)^(1/2) - log(((x^2 - 25)^(1/2) + 5*i)/x)*5*i
I tried the simplify command, but still a complex answer. Now, this might be fixed in the latest version of Matlab. If so, can people let me know or offer a suggestion for getting the real answer?
The hand-calculated answer is sqrt(x^2-25)-5*asec(x/5)+C.
This behavior is present in R2017b, though when converted to floating point the imaginary components are different.
Why does this occur?
This occurs because Matlab's int function returns the full general solution when you ask for the indefinite integral. This solution is valid over the entire domain of of real values, including your restricted domain of x>=5.
With a bit of math you can show that the solution is always real for x>=5 (see complex logarithm). Or you can use more symbolic math via the isAlways function to show this:
syms x real
assume(x>=5)
y = int(sqrt(x^2-25)/x, x)
isAlways(imag(y)==0)
This returns true (logical 1). Unfortunately, Matlab's simplification routines appear to not be able to reduce this expression when assumptions are included. You might also submit this case to The MathWorks as a service request in case they'd consider improving the simplification for this and similar equations.
How can this be "fixed"?
If you want to get rid of the zero-valued imaginary part of the solution you can use sym/real:
real(y)
which returns 5*atan2(5, (x^2-25)^(1/2)) + (x^2-25)^(1/2).
Also, as #SardarUsama points out, when the full solution is converted to floating point (or variable precision) there will sometimes numeric imprecision when converting from exact symbolic form. Using the symbolic real form above should avoid this.
The answer is not really complex.
Take a look at this:
clear all; %To clear the conditions of x as real and >=5 (simple clear doesn't clear that)
syms x;
y = int(sqrt(x^2-25)/x, x)
which, as we know, gives:
y =
(x^2 - 25)^(1/2) - log(((x^2 - 25)^(1/2) + 5i)/x)*5i
Now put some real values of x≥5 to check what result it gives:
n = 1004; %We'll be putting 1000 values of x in y from 5 to 1004
yk = zeros(1000,1); %Preallocation
for k=5:n
yk(k-4) = subs(y,x,k); %Putting the value of x
end
Now let's check the imaginary part of the result we have:
>> imag(yk)
ans =
1.0e-70 *
0
0
0
0
0.028298997121333
0.028298997121333
0.028298997121333
%and so on...
Notice the multiplier 1e-70.
Let's check the maximum value of imaginary part in yk.
>> max(imag(yk))
ans =
1.131959884853339e-71
This implies that the imaginary part is extremely small and it is not a considerable amount to be worried about. Ideally it may be zero and it's coming due to imprecise calculations. Hence, it is safe to call your result real.

precision matlab vpa

I'm working with an algorithm, which uses hyperbolic functions and in order to get more accurate results from it I need to increase the precision, so I would like to do it by vpa function means, but I'm not quite sure how to implement it. Here some code to clarify the situation further:
x=18; %the hyperbolic relation is valid until x=18
cosh(x)^2-sinh(x)^2
ans = 1
x=19; %the hyperbolic relation is no longer valid
cosh(x)^2-sinh(x)^2
ans = 0
working with the VPA function:
a=vpa('cosh(40)',30); %the hyperbolic relation is valid beyond x=19
b=vpa('sinh(40)',30);
a^2-b^2
ans = 1.00008392333984375
the problem now is that I don't know how to get the value from VPA with a variable of control 'x'
I tried this but it didn't work:
x=40;
a=vpa('cosh(x)',x,30);
b=vpa('sinh(x)',30);
a^2-b^2
When doing symbolic math or variable precision arithmetic one must be careful with with converting between floating-point. In this case, you need to convert your input, x, to variable precision before passing it in to cosh or sinh (otherwise only the output of these will be converted to variable precision). For your example:
x = vpa(40,30);
a = cosh(x);
b = sinh(x);
a^2-b^2
which returns the expected 1.0. I'm not sure where you found the the use of vpa with string inputs, but that form is no longer used (using strings may even result in different results due to different functions being called). Note also that the default setting for digits in current versions of Matlab is 32.

evaluate numeric part of a "sym" variable

I need to evaluate numeric part of a "sym" variable in MATLAB(something like "evalf" function in maple) for instance I have this sym variable :
(12*(51*EE*II - 8*39^(1/2)*EE*II))/(AA*ll^4*ro)
"evalf" in maple gives me 12.48019224*EE*II/(AA*ll^4*ro), is there any way to do this in MATLAB?
I think that you're looking for the vpa (variable precision arithmetic) function
syms EE II AA ll ro
y = (12*(51*EE*II - 8*39^(1/2)*EE*II))/(AA*ll^4*ro)
vpa(y)
which returns
ans =
(12.48019215375377223869826038978*EE*II)/(AA*ll^4*ro)
MATLAB has a simplify command, but keep in mind that the symbolic toolbox does not like to evaluate to give decimal, it will try to keep everything in fractional values, since that is more accurate anyway.
syms('EE','AA','ll','II','ro')
simplify((12*(51*EE*II - 8*39^(1/2)*EE*II))/(AA*ll^4*ro)))
This will reduce down into the following
-(12*EE*II*(8*39^(1/2) - 51))/(AA*ll^4*ro)
Whether this is more to your liking is really up to you, but I would suggest keeping things in fractions as opposed to decimal. More accuracy is better.
The eval function might also be of some use to you, but that too will keep it fractional. Using that will give you
(13722116389931*EE*II)/(1099511627776*AA*ll^4*ro)

Format of MatLab Integration Result

I have been trying to integrate a function with matlab but it keeps giving me strange
results.
>> syms w x;
>> w = 0.8335*(cosh(52.42*x)-cos(52.42*x)-sinh(52.42*x)+sin(52.42*x));
>> int(w, 0, 1)
>> (1667*sinh(2621/50))/104840 ... /*Some long expression*/
Instead of giving me some final numerical value it leaves the integration with sinh(2621/50). Am I using the wrong functions? Any help would be great.
If you want to get the numerical value you can just evaluate the resulting expression.
Note that sinh(2621/50) is just a number.
I do not have access to the symbolic toolbox, but if you want precise control of the output it seems like the function vpa() (mathworks variable-precision arithmetic) is an alternative to evaluating the expression.
For example vpa(int(w, 0, 1),5) would give you 5 significant digits.

MATLAB: computations involving large numbers

How can one perform computations in MATLAB that involve large numbers. As a simple example, an arbitrary precision calculator would show that ((1/120)^132)*(370!)/(260!) is approximately 1.56, but MATLAB is not able to perform such a computation (power(120,-132)*factorial(370)/factorial(260) = NaN).
I have also tried the following, which does not work:
syms a b c d;
a=120; b=-132; c=370; d=260;
f=sym('power(a,b)*gamma(c+1)/gamma(d+1)')
double(f); % produces error that instructs use of `vpa`
vpa(f) % produces (gamma(c + 1.0)*power(a, b))/gamma(d + 1.0)
If you just want to calculate the factorial of some large numbers, you can use the Java arbitrary precision tools, like so:
result = java.math.BigDecimal(1);
for ix = 1:300
result = result.multiply(java.math.BigDecimal(ix));
end
disp(result)
306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000
The value result in this case is a java object. You can see the available methods here: http://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html
I'm still not sure that I would trust this method for (1e6)! though. You'll have to experiment and see.
Depending on what you're trying to do, then you may be able to evaluate the expression you're interested in in log-space:
log_factorial = sum(log(1:300));
You can use Stirling's approximation to approximate large factorials and simplify your expression before computing it numerically.
This will work:
vpa('120^-132*370!/260!')
and the result is
1.5625098001612564605522837520443