Optimisation for 3-element Windkessel Model Not Working - Using Least Squares Method and fminsearch. Advice? Should I use other optimisation algorithms?
Show older comments
So I am trying to optimise the parameters (R1, R2, C) for the 3-element windkessel model for the aorta. I am supplying it with tabular data for the Pressure and Flow (Q), but neither of the models are doing anything, and not giving any errors either. Kindly advise.

My code is as follows:
clear all
close all
clc
%% Inputs
R1 = 4.4e+6;
R2 = 1.05e+8;
C = 1.31e-8;
% L = 6.799e+5;
TimeStep = 0.001;
Beta = TimeStep / (C*R2);
%Initial conditions for WK-3 parameters
IC = [C, R1, R2];
%% Importing flow and pressure data
RefPQWK = readtable('Ref_P_Q_WK_No-Osc_1-Cycle.csv');
t=RefPQWK.t;
Q=RefPQWK.Q;
P=RefPQWK.P;
P0=RefPQWK.P(1);
Q0=RefPQWK.Q(1);
dt = TimeStep;
t_0 = 0:dt:t(end);
Q = smooth(interp1(t, Q, t_0), 50);
P = smooth(interp1(t, P, t_0), 50);
%Initial conditions
IC_Q = Q(1);
IC_P = P(1);
dP = diff(P)./dt;
dP(end+1) = dP(end);
dQ = diff(Q)./dt;
dQ(end+1) = dQ(end);
%dqdt = derivative(Q,t_0);
%% Curve fitting using the method of least squares
LB = [1e-10 1 1]; UB = [1 1e10 1e10]; % Lower and Upper bounds
options = optimoptions('lsqcurvefit', 'Algorithm', 'levenberg-marquardt', 'StepTolerance', 1e-100,'FunctionTolerance', 1e-10,'Display','iter');
%options = optimoptions('lsqcurvefit', 'Algorithm', 'levenberg-marquardt', 'MaxFunctionEvaluations', 1e100, 'MaxIterations', 1e4, 'StepTolerance',1e-300, 'Display','iter');
%options =optimoptions('lsqcurvefit','MaxFunctionEvaluations', 1e100, 'MaxIterations', 1e100,'Display','iter');
f = @(x, t_0)fun_lsq(x, t_0, dt, P, Q, dQ, IC_P);
%ydata=zeros(1, height(P))';
sol = lsqcurvefit(f, IC, t_0, P, LB, UB, options);
C_optim = sol(1); Rp_optim = sol(2); Rd_optim = sol(3);
%% Curve fitting using the fminsearch
% options = optimset('Display','iter','PlotFcns',@optimplotfval);
%
% f = @(x)fun_fmin(x, t_0, dt, P, Q, dQ, IC_P);
% sol = fminsearch(f,IC);
%% Solving and Plotting ODE for P
tspan = [t_0(1):dt:t_0(end)]; %Time interval of the integration
funP = @(t,y_P) P_odefcn(t, y_P, C, R1, R2, t_0, Q, dQ);
[t,y_P] = ode78(funP, tspan, IC_P);
funP_opt = @(t,y_P_opt) P_odefcn(t, y_P_opt, C, R1, R2, t_0, Q, dQ);
[t,y_P_opt] = ode78(funP, tspan, IC_P);
% y_Q = smooth(interp1(t, y_Q, t_0), 50);
y_P = smooth(interp1(t, y_P, t_0), 50);
y_P_opt = smooth(interp1(t, y_P, t_0), 50);
figure(1), plot(t_0, P), hold on, plot(t_0, y_P); hold on, plot(t_0, y_P_opt);
xlabel('Time'); ylabel('P')
legend('Actual', 'Stergiopoulos', 'Optimised')
%% Function for lsq optimisation
function f = fun_lsq(x, time, dt, P_in, Q_out, dQ_out, IC_p)
%Renaming the constants
C = x(1); R1 = x(2); R2 = x(3);
tspan = [0:dt:time(end)]; %Time interval of the integration
%Solving the ODEs
fun2 = @(t,y) P_odefcn(t, y, C, R1, R2, time, Q_out, dQ_out);
[t,y] = ode78(fun2, tspan, IC_p);
P = y(:,1);
%Q=interp1(t, Q, time);
f = P-P_in;
end
%% Function for fminsearch optimisation
function f = fun_fmin(x, time, dt, P_in, Q_out, dQ_out, IC_p)
%Renaming the constants
C = x(1); R1 = x(2); R2 = x(3);
tspan = [0:dt:time(end)]; %Time interval of the integration
%Solving the ODEs
fun2 = @(t,y) P_odefcn(t, y, C, R1, R2, time, Q_out, dQ_out);
[t,y] = ode78(fun2, tspan, IC_p);
P = y(:,1);
%Q=interp1(t, Q, time);
f = sqrt(sum((P-P_in).^2));
end
%% Function for ODE
function dPdt = P_odefcn(t, y, C, Rp, Rd, time, Q_in, dQ_in)
dPdt = zeros(1,1); %Initializing the output vector
%Determine the closest point to the current time
[d, closestIndex]=min(abs(time-t));
Q = Q_in(closestIndex);
dQ = dQ_in(closestIndex);
dPdt(1) =(Q/C)*(1+Rp/Rd) + Rp*dQ - y(1)/(C*Rd);
end
Both results look like this:

I do get the following for the LSQ method though:

6 Comments
Torsten
on 24 Mar 2024
We miss your .csv file.
Hussam
on 24 Mar 2024
Torsten
on 24 Mar 2024
You didn't include the function "derivative". Please test beforehand under MATLAB online if the code works.
Hussam
on 24 Mar 2024
Torsten
on 24 Mar 2024
If you use "lsqcurvefit", you must return
f = P;
not
f = P-P_in;
Don't you have a separate equation for Q so that you wouldn't need to differentiate your measurement data ?
[d, closestIndex]=min(abs(time-t));
Q = Q_in(closestIndex);
dQ = dQ_in(closestIndex);
Hussam
on 24 Mar 2024
Accepted Answer
More Answers (0)
Categories
Find more on Get Started with Curve Fitting Toolbox 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!





