using ilaplace in conjunction with rltool - matlab

Using Matlab, I have the following code:
s = tf('s')
K=0.5;
H= 1/(s*(s+2));
Hcl=feedback(K*H,1)
ilaplace(Hcl)
rltool(H)
I want to get the inverse laplace transform of the unity closed-loop system.
rltool(H) generates automatically the unity closed-loop system. That's why I pass the open-loop system as an argument.
When I run this code, Matlab gives an error about ilaplace:
"Check for incorrect argument data type or missing argument in call to function 'ilaplace'."
Can someone help me how to use ilaplace and rltool concurrently

I have found a solution for this problem.
syms s;
K=1/2;
H= 1/(s*(s+2))
Hcl=simplify(K*H/(1+K*H))
P=poles(Hcl)
ilaplace(Hcl)
H = syms2tf(Hcl)
rltool(H)
ilaplace works with symbolic expressions and not with a transfer function. By converting the symbolic expression to a transfer function midway of the code, I can use both functions in the same code.
Notice I've added the function simplify and changed the beginning from s=tf('s') to syms s
The function syms2tf() can be found here

Related

Using fzero to solve eqn in MatLab

I hope this is the right area. I'm trying to get this code to work in MatLab.
function y=test(x)
y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r- a)+p* ((b/x)^B))/(1-(b/x)^B);
end
I then jump to the command value and type this:
B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;
I then try to find the zeros of the first equation by typing this and I get errors:
solution=fzero(#test,5000000)
I'm getting the following error:
Error: File: test.m Line: 5 Column: 1 This statement is not
inside any function. (It follows the END that terminates the
definition of the function "test".)
New error
Error using fzero (line 289)
FZERO cannot continue because user supplied function_handle ==> #(x)
(test(x,B,b,a,r,p))
failed with the error below.
Subscript indices must either be real positive integers or logicals.
I would guess that this is a problem of scoping, you are defining variables (B, b, etc...) in the command line but trying to use them inside your test function where they are out of scope. You should alter your test function to take these in as parameters and then use an anonymous function so that your call to test in fsolve still only takes a single parameter:
function y=test(x, B, b, r, a, p)
y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r- a)+p* ((b/x)^B))/(1-(b/x)^B);
end
and
B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;
solution=fzero(#(x)(test(x,B,b,a,r,p)),5000000)
As an aside, unless you really do mean matrix multiplication, I would suggest that you replace all your *s and /s in test with the element-wise operators .* and ./. If you are dealing with scalars, it doesn't matter now, but it makes a big difference if you later want to scale your project and need a vectorized solution.
Regarding the errors you have added to your question:
You can't put code after the end in your function file. (With the exception of local functions). Your objective function should be an .m-file containing the code for one single function.
This is because in your test function you have ...b((1-(b/x)^(B-1))... which in MATLAB means you are trying to index the variable b in which case the value of (1-(b/x)^(B-1) has to be a positive integer. I'm guess you are missing a *
Your
function y=test(x)
y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r- a)+p* ((b/x)^B))/(1-(b/x)^B);
end
cannot access variables in your workspace. You need to pass the values in somehow. You could do something like:
function y=test(x,B,b,a,r,p)
y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r- a)+p* ((b/x)^B))/(1-(b/x)^B);
end
and then you can create an implicit wrapper function:
B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;
solution = fzero(#(x) test(x,B,b,a,r,p),5000000)
I haven't tested whether fzero returns sensible results, but this code shouldn't give an error.

Error regarding inlineeval in MATLAB

As part of a group project we have a system of 2 non linear differential equations and we have to draw the S=S(t) , I=I(t) graphic using the midpoint method.
And I'm getting the following error when trying to insert the matrix with the corresponding differential equations:
"Error in inline expression ==> matrix([[-(IS)/1000], [(IS)/1000 - (3*I)/10]])
Undefined function 'matrix' for input arguments of type 'double'.
Error in inline/subsref (line 23)
INLINE_OUT_ = inlineeval(INLINE_INPUTS_, INLINE_OBJ_.inputExpr, INLINE_OBJ_.expr);"
The code I have done is the following:
syms I S
u=[S;I];
F=[-0.001*S*I;0.001*S*I-0.3*I];
F1=inline(char(F),'I','S');
h=100; %Valores aleatórios
T=100000;
ni=(T/h);
u0=[799;1];
f=zeros(1,2);
k=zeros(1,2);
i=1;
while i<=ni
f(1)=F1(u0(1));
f(2)=F1(u0(2));
dx=h*f;
k(1)=F1((u0(1)+h*(1/2)),(u0(2)+h*(1/2)));
k(2)=F1((u0(1)+h*(1/2)),(u0(2)+h*(1/2)));
u1=u0+h*k;
disp('i:'),disp(i)
disp('u= '),disp(u1)
u0=u1;
i=i+1;
end
I'm new to this so the algorithm it's very likely to be wrong but if someone could help me with that error I'd apreciate it. Thank you!
The problem that specifically creates the error is that you are putting two symbolic functions into a matrix and then calling char (which outputs matrix([[-(IS)/1000], [(IS)/1000 - (3*I)/10]]) rather than converting nicely to string).
The secondary problem is that you are trying to pass two functions simultaneously to inline. inline creates a single function from a string (and using anonymous functions instead of inline is preferred anyway). You cannot put multiple functions in it.
You don't need sym here. In fact, avoid it (more trouble than it's worth) if you don't need to manipulate the equations at all. A common method is to create a cell array:
F{1} = #(I,S) -0.001*S*I;
F{2} = #(I,S) 0.001*S*I-0.3*I;
You can then pass in I and S as so:
F{1}(500,500)
Note that both your functions include both I and S, so they are always necessary. Reconsider what you were expecting when passing only one variable like this: f(1)=F1(u0(1));, because that will also give an error.

MATLAB symbolic variables couldn't be used in nested function

I have a MATLAB function to solve a Inertia Tensor , and I have a nested function in my program . All the variables in it are symbolics but it told me
“Error using assignin: Attempt to add ”x“ to a static workspace”
and I don't understand why this happens . Here is my test.m code:
function test
syms x y z
f=x
f1=f+1
f2=f1^2
function r=test2
r=f2^3;
end
f3=test2
end
After searching this web-forum I have found some answers . But at the same time I just don't understand it
Andrew Janke explianed it like this : While syms A may look like a static variable declaration, it isn't. It's just a regular function call. It's using Matlab's "command" invocation style to look like syntax, but it's really equivalent to syms('a', 'b', 'c').
on this page : Matlab: "Error using assignin: Attempt to add "c" to a static workspace"
what does static variable mean ?
I also search the HELP doc and it said :In functions and scripts, do not use syms to create symbolic variables with the same names as MATLAB® functions. For these names MATLAB does not create symbolic variables, but keeps the names assigned to the functions.
I only know syms x to create a symbolic variable in the workspace but why does the documentation say MATLAB does not create ?
'Static' means fixed, 'workspace' is what Matlab calls the places where all of its variables are stored. For non-nested functions the workspace starts off as empty when Matlab is at the beginning of the function; as Matlab continues through function's lines of code it continuously add more variables to the workspace.
For functions with a nested function, Matlab first parses the function to see what variable will be created (it specifically looks for x = type lines), then it creates all of these variables (with value as 'unassigned'), and then only does it start to run through the code; but while running through the code, it can never create a new variable.
This is why the code
function TestNestedFunction
syms x;
function Nested()
end
end
generates an error, there is no x = to tell it to pre-create the unassigned variable x at the start of the code. It fails at syms x;, as that line tries to create a new variable x, which fails as it may not.
This is also why the following code runs
function TestNestedFunction
syms x;
x = x;
function Nested()
end
end
it sees the x = and then pre-creates x. (This is why your example of adding [x, y, z] = deal([]); also works).
You can test this with a break point at the beginning of simple non-nested function and a simple nested function. Just run it step by step.
This code works:
function test
x=sym('x')
y=sym('y')
z=sym('z')
f=x
f1=f+1
f2=f1^2
function r=test2
r=f2^3;
end
f3=test2
end
I think the pages you found are quite clear.
You need to declare the variables one by one and use:
x = sym('x')
Otherwise syms will try to assign the values into a workspace where this is not allowed.

In Matlab, how to solve an equation originating in a function?

How do I easiest solve an equation=0 with a function as a parameter?
My function with one input variable is called potd(angle), with one output variable, potNRGderiv. I tried:
syms x
solve(potd(x))
This gave me error: Undefined function 'sind' for input arguments of type 'sym'.
Have you got any ideas? Thanks in advance.
solve is the wrong avenue here, unless your function can be rewritten as a simple equation. solve uses muPAD functions which is why you can do solve(sin(x)) but not solve(sind(x)). You can, of course, just do the conversion yourself.
If your function is more complicated or you'd rather not rewrite it, look into fsolve:
x = fsolve(#myfun,x0)
Where x0 is your initial guess - i.e. myfun(x0) is close to 0 - and myfun is a function which takes x and returns a single output. Depending on what your function does, you may have to adjust the options using optimoptions (tolerance, step size, etc) to get a good result.

Solving Bessel Function using Runge Kutta

I'm working on an assignment for a class of mine and I'm supposed to write a code using a program of my choice (I've chosen Matlab) to solve the Bessel function differential equation using the 4th order Runge-Kutta method. For reference the Bessel function DE is:
x^2*(J_n)''+x*(J_n)'+(x^2-n^2)*J_n=0.
I'm able to separate this into two coupled first order DEs by:
(J_n)'=Z_n and
(Z_n)'+(1/x)*Z_n+[(x^2-n^2)/x^2]*J_n=0.
I have no experience with Matlab nor any other programming language before this assignment. I know Matlab has the 'ode45' command but I'm supposed to write the code myself, not rely on Matlab's commands. So far I've been working on the n=0 case for the Bessel function but I keep getting an error when I try and plot the function. The current error I have says: "Undefined function or method 'J' for input arguments of type 'double'." But I don't know how to fix this error nor if my code is even correct. Could someone tell me where I've gone wrong or what is the correct way to write this code?
h=0.01; %step size
J_0(1)=1; %initial condition for J_0
Z_0(1)=1; %initial condition for Z_0-This value should be zero
%but Matlab gives me an error. To fix this, I input
%Z_0(1)-1 to use the correct value for Z_0(1).
x(1)=0.001; %first value of x
dZ(Z_0,J_0)=(-1/x)*(Z_0-1)-J_0;
for i=[1:1:10]
dZ1=(-1/x)*(Z_0-1)-J_0;
dJ1=(Z_0(1)-1)*h;
dZ2=(-1/x)*(Z_0-1+0.5*h)-(J_0+0.5*h*dJ1);
dJ2=((Z_0(1)-1)+dZ1)*h;
dZ3=(-1/x)*(Z_0-1+0.5*h)-(J_0+0.5*h*dJ2);
dJ3=((Z_0(1)-1)+dZ1+dZ2)*h;
dZ4=(-1/x)*(Z_0-1+h)-(J_0+h*dJ3);
dJ4=((Z_0(1)-1)+dZ1+dZ2+dZ3)*h;
J(i+1)=J(i)+(h/6)*(dJ1+2*dJ2+2*dJ3+dJ4);
end
plot(J_0);
Thanks in advance for any help
Your problem is on the line:
J(i+1)=J(i)+(h/6)*(dJ1+2*dJ2+2*dJ3+dJ4);
In the right-hand side of your assignment operator you use the variable J that is never set before i is taking the value 1. Looks like a typo to me (should it be J_0 instead?)
Also, don't forget your index i when computing your dJ and dZ stuff in the for loop.