Matlab gives no result when I use the integral function - matlab

When trying to calculate the Integral of two variables, I got nothing!
Here is the code:
syms x;
a=0.4;
theta=(9 - 4*x*(5*x - 141/25))^(1/2)/2 - 3/2;
theta_prime=-(40*x - 564/25)/(4*(9 - 4*x*(5*x - 141/25))^(1/2));
g=(1/theta)*theta_prime
s=(1+a*(theta-1))*(g)^2
sgen = int(s,x,0.1,1) %x=0.1:0.1: 1
What was my mistake?
It supposed to be one value, such as '4.86'.
Please advise.

sgen is a symbolic object representing the integral of your function s. You can cast it to double to obtain a numerical value for your integral:
syms x;
a=0.4;
theta=(9 - 4*x*(5*x - 141/25))^(1/2)/2 - 3/2;
theta_prime=-(40*x - 564/25)/(4*(9 - 4*x*(5*x - 141/25))^(1/2));
g=(1/theta)*theta_prime;
s=(1+a*(theta-1))*(g)^2;
sgen = double(int(s,x,0.1,1)) % returns 4.8694
But if you're not interested in the symbolic equation for the integral, there really is no point in using the symbolic toolbox for this. It is much faster to compute the integral numerically. One way to do so is to create a function s(x) and then use integral to find the numerical integration. Do note that s(x) must be vectorized on the x variable for this to work (integral will call it with a vector of x values to save time). For vectorized computation, it is necessary to add dots in front of some of the *, / and ^ operators. This is the result:
a = 0.4;
theta = #(x) (9 - 4*x.*(5*x - 141/25)).^(1/2)/2 - 3/2;
theta_prime = #(x) -(40*x - 564/25)./(4*(9 - 4*x.*(5*x - 141/25)).^(1/2));
g = #(x) (1./theta(x)).*theta_prime(x);
s = #(x) (1+a*(theta(x)-1)).*g(x).^2;
sgen = integral(s,0.1,1.0) % returns 4.8694

Related

Taylor series for (exp(x) - exp(-x))/(2*x)

I've been asked to write a function that calculates the Taylor series for (exp(x) - exp(-x))/(2*x) until the absolute error is smaller than the eps of the machine.
function k = tayser(xo)
f = #(x) (exp(x) - exp(-x))/(2*x);
abserror = 1;
sum = 1;
n=2;
while abserror > eps
sum = sum + (xo^n)/(factorial(n+1));
n=n+2;
abserror = abs(sum-f(xo));
disp(abserror);
end
k=sum;
My issue is that the abserror never goes below the eps of the machine which results to an infinite loop.
The problem is expression you're using. For small numbers exp(x) and exp(-x) are approximately equal, so exp(x)-exp(-x) is close to zero and definitely below 1. Since you start with 1 and only add positive numbers, you'll never reach the function value.
Rewriting the expression as
f = #(x) sinh(x)/x;
will work, because it's more stable for these small values.
You can also see this by plotting both functions:
x = -1e-14:1e-18:1e-14;
plot(x,(exp(x) - exp(-x))./(2*x),x,sinh(x)./x)
legend('(exp(x) - exp(-x))/(2*x)','sinh(x)/x')
gives

MATLAB not evaluating integral

MATLAB gives me the same expression back.
Here's my code
syms tau alpha phi
f = sign(alpha*cos(phi))*(abs(alpha*cos(phi)) - 2.5*(alpha*cos(phi))^2);
F=f*sin(phi);
int(F,phi, [pi/2, acos(tau/alpha)])
I did plug in the values of variables tau and alpha but it still gives me the same expression back. Anyone know how to solve it? Or some other numerical method which could give me answer in these symbols? Will wolfram-mathematica help?
Mathematica
Integrate[(Sign[alpha*Cos[phi]]*(Abs[alpha*Cos[phi]] - 5/2*
(alpha*Cos[phi])^2))*Sin[phi], {phi, Pi/2, ArcCos[tau/alpha]}]
(* ConditionalExpression[-(tau^2/(2 alpha)) + (5 alpha^3 Abs[tau]^3)/
(6 Abs[alpha]^4), ArcCos[tau/alpha] \[Element] Reals] *)
Thus the result is the expression inside the ConditionalExpression if the ArcCos[tau/alpha] is an element of the reals.
If you could specify something like -1<=tau/alpha<=1 && 0<=tau then it can provide an even simpler result, (tau^2 (-3 + 5 tau))/(6 alpha)
Please verify this before you depend on it.
Something like
syms tau alpha phi
f = sign(alpha*cos(phi))*(abs(alpha*cos(phi)) - 2.5*(alpha*cos(phi))^2);
will just generate another symbolic variable. Your goal however is to specify a symbolic function and for that you have to specify the function arguments:
syms tau alpha phi
f(tau,alpha,phi) = sign(alpha*cos(phi))*(abs(alpha*cos(phi)) - 2.5*(alpha*cos(phi))^2);
F(tau,alpha,phi) =f*sin(phi);
Then you can calculate the integral with
R = int(F,phi, [pi/2, acos(tau/alpha)])
Since your integral is dependent on tau and alpha, R is again a symbolic function R(tau,alpha).
Alternatively you could just specify the arguments at the end, e.g.
syms tau alpha phi
f = sign(alpha*cos(phi))*(abs(alpha*cos(phi)) - 2.5*(alpha*cos(phi))^2);
F=f*sin(phi);
R(tau,alpha) = int(F,phi, [pi/2, acos(tau/alpha)])
But I personally find that less clean.
Note that you could also write F directly as
F(tau,alpha,phi) = sin(phi)*(sign(alpha*cos(phi))*(abs(alpha*cos(phi)) - 2.5*(alpha*cos(phi))^2));

Find z-transform and plot it's pole-zero map with MATLAB

I have this function:
x[n] = (1/2) ^ n * u[n] + (-1/3) ^ n * u[n]
I need to do two things with this using MATLAB:
Find it's z-transform.
Plot it's poles and zeros.
I am using the following code:
syms n;
f = (1/2)^n + (-1/3)^n;
F = ztrans(f);
I get the z-transform in the F variable, but I can't see how to create it's pole-zero plot. I am using the built-in function pzmap (pzmap(F);), but it doesn't seem to work with the output of ztrans(f).
What am I doing wrong? Do I need to change the z-transform into some other form like like a transfer function model or a zero-pole gain model? If so, can someone explain how that can be done using the output of ztrans(f)?
The first bit of code you gave uses symbolic math to solve for the z-transform. You'll need to convert the output to a discrete-time model supported by the Control System toolbox.
syms n;
f = (1/2)^n + (-1/3)^n;
F = ztrans(f)
returns z/(z - 1/2) + z/(z + 1/3). You can optionally use collect to convert this
F2 = collect(F)
to (12*z^2 - z)/(6*z^2 - z - 1). Then you'll want to find the coefficients of the polynomials in the numerator and denominator and create a discrete-time transfer function object with tf for a particular sampling period:
[num,den] = numden(F2);
Ts = 0.1; % Sampling period
H = tf(sym2poly(num),sym2poly(den),Ts)
Then pzmap(H) will produce a plot like this:

matlab with symbol, how can I shorten numbers?

syms w
A=[141432432 23432*w; 31432*w 3543566]
B=[13432*w^2 ; 3424324]
which returns
A =
[ 141432432, 23432*w]
[ 31432*w, 3543566]
B =
13432*w^2
3424324
Then
C=A\B
c1=C(1)
simplify(c1)
returns
C =
-(w*(2974823657*w - 5014922498))/(2*(23016082*w^2 - 15661723666641))
(2*(6596791*w^3 - 7567351113687))/(23016082*w^2 - 15661723666641)
c1 =
-(w*(2974823657*w - 5014922498))/(2*(23016082*w^2 - 15661723666641))
ans =
-(w*(2974823657*w - 5014922498))/(2*(23016082*w^2 - 15661723666641))
I want to simplify c1 to something like this,
c1 = -(w*(3*e^9*w-5.01*e^9))/......
How can I do this? When I do not use syms variables, the numbers looks good. But, if I use this, the formula look so dirty.
It may look "dirty," but that's the point of symbolic math – it's accurate to the full precision of your original input. If you want a result in decimal format you should be aware that it will necessarily be less precise unless the values can be represented exactly as a (sufficiently short) finite decimal expansion. In Matlab's Symbolic Math toolbox, you can simply use the vpa function to convert your result to variable precision arithmetic:
syms w;
c1 = -(w*(2974823657*w - 5014922498))/(2*(23016082*w^2 - 15661723666641));
vpa(c1)
which returns
-(1.0*w*(2974823657.0*w - 5014922498.0))/(46032164.0*w^2 - 31323447333282.0)
This doesn't help you much in this case. If you want a lot less precision, as suggested in your question, you can use digits or the second argument to vpa:
syms w;
c1 = -(w*(2974823657*w - 5014922498))/(2*(23016082*w^2 - 15661723666641));
vpa(c1,3) % default value is 32
which now returns the much less precise
-(1.0*w*(2.97e9*w - 5.01e9))/(4.6e7*w^2 - 3.13e13)
Lastly, you can also convert your symbolic expression to a floating point function using the unfortunately-named matlabFunction:
syms w;
c1 = -(w*(2974823657*w - 5014922498))/(2*(23016082*w^2 - 15661723666641));
c1_fun = matlabFunction(c1)
which returns the anonymous function
c1_fun =
#(w)-(w.*(w.*2.974823657e9-5.014922498e9))./(w.^2.*4.6032164e7-3.1323447333282e13)

Cross characteristics of a non-linear equation in Matlab

I'd like to create a Matlab plot of propeller angular velocity in terms of applied current. The point is, this requires combining two interdependent sets of data.
Firstly, drag coefficient c_d depends on angular velocity omega (I have no formula, just data) as seen on the plot below - the characteristics c_d(omega) could be easily linearised as c_d(omega) = p*omega + p_0.
Secondly, omega depends not only on applied current i, but also on the drag coefficient c_d(omega).
A script that solves the case, where c_d is constant below. It must be somehow possible to join those two using Matlab commands. Thanks for any help.
%%Lookup table for drag coefficient c_d
c_d_lookup = [248.9188579 0.036688351; %[\omega c_d]
280.2300647 0.037199094;
308.6091183 0.037199094;
338.6636881 0.03779496;
365.8908244 0.038305703;
393.9557188 0.039156941;
421.9158934 0.039667683;
452.2846224 0.040348674;
480.663676 0.041199911;
511.032405 0.042051149;
538.9925796 0.042561892;
567.2669135 0.043242882;
598.4734005 0.043668501;
624.1297405 0.044264368;
651.9851954 0.044604863;
683.6105614 0.045200729];
subplot(2,1,1)
plot(c_d_lookup(:,1), c_d_lookup(:,2))
title('This is how c_d depends on \omega')
ylabel('c_d')
xlabel('\omega [rad/s]')
%%Calculate propeller angular speed in terms of applied current. omega
%%depends on c_d, which in turn depends on omega. The formula is:
% omega(i) = sqrt(a*i / (b * c_d(omega)))
% Where:
% i - applied current
% omega - propeller angular velocity
% a,b - coefficients
i = [1:15];
a = 0.0718;
b = 3.8589e-005;
%If c_d was constant, I'd do:
omega_i = sqrt(a .* i / (b * 0.042));
subplot(2,1,2)
plot(i, omega_i)
ylabel({'Propeller ang. vel.', '\omega [rad/s]'})
xlabel('Applied current i[A]')
title('Propeller angular velocity in terms of applied current')
EDIT:
Trying to follow bdecaf's solution. So I created a function c_d_find, like so:
function c_d = c_d_find(omega, c_d_lookup)
c_d = interp1(c_d_lookup(:,1), c_d_lookup(:,2), omega, 'linear', 'extrap');
end
I don't know anything about Matlab function handles, but seem to understand the idea... In Matlab command window I typed:
f = #(omega) omega - sqrt(a .* i / (b * c_d_find(omega, c_d_lookup)))
which I hope created the correct function handle. What do I do next? Executing the below doesn't work:
>> omega_consistent = fzero(f,0)
??? Operands to the || and && operators must be convertible to logical scalar
values.
Error in ==> fzero at 333
elseif ~isfinite(fx) || ~isreal(fx)
hmmm...
Wonder if I understand correctly - but looks like you are looking for a consistent solution.
Your equations don't look to complicated I would outline the solution like this:
Write a function function c_d = c_d_find(omega) that does some interpolation or so
make a function handle like f = #(omega) omega - sqrt(a .* i / (b * c_d_find(omega))) - this is zero for consistent omega
calculate a consistent omega with omega_consistent =fzero(f,omega_0)