Hi i've been asked to solve SIR model using fsolve command in MATLAB, and Euler 3 point backward. I'm really confused on how to proceed, please help. This is what i have so far. I created a function for 3BDF scheme but i'm not sure how to proceed with fsolve and solve the system of nonlinear ODEs. The SIR model is shown as and 3BDF scheme is formulated as
clc
clear all
gamma=1/7;
beta=1/3;
ode1= #(R,S,I) -(beta*I*S)/(S+I+R);
ode2= #(R,S,I) (beta*I*S)/(S+I+R)-I*gamma;
ode3= #(I) gamma*I;
f(t,[S,I,R]) = [-(beta*I*S)/(S+I+R); (beta*I*S)/(S+I+R)-I*gamma; gamma*I];
R0=0;
I0=10;
S0=8e6;
odes={ode1;ode2;ode3}
fun = #root2d;
x0 = [0,0];
x = fsolve(fun,x0)
function [xs,yb] = ThreePointBDF(f,x0, xmax, h, y0)
% This function should return the numerical solution of y at x = xmax.
% (It should not return the entire time history of y.)
% TO BE COMPLETED
xs=x0:h:xmax;
y=zeros(1,length(xs));
y(1)=y0;
yb(1)=y0+f(x0,y0)*h;
for i=1:length(xs)-1
R =R0;
y1(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - R, y1(i-1,:)+2*h*F(i,:))
S = S0;
y2(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - S, y2(i-1,:)+2*h*F(i,:))
I= I0;
y3(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - I, y3(i-1,:)+2*h*F(i,:))
end
end
You have an implicit equation
y(i+1) - 2*h/3*f(t(i+1),y(i+1)) = G = (4*y(i) - y(i-1))/3
where the right-side term G is constant in the call to fsolve, that is, during the solution of the implicit step equation.
Note that this is for the vector valued system y'(t)=f(t,y(t)) where
f(t,[S,I,R]) = [-(beta*I*S)/(S+I+R); (beta*I*S)/(S+I+R)-I*gamma; gamma*I];
To solve this write
G = (4*y(i,:) - y(i-1,:))/3
y(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - G, y(i-1,:)+2*h*F(i,:))
where a midpoint step is used to get an order 2 approximation as initial guess, F(i,:)=f(t(i),y(i,:)). Add solver options for error tolerances as necessary, you want the error in the implicit equation smaller than the truncation error O(h^3) of the step. One can also keep only a short array of function values, then one has to be careful for the correspondence of the position in the short array to the time index.
Using all that and a reference solution by a higher order standard solver produces the following error graphs for the components
where one can see that the first order error of the constant first step results in a first order global error, while with a second order error in the first step using the Euler method results in a clear second order global error.
Implement the method in general terms
from scipy.optimize import fsolve
def BDF2(f,t,y0,y1):
N, h = len(t)-1, t[1]-t[0];
y = (N+1)*[np.asarray(y0)];
y[1] = y1;
for i in range(1,N):
t1, G = t[i+1], (4*y[i]-y[i-1])/3
y[i+1] = fsolve(lambda u: u-2*h/3*f(t1,u)-G, y[i-1]+2*h*f(t[i],y[i]), xtol=1e-3*h**3)
return np.vstack(y)
Set up the model to be solved
gamma=1/7;
beta=1/3;
print beta, gamma
y0 = np.array([8e6, 10, 0])
P = sum(y0); y0 = y0/P
def f(t,y): S,I,R = y; trns = beta*S*I/(S+I+R); recv=gamma*I; return np.array([-trns, trns-recv, recv])
Compute a reference solution and method solutions for the two initialization variants
from scipy.integrate import odeint
tg = np.linspace(0,120,25*128)
yg = odeint(f,y0,tg,atol=1e-12, rtol=1e-14, tfirst=True)
M = 16; # 8,4
t = tg[::M];
h = t[1]-t[0];
y1 = BDF2(f,t,y0,y0)
e1 = y1-yg[::M]
y2 = BDF2(f,t,y0,y0+h*f(0,y0))
e2 = y2-yg[::M]
Plot the errors, computation as above, but embedded in the plot commands, could be separated in principle by first computing a list of solutions
fig,ax = plt.subplots(3,2,figsize=(12,6))
for M in [16, 8, 4]:
t = tg[::M];
h = t[1]-t[0];
y = BDF2(f,t,y0,y0)
e = (y-yg[::M])
for k in range(3): ax[k,0].plot(t,e[:,k],'-o', ms=1, lw=0.5, label = "h=%.3f"%h)
y = BDF2(f,t,y0,y0+h*f(0,y0))
e = (y-yg[::M])
for k in range(3): ax[k,1].plot(t,e[:,k],'-o', ms=1, lw=0.5, label = "h=%.3f"%h)
for k in range(3):
for j in range(2): ax[k,j].set_ylabel(["$e_S$","$e_I$","$e_R$"][k]); ax[k,j].legend(); ax[k,j].grid()
ax[0,0].set_title("Errors: first step constant");
ax[0,1].set_title("Errors: first step Euler")
I'm trying to solve this equation in Matlab
dT=((-A-B*C+D*./E)
where C=sin(dT). dT is unknown. A, B, D, and E are known variables. Using Matlab's solve function:
Ans=solve(dT==((-gra-H_vap*m_lg+grb*./ro_cp),dT);
But I receive an error message. How do I solve this equation?
You haven't given us any specifics on the values of your known parameters, and I also believe that D*/E in your example were intended to be a more valid expression.
Anyway, here is an example of how you make use of the symbolic solver solve:
syms dT
A = 1
B = 2
D = [1 2]
E = [3 4]
eqn = -A - B*sin(dT) + D/E - dT == 0
soldT = solve(eqn,dT)
which produces the following output
% ...
eqn =
- dT - 2*sin(dT) - 14/25 == 0
% ...
soldT =
-0.18739659458654612052194305796251
See also the language docs for solve.
I want to integrate a differential equation dc/dt. Below is the code and the values of the variables.
clear all;
c1=.185;c0=2*10^-6;k3=.1*10^-6;
v1=6;v2=.11;v3=.09*10^-6;
Ca_ER=10*10^-6;Ca_cyto=1.7*10^-6;
p_open3=0.15;c=15*10^-6;
dcdt= (c1*(v1*(p_open3)+v2)*(Ca_ER)-c)-v3*((c)^2)/(c^2+(k3)^2);
I know there is an integral function but I am not sure how to apply for this equation. How do I proceed from here? Please help. The value of initial c, if needed, can be taken as 0.15*10^-6. Also, I need to plot the obtained result versus time. So will get an array of values or just a single value?
the link to the article. the equation i have used comes under Calcium Oscillations section
You could use Euler method to solve this problem to get a rough idea regarding the solution yet not accurate.
clear all
clc
t = 0;
dt = 0.0001;
c1 = 0.185;
c0 = 2*10^-6;
k3 = 0.1*10^-6;
v1 =6;
v2 =.11;
v3 =.09*10^-6;
Ca_ER =10*10^-6;
Ca_cyto =1.7*10^-6;
p_open3 =0.15;
c = 15*10^-6;
%store initial values
C(1) = c;
T(1) = t;
for i = 1:40000
dc = ( (c1*(v1*(p_open3)+v2)*(Ca_ER)-c)- v3*( c^2 /( c^2+(k3)^2) ) );
c = c + dt*dc;
t = t + dt;
%store data
C(i+1) = c;
T(i+1) = t;
end
plot(T,C, 'LineWidth',2)
xlabel('time (sec)')
ylabel('c(t)')
grid on
The result is
You can also use Wolfram which gives same result.
Hello I am relatively new to MATLAB and have received and assignment in which we could use any programming language. I would like to continue MATLAB and have decided to use it for this assignment. The questions has to do with the following formula:
x(t) = A[1+a1*E(t)]*sin{w[1+a2*E(t)]*t+y}(+/-)a3*E(t)
The first question we have is to develop an appropriate discretization of x(t) with a time step h. I think i understand how to do this using step but because there is a +/- in the end I am running into errors. Here is what I have (I have simplified the equation by assigning arbitrary values to each variable):
A = 1;
E = 1;
a1 = 1;
a2 = 2;
a3 = 3;
w = 1;
y = 0;
% ts = .1;
% t = 0:ts:10;
t = 1:1:10;
x1(t) = A*(1+a1*E)*sin(w*(1+a2*E)*t+y);
x2(t) = a3*E;
y(t) = [x1(t)+x2(t), x1(t)-x2(t)]
plot(y)
The problem is I keep getting the following error because of the +/-:
In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in Try1 (line 21)
y(t) = [x1(t)+x2(t), x1(t)-x2(t)]
Any help?? Thanks!
You can remove the (t) from the left-hand side of all three assignments.
y = [x1+x2, x1-x2]
MATLAB knows what to do with vectors and matrices.
Or, if you want to write it out the long way, tell MATLAB there will be two columns:
y(t, 1:2) = [x1(t)'+x2(t)', x1(t)'-x2(t)']
or two rows:
y(1:2, t) = [x1(t)+x2(t); x1(t)-x2(t)]
But this won't work when you have fractional values of t. The value in parentheses is required to be the index, not a dependent variable. If you want the whole vector, just leave it out.
Solving coupled non linear differential equation by Mat-lab or by calculations
equation 1: x'(t) = -a* x(t) /(x(t) + y(t))
equation 2: y'(t) = -b* y(t) /(x(t) + y(t))
I tried in mathematica but got a very comlicated solution.
Solve[{x'[t] == -a* x[t] /(x[t] + y[t]), y'[t] == -b* y[t] /(x[t] + y[t])}, {x, y}, t]
How can I plot it?
My initial conditions are
x(0) = xo
y(0) = yo
Also, a and b are constants.
I have to plot x and y wrt t after inserting values of a and b . ( a= 2 , b =5 say )
A lot of things to note in this situation:
You need to create a function that contains both a and b:
function dy =soProblem(t,y,a,b)
dy=[-a*y(1)/(y(1)+y(2)); -b*y(2)/(y(1)+y(2))];
end
Call the standard ode function:
a = 2;
b = 5; tend = 10; x0 = 1; y0 = 2;
[T,Y] = ode45(#(t,y)soProblem(t,y,a,b),[0 tend],[x0 y0]);
plot (T,Y)
Realize you may have a stiff equation on your hands.
Have fun identifying the ideal function call:
[T15,Y15] = ode15s(#(t,y)soProblem(t,y,a,b),[0 tend],[x0 y0]);
[T23t,Y23t] = ode23t(#(t,y)soProblem(t,y,a,b),[0 tend],[x0 y0]);
[T23tb,Y23tb] = ode23tb(#(t,y)soProblem(t,y,a,b),[0 tend],[x0 y0]);
%note ode23s doesn't converge (or at least takes forever)
plot (T,Y,T15,Y15,T23t,Y23t,T23tb,Y23tb)
Understand why mathematica becomes restless
In mathematica:
Try ndsolve
In matlab:
Create a function file yourfunction.m:
function [Y_prime]=yourfunction(t, Y)
Y_prime=[-2*Y(1)./(Y(1) + Y(2)) -5*Y(2)./(Y(1) + Y(2))];
end
and then
[T,Y] = ode45(yourfunction,[0 t_end],[x0 y0]);
plot(T,Y(:,1));
hold on
plot(T,Y(:,2));