I have two differential equations I would like to solve simultaneously using ode45 in Matlab, shown below.
The problem I have is that the second differential equation is actually d(y^3)/dt, i.e. the derivative of y^3 with respect to t. How do I express this?
function dydt=odefcnNY(t,y,D,Cs,rho,r0,Af,N,V)
dydt=zeros(2,1);
dydt(1)=(3*D*Cs/rho*r0^2)*(y(1)/r0)*(1-y(2)/Cs);
dydt(2)=(D*4*pi*r0*N*(1-y(2)/Cs)*(y(1)/r0)-(Af*y(2)/Cs))/V;
end
D=4e-9;
rho=1300;
r0=10.1e-6;
Cs=0.0016;
V=1.5e-6;
W=4.5e-8;
N=W/(4/3*pi*r0^3*rho);
Af=0.7e-6/60;
tspan=[0 75000];
y0=[r0 Cs];
[t,y]=ode45(#(t,y) odefcnNY(t,y,D,Cs,rho,r0,Af,N,V), tspan, y0);
plot(t,y(:,1),'-o',t,y(:,2),'-.')
d(y^3)/dt = 3 * y^2 * dy/dt so you can divide the second equation with (3 * y(2) * y(2)) . This should be fine unless y(2) gets close to zero.
If it does get close to zero then you will have to re-write your differential equation in terms of another variable in which the second equation doesn't have singularities. For example you can have u(t) = y^3(t) and then y(t) = u(t)^{1/3} (you will have to figure out if there will be ambiguities with negative cube roots).
Related
Introduction
If you want to know the grand scheme... read the introduction. If not, Just skip down to My Problem.
I have a project for my Differential Equations and Linear Algebra course where I have to use a computer algebra system to solve both linear, ordinary differential equations of the first degree with constant coefficients and a non-linear ODE with constant coefficients. I have to show this being done both analytically and numerically. My plan is to have 2 functions that make use of the dsolve function for the analytical part and a function called ODE1 I learned about through this tutorial by Matlab. This function is defined to approximate the solution to the differential equation using Euler's Method. The functions would all use the same input parameters so each input could be defined once and the functions would all understand what inputs to use (maybe nest the functions under one calling function). The goal is to evaluate the analytical solution over the same interval being used to find the numerical approximation and compare the results in both a table and graph. I got the numerical solution to give me a "table" in the form of a row vector and also graph that row vector. I began having an issue with the Analytic solution...
My Problem
To solve a linear ODE of the first order, I generated this function
function [s1] = L_Analytic(eqn,t0,h,numstep,y0)
% eqn is the differential equation to be solved
% t0 is the start of the interval that the resulting equation is to be evaluated at
% h is the stepsize
% numstep is the number of steps
% y0 is the initial condition
syms y(x)
cond = y(0) == y0;
A = dsolve(eqn,cond);
s1 = A;
S1 = s1;
for t = t0 : h : h*(numstep-2)
S1 = [subs(S1); vpa(subs(s1))]
end
end
The list generated by this function L_Analytic(diff(y)==y, 0, 0.1, 5, 1) is
1
1.0
1.105170...
1.221402...
1.349858...
When using the numerical method in a different function in Matlab using the same inputs, I get the list:
1.0000
1.1000
1.2100
1.3310
1.4641
For those who know their way around differential equations or are proficient in calculus, the solution to y' = y is e^x, and when evaluated over the interval 0:0.4 using 5 steps, the list should be
1
1.105...
1.2214...
1.3498...
1.4918...
after some rounding.
So the issue here is that I have an extra entry of 1 in my analytical solutions. I'm confident it has something to do with the subs(S1) part of S1 = [subs(S1); vpa(subs(s1))] in the for loop but I am stumped as to how to fix this.
I kind of understand why I need to use the subs function, in that I am using symbolic variables to use the dsolve function which outputs symbolic variables in its answer. Also, in order for the for loop to iterate and change, the symbolic variables must be substituted for real values of t each time. I did try moving the vpa(subs(s1)) just before the for loop, but this just returned the same value in the vector 5 times. I also tried not using subs(S1) and it gave me
exp(t)
1.0
1.1051709...
1.2214027...
1.3498588...
so I'm positive it's this part of the code.
Side Note: I understand the analytical method outputs a column vector as does the ODE1 shown in the video that's linked. In order to have Matlab plot this as one line, I transposed the column vector to make a row vector and will do the same with the analytical solution once the solution part is fixed.
By changing the internals of the for loop I made it work. My final function code turned out to be this:
function [s1] = L_Analytic3(eqn,t0,h,numstep,y0)
%Differential Equation solver for specific inputs
% eqn is the differential equation
% t0 is start of evaluation interval
% h is stepize
% numstep is the number of steps
% y0 is the initial condition
syms y(x)
cond = y(0) == y0;
A = dsolve(eqn, cond);
s1 = A;
S1 = s1;
for x = t0 : h : h*(numstep)
subs(x);
if x == t0
S1 = subs(s1,x);
else
S1 = [subs(S1), subs(s1,vpa(x))];
end
end
end
I want to solve the differential equation. MATLAB shows warning:
clear all
syms x f(x) theta
eq = (-6*x+(-7+theta)*f*diff(f,x))*(1+diff(f,x)^2)+x*f*(diff(f,x,x))==0
cond = f(0)==1
dsolve(eq,cond)
Warning: Explicit solution could not be found.
> In dsolve (line 201)
In dsolvef (line 5)
ans =
[ empty sym ]
Is there a way to solve it?(analytically or numerically)
Thank you
There is a very high probability that no symbolic solution exists. In general the set of ODE that have symbolic solutions is "thin" in that slight variations of a symbolically solvable ODE make it unsolvable.
For a numerical solution use the ode45 solver or implicit solvers like ode15. The all need an ODE function that encodes the ODE as explicit order 1 system.
function dz = derivs(x,z)
y=z(1); dy = z(2)
ddy = -(-6*x+(-7+theta)*y*dy)*(1+dy^2) / (x*y)
dz = [ dy ddy ]
end
See also similar topics:
How do you plot nonlinear differential equations in matlab
How to draw the direction field of van der pol oscillator?
I want to solve the following equation
I am doing something wrong with the definition of the function but I still don't get it
function F=myairyint(x)
F=integral(#(x)airy,x,1000)
end
functi2=#(x) myairyint;
x0=-1:-1:-15;
fsolve(functi2,x0)
Why doesn't it work?
Your integral seems to have no roots in [-15 -1] and converges to zero. I have tested it via plotting:
x0 = linspace(-20,20);
airyint = arrayfun(#(x0) integral(#(n) airy(n), x0, inf), x0);
plot(x0, airyint);
I also tested it via fzero() such as:
f = #(x) integral(#(n) airy(n), x, inf);
fzero(f, 0)
Output is as expected:
ans =
115.8524
But it seems like every real numbers for x > 115.8524 will look like roots of this integral equation.
Additional:
fzero() is a function trying to find roots looking at the values of funtion between two dynamic intervals. If it catches minus and positive values, it is narrowing the interval to catch the root. But there is an error rate since you also can observe from this example. This equation will be zero only when x goes to infinity which means there is no real roots of this equation.
I have a problem with some differential equations of first-order.
I'm trying to solve them with ode23 and ode23s.
The differential equations are:
y'+3y+z=0
z'-y+z=0
with the initial values:
y(0)=1 and z(0)=1
I also want to compare it with the analytical solution:
y=exp(-2x)(1-2x)
z=exp(-2x)(1+2x)
I want to do it this way because I need to do the comparison in order to choose the better solver: ode23 or ode23s, whichever one is closer to the analytical solution.
My code is:
function dy=projectb1(t,y)
%y'=-4y
%z'= 0
%y(1)=y'
%y(2)=z'
dy = [-4*y(2); 0*y(1)];
and:
% Comparison of analytical solution
clear
options= odeset('RelTol',1e-4,'AbsTol', [1e-4 1e-4]);
%figure
%t1=cputime;
[t23,y23]= ode23('projectb1',[0 12],[1 1],options);
[t23s,y23s]= ode23s('project1',[0 20],[1 0],options);
%tobl = cputime -t1
figure
ya=exp(-2*t23).*(1-2*t23);
za=exp(-2*t23).*(1+2*t23);
plot(t23,ya,za,'r',t23,y23(:,1),'g-.',t23s,y23s(:,1),'b');
%legend('ya','ode23','ode23s',0)
text(3.4,-1.7,'ya')
title('\bf{Analytical and numerical solutions using} \it{ode23s, ode23}')
But it doesn't work. Could someone help me?
The error Matlab throws right away has to do with the line
plot(t23,ya,za,'r',t23,y23(:,1),'g-.',t23s,y23s(:,1),'b');
This should be
plot(t23,ya,t23,za,'r',t23,y23(:,1),'g-.',t23s,y23s(:,1),'b');
You missed that extra t23.
Another problem appears to be in the definition of the differential equation.
For systems of differential equations, the Matlab ODE suite passes a vector x whose components are the values of the functions you are attempting to approximate.
Therefore, as in the example below, the first component of x is the value of y at time t, and the second component of x is the value of z at time t:
function dx = projectb1(t,x)
y = x(1);
z = x(2);
dy = -3*y - z;
dz = y - z;
dx = [dy;dz];
end
I changed the input y to x to make it clear that what is input is a vector of values of y and z.
Also, note that while ode23 has the initial conditions [1,1], ode23s has [1,0], which means it is solving a different initial value problem.
My intention is to plot the original mathematical function values from the differential equation of the second order below:
I(thetadbldot)+md(g-o^2asin(ot))sin(theta)=0
where thetadbldot is the second derivative of theta with respect to t and m,d,I,g,a,o are given constants. Initial conditions are theta(0)=pi/2 and thetadot(0)=0.
My issue is that my knowledge and tutoring is limited to storing the values of the derivatives and returning them, not values from the original mathematical function in the equation. Below you can see a code that calculates the differential in Cauchy-form and gives me the derivatives. Does anyone have suggestions what to do? Thanks!
function xdot = penduluma(t,x)
% The function penduluma(t,x) calculates the differential
% I(thetadbldot)+md(g-o^2asin(ot))sin(theta)=0 where thetadbldot is the second
% derivative of theta with respect to t and m,d,I,g,a,o are given constants.
% For the state-variable form, x1=theta and x2=thetadot. x is a 2x1 vector on the form
% [theta,thetadot].
m=1;d=0.2;I=0.1;g=9.81;a=0.1;o=4;
xdot = [x(2);m*d*(o^2*a*sin(o*t)-g)*sin(x(1))/I];
end
options=odeset('RelTol', 1e-6);
[t,xa]=ode45(#penduluma,[0,20],[pi/2,0],options);
% Then the desired vector from xa is plotted to t. As it looks now the desired
% values are not found in xa however.
Once you have the angle, you can calculate the angular velocity and acceleration using diff:
options=odeset('RelTol', 1e-6);
[t,xa]=ode45(#penduluma,[0,20],[pi/2,0],options);
x_ddot = zeros(size(t));
x_ddot(2:end) = diff(xa(:,2))./diff(t);
plot(t,xa,t,x_ddot)
legend('angle','angular velocity','angular acceleration')
which gives the following plot in Octave (should be the same in MATLAB):
Alternatively, you can work it out using your original differential equation:
x_ddot = -m*d*(o^2*a*sin(o*t)-g).*sin(xa(:,1))/I;
which gives a similar result: