How to input a "sym" type equation into ODE45 to solve first order differential equation?

% Sample
close all;
clear all;
clc;
syms t tt;
a=1;
b=2;
c=3;
fs_d=50*t^2+60*t^4+70*t^9;
fd_d=diff(fs_d,t);
dTime=1e-6; % time step
Tfinal=timeduration; % time final
zeit=0:dTime:Tfinal; %
% ODE solver
% initial condition
x1_0=0;
dx1_0=0;
%ode45
options = odeset('RelTol',1.e-6);
[tt,dx] = ode45(@(tt,x) Output123(tt, x, a, b, c, fd_d, t), zeit, x1_0, options);
function dx = Output123(tt, x, a, b, c, fd_d, t)
tic;
%dx(1)=x(2);
dx=-a*subs(fd_d,t,tt)*b/(c)-x*(b/(c));
dx = dx'; % output result
toc;
end
The above the a sample code I want to achieve, it is a first order differential equation, the "subs" method works for second order differential equation.
Can anyone help me with this problem?
Thanks,

 Accepted Answer

I do not understand what you are doing.
However the correct way to use a symbolic different ia equation with the numeric solvers would be something like this —
syms a b c t tt x
fs_d=50*t^2+60*t^4+70*t^9;
fd_d=diff(fs_d,t);
f=-a*subs(fd_d,t,tt)*b/(c)-x*(b/(c))
f = 
Output123 = matlabFunction(f, 'Vars',{tt,x,a,b,c})
Output123 = function_handle with value:
@(tt,x,a,b,c)-(b.*x)./c-(a.*b.*(tt.*1.0e+2+tt.^3.*2.4e+2+tt.^8.*6.3e+2))./c
a=1;
b=2;
c=3;
timeduration = 1;
dTime=1e-6; % time step
Tfinal=timeduration; % time final
zeit=0:dTime:Tfinal; %
x1_0=0;
dx1_0=0;
options = odeset('RelTol',1.e-6);
[tt,x] = ode45(@(tt,x) Output123(tt, x, a, b, c), zeit, x1_0, options);
figure
plot(tt, x)
grid
Make appropriate changes to ger the resullt you want.
.

11 Comments

Thank you my friend. Do you think you can write the code in a way like I did here?
function dx = Output123(tt, x, a, b, c, fd_d, t)
tic;
%dx(1)=x(2);
dx=-a*subs(fd_d,t,tt)*b/(c)-x*(b/(c));
dx = dx'; % output result
toc;
end
My pleasure!
Creating that as a function file is straightforward —
function dx = Output123(tt,x,a,b,c)
dx = -(b.*x)./c-(a.*b.*(tt.*1.0e+2+tt.^3.*2.4e+2+tt.^8.*6.3e+2))./c;
end
The trest of the code remains unchanged. With only one differential equation, transposing it is not appropriate. There is no need to pass any other parameters to it, since it does not usee them.
.
Is there any chance the following code can be included in the function? Or it has to be excluded? @Star Strider
f=-a*subs(fd_d,t,tt)*b/(c)-x*(b/(c))
As always, my pleasure!
With respect to your second Comment, it may not have to be excluded, however I would exclude it, since it would just slow everything down and could produce errors. Besides, by definition it calls the Symbolic Math Toolbox, and while that is appropriate in some situations, it is not appropriate here.
As a general rule, it is best to use the Symbolic Math Toolbox for symbolic derivations, and then create numeric functions from them to use in numeric (and especially interative) calculations, and not use the Symbolid Math Toolbox for iterative calculations, such as numerically integrating differential equations.
.
Thank you for your comment.
Yes, I did come into some error while including in the function. You seems have much more experience than I do for matlat coding. If possible, I wish to include it in the function. Would you mind to do some simple try out for me to make it work which may help me quite a bit for my calculation. Anyway, you already help me a lot.
As always, my pleasure!
I do not understand what you want to do.
Mixing numeric and symbolic code (as you want to do here) is not adviasable for the reasons I already stated. If the symbolic code has a specific purpose (that is not obvious to me) it might be possible to include it, even though that would create slower and much less efficient code.
The code in your earlier Comment is already included in the existing numeric code to create ‘f’. There is no reason to include it separately in the function, and especially as a Symbolic Math Toolbox call.
.
Because I am using a Maple Symbolic Math Toolbox, so "matlabFunction" function didn't work with my current matlab, I tested the function in another computer with original matlab, the reason why I used Maple Symbolic Math Toolbox is for faster calculation.
function dx = Output123(tt,x,a,b,c)
dx = -(b.*x)./c-(a.*b.*(tt.*1.0e+2+tt.^3.*2.4e+2+tt.^8.*6.3e+2))./c;
end
if I could included
-a*subs(fd_d,t,tt)*b/(c)-x*(b/(c))
inside dx equation in the function, I could make it works.
Thanks again.
Then code it by hand if it is morally important for you.
Reminder: the ode*() functions strictly require that the output is double() or single(), but the output of subs() is always symbolic.

Sign in to comment.

More Answers (0)

Products

Release

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!