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.
Related
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
I am trying to run code similar to the following, I replaced the function I had with one much smaller, to provide a minimum working example:
clear
syms k m
n=2;
symsum(symsum(k*m,m,0,min(k,n-k)),k,0,n)
I receive the following error message:
"Error using sym/min (line 86)
Input arguments must be convertible to floating-point numbers."
I think this means that the min function cannot be used with symbolic arguments. However, I was hoping that MATLAB would be substituting in actual numbers through its iterations of k=0:n.
Is there a way to get this to work? Any help much appreciated. So far I the most relevant page I found was here, but I am somewhat hesitant as I find it difficult to understand what this function does.
EDIT following #horchler, I messed around putting it in various places to try and make it work, and this one did:
clear
syms k m
n=2;
symsum(symsum(k*m,m,0,feval(symengine, 'min', k,n-k)),k,0,n)
Because I do not really understand this feval function, I was curious to whether there was a better, perhaps more commonly-used solution. Although it is a different function, there are many pieces online advising against the eval function, for example. I thought perhaps this one may also carry issues.
I agree that Matlab should be able to solve this as you expect, even though the documentation is clear that it won't.
Why the issue occurs
The problem is due the inner symbolic summation, and the min function itself, being evaluated first:
symsum(k*m,m,0,min(k,n-k))
In this case, the input arguments to sym/min are not "convertible to floating-point numbers" as k is a symbolic variable. It is only after you wrap the above in another symbolic summation that k becomes clearly defined and could conceivably be reduced to numbers, but the inner expression has already generated an error so it's too late.
I think that it's a poor choice for sym/min to return an error. Rather, it should just return itself. This is what the sym/int function does when it can't evaluate an integral symbolically or numerically. MuPAD (see below) and Mathematica 10 also do something like this as well for their min functions.
About the workaround
This directly calls a MuPAD's min function. Calling MuPAD functions from Matlab is discussed in more detail in this article from The MathWorks.
If you like, you can wrap it in a function or an anonymous function to make calling it cleaner, e.g.:
symmin = #(x,y)feval(symengine,'min',x,y);
Then, you code would simply be:
syms k m
n = 2;
symsum(symsum(k*m,m,0,symmin(k,n-k)),k,0,n)
If you look at the code for sym/min in the Symbolic Math toolbox (type edit sym/min in your Command Window), you'll see that it's based on a different function: symobj::maxmin. I don't know why it doesn't just call MuPAD's min, other than performance reasons perhaps. You might consider filing a service request with The MathWorks to ask about this issue.
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.
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.
UPDATE
I am trying to find the Lyapunov Exponents given in link LE. I am trying to figure it out and understand it by taking the following eqs for my case. These are a set of ordinary differential equations (these are just for testing how to work with cos and sin as ODE)
f(1)=ALPHA*(y-x);
f(2)=x*(R-z)-y;
f(3) = 10*cos(x);
and x=X(1); y=X(2); cos(y)=X(3);
f1 means dx/dt;f2 dy/dt and f3 in this case would be -10sinx. However,when expressing as x=X(1);y=X(2);i am unsure how to express for cos.This is just a trial example i was doing so as to know how to work with equations where we have a cos,sin etc terms as a function of another variable.
When using ode45 to solve these Eqs
[T,Res]=sol(3,#test_eq,#ode45,0,0.01,20,[7 2 100 ],10);
it throws the following error
??? Attempted to access (2); index must be a positive integer or logical.
Error in ==> Eq at 19
x=X(1); y=X(2); cos(x)=X(3);
Is my representation x=X(1); y=X(2); cos(y)=X(3); alright?
How to resolve the error?
Thank you
No your representation is completely wrong.
You can't possibly set values in this way!
For a start, you are trying to assign a value X(3) to a function.
first I am not sure you understand the difference between
x=4
and
4=x
which are completely different meanings. If you understand this, you'll see that you can't possibly assign using cos(x)=X(3).
Second: what is the function sol() you are calling? have you defined it?
Third, to solve or evaluate ODEs you should be using deval or solve functions in matlab. Their help files should give you examples.