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.
Related
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.
I am trying to compute the following expected value for Z being lognormally distributed
E[Z^eta w(F_Z (Z))^-eta]
where eta is a real number, F_Z the distribution function of Z and w:[0,1]->[0,1] an increasing function.
First of all, I am pretty new to Matlab so I don't know which way of integrating is the better one, numerically or symbolically. I tried symbolically.
My idea was to subsequently define functions:
syms x;
g_1(x) = x^eta;
g_2(x) = logncdf(x);
g_2(x) = w(x)^-eta;
g_4(x) = g_1(x) * g_3(g_2(x));
And then
exp = int(g_4(x),x,0,inf)
Unfortunately this doesn't work and MATLAB just posts the whole expression of g_4...
Is it better to use the numerical integration quadqk? What am I doing wrong here? I already read something about MATLAB not being the best program for integration but I have to use it so switching to a different program does not help.
Thanks a lot!
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)
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.
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