Changing numeric variables based on symbolic variables in a set of differential equations.

16 views (last 30 days)
I am implementing a mathematical model of the cardiovascular system based on a paper by Burkhoff and Tyberg.
Below is my code, with screenshots of the equations in the paper that I am attempting to represent. Any variable that is not symbolic is a constant parameter that is set at the start of the code (not shown).
%create symbols
syms V_lv(t) V_rv(t) V_C_as(t) V_C_vs(t) V_C_ap(t) V_C_vp(t) e(t)
tAll = [];
yAll = [];
tPool = [0 2*T_es T]; % time periods in the cardiac cycle
yInit = [12 16 32 23 40 50]; % initial conditions (volumes)
%initialise ejection/filling coefficients
alpha_rv = 0;
alpha_lv = 1;
beta_rv = 0;
beta_lv = 1;
for k = 1:numel(tPool) - 1
%ventricles (time varying elastance)
P_es_lv = E_es_lv*(V_lv - V_0); % LV ESPVR
P_ed_lv = A*(exp(B_lv*(V_lv - V_0)) - 1); % LV EDPVR
P_es_rv = E_es_rv*(V_rv - V_0); % RV ESPVR
P_ed_rv = A*(exp(B_rv*(V_rv - V_0)) - 1); %RV EDPVR
switch k
case 1
e = 0.5*(1-cos(2*pi*t/T_es));
case 2
e = 0;
case 3
e = 0;
end
P_lv = (P_es_lv - P_ed_lv)*e + P_ed_lv; %left ventricular pressure
P_rv = (P_es_rv - P_ed_rv)*e + P_ed_rv; %right ventricular pressure
The above code represents this section (except that I have implemented a simpler version of the piecewise e(t) function:
%systemic and pulmonary circulation
P_C_as = V_C_as/C_as; % systemic arteries
P_C_vs = V_C_vs/C_vs; % systemic veins
P_C_ap = V_C_ap/C_ap; % pulmonary arteries
P_C_vp = V_C_vp/C_vp; % pulmonary veins
The above code represents this section:
%blood volume
V_T = V_C_as + V_C_vs + V_C_ap + V_C_vp + V_U + V_lv + V_rv;
%differential equations
ode1 = diff(V_lv) == ((P_C_vp - P_lv)/R_vp)*alpha_lv - ((P_lv - P_C_as)/R_cs)*beta_lv;
ode2 = diff(V_rv) == ((P_C_vs - P_rv)/R_vp)*alpha_rv - ((P_rv - P_C_ap)/R_cp)*beta_rv;
ode3 = diff(V_C_as) == ((P_lv - P_C_as)/R_cs)*beta_lv - ((P_C_as - P_C_vs)/R_as);
ode4 = diff(V_C_vs) == ((P_C_as - P_C_vs)/R_as) - ((P_C_vs - P_rv)/R_vs)*alpha_rv;
ode5 = diff(V_C_ap) == ((P_rv - P_C_ap)/R_cp)*beta_rv - ((P_C_ap - P_C_vp)/R_ap);
ode6 = diff(V_C_vp) == ((P_C_ap - P_C_vp)/R_ap) - ((P_C_vp - P_lv)/R_vp)*alpha_lv;
odes = [ode1; ode2; ode3; ode4; ode5; ode6];
[VF, Sbs] = odeToVectorField(odes);
%solve numerically
M = matlabFunction(VF,'vars',{'t','Y'});
[T, Y] = ode45(M, [tPool(k:k+1)], yInit);
tAll = cat(1, tAll, T); % Append new solution to total solution
yAll = cat(1, yAll, Y);
yInit = Y(end, :); % Update the initial value
The above code represents this section:
%set ejection/filling coefficients
end
plot(tAll, yAll)
As seen in equations A11 to A16, there are four coefficients that are set to either 1 or 0 depending on whether ventricular ejection or filling is occuring:
I know that I can't compare these pressure values directly as they are symbolic. I have tried using subs, but that only works for the pressures that don't contain time-varying terms. For example:
test1 = subs(P_lv, V_lv, Y(end, 1))
test2 = subs(P_C_vp, V_C_vp, Y(end, 6))
test1 can be converted into a double, but test2 can't.
I implemented the piecewise e(t) function based on an answer from this post, but I can't figure out how to change the values of alpha and beta at each t value based on logical comparisons of symbolic variables.
Any help is appreciated.

Accepted Answer

Star Strider
Star Strider on 18 Sep 2023
It can, actually, using the vpa function:
test1 = vpa(subs(P_lv, V_lv, Y(end, 1)), 8)
test2 = vpa(subs(P_C_vp, V_C_vp, Y(end, 6)), 8)
however something is missing here, so I cannot run the code —
%create symbols
syms V_lv(t) V_rv(t) V_C_as(t) V_C_vs(t) V_C_ap(t) V_C_vp(t) e(t)
tAll = [];
yAll = [];
tPool = [0 2*T_es T]; % time periods in the cardiac cycle
Unrecognized function or variable 'T_es'.
yInit = [12 16 32 23 40 50]; % initial conditions (volumes)
%initialise ejection/filling coefficients
alpha_rv = 0;
alpha_lv = 1;
beta_rv = 0;
beta_lv = 1;
for k = 1:numel(tPool) - 1
%ventricles (time varying elastance)
P_es_lv = E_es_lv*(V_lv - V_0); % LV ESPVR
P_ed_lv = A*(exp(B_lv*(V_lv - V_0)) - 1); % LV EDPVR
P_es_rv = E_es_rv*(V_rv - V_0); % RV ESPVR
P_ed_rv = A*(exp(B_rv*(V_rv - V_0)) - 1); %RV EDPVR
switch k
case 1
e = 0.5*(1-cos(2*pi*t/T_es));
case 2
e = 0;
case 3
e = 0;
end
P_lv = (P_es_lv - P_ed_lv)*e + P_ed_lv; %left ventricular pressure
P_rv = (P_es_rv - P_ed_rv)*e + P_ed_rv; %right ventricular pressure
%set ejection/filling coefficients
end
plot(tAll, yAll)
test1 = vpa(subs(P_lv, V_lv, Y(end, 1)), 8)
test2 = vpa(subs(P_C_vp, V_C_vp, Y(end, 6)), 8)
.
  8 Comments

Sign in to comment.

More Answers (0)

Categories

Find more on Cardiology in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!