Related
I have stumbled upon this matlab code that solves this ODE
y'''(t) + a y(t) = -b y''(t) + u(t)
but I am confused by the ode_system function definition, specifically by the y(2) y(3) part. I would greatly appreciate if someone can shed some light
y(2) y(3) part in the ode_system function confuses me and how it contributes to overaal solution
% Define the parameters a and b
a = 1;
b = 2;
% Define the time horizon [0,1]
time_horizon = [0, 1];
% Define the initial conditions for y, y', and y''
initials = [0; 0; 0];
% Define the function handle for the input function u(t)
%sin(t) is a common example of a time-varying function.
% You can change the definition of u to any other function of time,
% such as a constant, a step function, or a more complex function, depending on your needs
u = #(t) sin(t);
% Define the function handle for the system of ODEs
odefunction = #(t, y) ode_system(t, y, a, b, u);
% Solve the ODEs using ode45
[t, y] = ode45(odefunction, time_horizon, initials);
% Plot the solution
plot(t, y(:,1), '-', 'LineWidth', 2);
xlabel('t');
ylabel('y');
function dydt = ode_system(t, y, a, b, u)
%Define the system of ODEs
dydt = [y(2); y(3); -b*y(3) + u(t) - a*y(1)];
end
This is more of a maths question than a Matlab one.
We would like to rewrite our ODE equation so that there is a single time derivative on the left-hand side and no derivatives on the right.
Currently we have:
y'''(t)+ay(t)=-by''(t)+u(t)
By letting z = y' and x = z' (= y''), we can rewrite this as:
x'(t)+a y(t)=-b x(t)+u(t)
So now we have 3 equations in the form:
y' = z
z' = x
x' = -b * x + u - a *y
We can also think of this as a vector equation where v = (y, z, x).
The right-hand side would then be,
v(1)' = v(2)
v(2)' = v(3)
v(3)' = -b * v(3) + u - a * v(1)
which is what you have in the question.
I need some help with finding solution to Cauchy problem in Matlab.
The problem:
y''+10xy = 0, y(0) = 7, y '(0) = 3
Also I need to plot the graph.
I wrote some code but, I'm not sure whether it's correct or not. Particularly in function section.
Can somebody check it? If it's not correct, where I made a mistake?
Here is separate function in other .m file:
function dydx = funpr12(x,y)
dydx = y(2)+10*x*y
end
Main:
%% Cauchy problem
clear all, clc
xint = [0,5]; % interval
y0 = [7;3]; % initial conditions
% numerical solution using ode45
sol = ode45(#funpr12,xint,y0);
xx = [0:0.01:5]; % vector of x values
y = deval(sol,xx); % vector of y values
plot(xx,y(1,:),'r', 'LineWidth',3)
legend('y1(x)')
xlabel('x')
ylabel('y(x)')
I get this graph:
ode45 and its related ilk are only designed to solve first-order differential equations which are of the form y' = .... You need to do a bit of work if you want to solve second-order differential questions.
Specifically, you'll have to represent your problem as a system of first-order differential equations. You currently have the following ODE:
y'' + 10xy = 0, y(0) = 7, y'(0) = 3
If we rearrange this to solve for y'', we get:
y'' = -10xy, y(0) = 7, y'(0) = 3
Next, you'll want to use two variables... call it y1 and y2, such that:
y1 = y
y2 = y'
The way you have built your code for ode45, the initial conditions that you specified are exactly this - the guess using y and its first-order guess y'.
Taking the derivative of each side gives:
y1' = y'
y2' = y''
Now, doing some final substitutions we get this final system of first-order differential equations:
y1' = y2
y2' = -10*x*y1
If you're having trouble seeing this, simply remember that y1 = y, y2 = y' and finally y2' = y'' = -10*x*y = -10*x*y1. Therefore, you now need to build your function so that it looks like this:
function dydx = funpr12(x,y)
y1 = y(2);
y2 = -10*x*y(1);
dydx = [y1 y2];
end
Remember that the vector y is a two element vector which represents the value of y and the value of y' respectively at each time point specified at x. I would also argue that making this an anonymous function is cleaner. It requires less code:
funpr12 = #(x,y) [y(2); -10*x*y(1)];
Now go ahead and solve it (using your code):
%%// Cauchy problem
clear all, clc
funpr12 = #(x,y) [y(2); -10*x*y(1)]; %// Change
xint = [0,5]; % interval
y0 = [7;3]; % initial conditions
% numerical solution using ode45
sol = ode45(funpr12,xint,y0); %// Change - already a handle
xx = [0:0.01:5]; % vector of x values
y = deval(sol,xx); % vector of y values
plot(xx,y(1,:),'r', 'LineWidth',3)
legend('y1(x)')
xlabel('x')
ylabel('y(x)')
Take note that the output when simulating the solution to the differential equation by deval will be a two column matrix. The first column is the solution to the system while the second column is the derivative of the solution. As such, you'll want to plot the first column, which is what the plot syntax is doing.
I get this plot now:
I have based my solution off the example provided by Matlab - solving a third order differential equation.
My problem is that I have to solve the third order differential equation, y'''+3y''+2y'+y=4u, by using the ode23 solver and plot the step response.
Here is what I have so far.
function dy = diffuy( t, y )
%Split uy into variables in equation
%y'''+3y''+2y'+y=4u
%Have to take third order equation and convert to 1st order
%y0 = y
%y1 = y0'
%y2 = y1'
%y3 = y2'
%y0' = y1
%y1' = y2
%y2' = y3
%y3' = y''' = -3*y2-2*y1-y0+4*u
%Assume that y(0)= 0, y'(0)=0, y''(0)=0, no initial conditions
u = #(t) heaviside(t);
dy = zeros(4,1);
dy(1) = y(2);
dy(2) = y(3);
dy(3) = y(4);
dy(4) = -3*y(3)-2*y(2)-y(1)+4*u(t);
end
In my main file, I have the code:
[T, Y]=ode23(#diffuy,[0 20],[0 0 0 0]);
figure(1)
plot(T,Y(:,1))
A=[0 1 0;0 0 1; -1 -2 -3]
B=[0;0;4]
C=[1 0 0]
D=[0]
sys4=ss(A,B,C,D)
figure(2)
step(sys4)
The problem I am having is that the step response produced from using the state-space representation commands in MATLAB do not match the step response produced by the ode23, so I assumed that I solved the differential equation incorrectly. Any tips or comments would be very helpful.
Step Response from ss commands:
Step Response from using ode23:
I'm not sure how the linked question got the correct answer because you're actually solving a fourth-order equation using their methodology.
The right hand-side vector given to the ODE suite should only have n entries for an n-order problem.
In your case, the change of variables
results in the third order system
with the initial conditions
.
Changing diffuy to
function dy = diffuy( t, y )
dy = zeros(3,1);
dy(1) = y(2);
dy(2) = y(3);
dy(3) = -3*y(3)-2*y(2)-y(1)+4*u(t);
end
gives a solution that matches the state-space model.
How can I solve a 2nd order differential equation with boundary condition like z(inf)?
2(x+0.1)·z'' + 2.355·z' - 0.71·z = 0
z(0) = 1
z(inf) = 0
z'(0) = -4.805
I can't understand where the boundary value z(inf) is to be used in ode45() function.
I used in the following condition [z(0) z'(0) z(inf)], but this does not give accurate output.
function [T, Y]=test()
% some random x function
x = #(t) t;
t=[0 :.01 :7];
% integrate numerically
[T, Y] = ode45(#linearized, t, [1 -4.805 0]);
% plot the result
plot(T, Y(:,1))
% linearized ode
function dy = linearized(t,y)
dy = zeros(3,1);
dy(1) = y(2);
dy(2) = y(3);
dy(3) = (-2.355*y(2)+0.71*y(1))/((2*x(t))+0.2);
end
end
please help me to solve this differential equation.
You seem to have a fairly advanced problem on your hands, but very limited knowledge of MATLAB and/or ODE theory. I'm happy to explain more if you want, but that should be in chat (I'll invite you) or via personal e-mail (my last name AT the most popular mail service from Google DOT com)
Now that you've clarified a few things and explained the whole problem, things are a bit more clear and I was able to come up with a reasonable solution. I think the following is at least in the general direction of what you'd need to do:
function [tSpan, Y2, Y3] = test
%%# Parameters
%# Time parameters
tMax = 1e3;
tSpan = 0 : 0.01 : 7;
%# Initial values
y02 = [1 -4.805]; %# second-order ODE
y03 = [0 0 4.8403]; %# third-order ODE
%# Optimization options
opts = optimset(...
'display', 'off',...
'TolFun' , 1e-5,...
'TolX' , 1e-5);
%%# Main procedure
%# Find X so that z2(t,X) -> 0 for t -> inf
sol2 = fminsearch(#obj2, 0.9879680932400429, opts);
%# Plug this solution into the original
%# NOTE: we need dense output, which is done via deval()
Z = ode45(#(t,y) linearized2(t,y,sol2), [0 tMax], y02);
%# plot the result
Y2 = deval(Z,tSpan,1);
plot(tSpan, Y2, 'b');
%# Find X so that z3(t,X) -> 1 for t -> inf
sol3 = fminsearch(#obj3, 1.215435887288112, opts);
%# Plug this solution into the original
[~, Y3] = ode45(#(t,y) linearized3(t,y,sol3), tSpan, y03);
%# plot the result
hold on, plot(tSpan, Y3(:,1), 'r');
%# Finish plots
legend('Second order ODE', 'Third order ODE')
xlabel('T [s]')
ylabel('Function value [-]');
%%# Helper functions
%# Function to optimize X for the second-order ODE
function val = obj2(X)
[~, y] = ode45(#(t,y) linearized2(t,y,X), [0 tMax], y02);
val = abs(y(end,1));
end
%# linearized second-order ODE with parameter X
function dy = linearized2(t,y,X)
dy = [
y(2)
(-2.355*y(2) + 0.71*y(1))/2/(X*t + 0.1)
];
end
%# Function to optimize X for the third-order ODE
function val = obj3(X3)
[~, y] = ode45(#(t,y) linearized3(t,y,X3), [0 tMax], y03);
val = abs(y(end,2) - 1);
end
%# linearized third-order ODE with parameters X and Z
function dy = linearized3(t,y,X)
zt = deval(Z, t, 1);
dy = [
y(2)
y(3)
(-1 -0.1*zt + y(2) -2.5*y(3))/2/(X*t + 0.1)
];
end
end
As in my comment above, I think you're confusing a couple of things. I suspect this is what is requested:
function [T,Y] = test
tMax = 1e3;
function val = obj(X)
[~, y] = ode45(#(t,y) linearized(t,y,X), [0 tMax], [1 -4.805]);
val = abs(y(end,1));
end
% linearized ode with parameter X
function dy = linearized(t,y,X)
dy = [
y(2)
(-2.355*y(2) + 0.71*y(1))/2/(X*t + 0.1)
];
end
% Find X so that z(t,X) -> 0 for t -> inf
sol = fminsearch(#obj, 0.9879);
% Plug this ssolution into the original
[T, Y] = ode45(#(t,y) linearized(t,y,sol), [0 tMax], [1 -4.805]);
% plot the result
plot(T, Y(:,1));
end
but I can't get it to converge anymore for tMax beyond 1000 seconds. You may be running into the limits of ode45 capabilities w.r.t. accuracy (switch to ode113), or your initial value is not accurate enough, etc.
I've been given following task and got stuck. Apparently I am returning a vector of length 4 instead of the 2 it should be.
The differential equation I am trying to plot is:
dv/dt=v*(1-v)(v-alpha)-w+C
and dw/dt=varepsilon(v-gamma*w)
function dydt = fun (v, alpha, w, C, gamma, varepsilon)
dydt = [v*(1-v)*(v-alpha)-w+C;varepsilon*(v-gamma*w)]
end
This is the Fitzhugh-Nagumo model (http://en.wikipedia.org/wiki/FitzHugh-Nagumo_model)
Now I want to solve this equation via ode45 (this is a prerequisite) in the following script:
tspan = [0, 6]; y0 = [1; 1];
alpha = 0.7;
gamma = 0.8;
varepsilon = 12.5;
C = 0.5;
ode = #(v,w) fun (v, alpha, w, C, gamma, varepsilon);
[v,w] = ode45(ode, tspan, y0);
plot(t,v(:,1),'r')
xlabel ('t')
ylabel('solution v & w')
title ('opdracht 1, name')
hold on
plot(t,w(:,1),'b')
shg
The goal is to plot v and w in function of t (time, defined by tspan). But I get the following error:
Error using odearguments (line 92)
#(V,W)OPDRACHT1FUNCTIEV(V,ALPHA,W,C,GAMMA,VAREPSILON) returns a vector of length 4, but the length of initial conditions vector is
2. The vector returned by #(V,W)OPDRACHT1FUNCTIEV(V,ALPHA,W,C,GAMMA,VAREPSILON) and the initial conditions vector must have the same
number of elements.
Can anyone tell me where these 4 solutions come from whilst there only should be 2? The handle #(v,w) contains but two values, does this not suffice?
Thanks in advance!
You should read how to use ode45. Try the following:
tspan = [0, 6];
v0 = [1; 1];
w0 = [1; 1];
alpha = 0.7;
gamma = 0.8;
varepsilon = 12.5;
C = 0.5;
fun = #(v, alpha, w, C, gamma, varepsilon) ...
[v.*(1-v).*(v-alpha)-w+C;varepsilon*(v-gamma*w)]
ode = #(t, y) fun (y(1:2), alpha, y(3:4), C, gamma, varepsilon);
[tt,yy] = ode45(ode, tspan, [v0;w0]);
plot(tt, yy(:,1:2),'r')
xlabel ('t')
ylabel('solution v & w')
title ('opdracht 1, name')
hold all
plot(tt, yy(:,3:4),'b')