51 views (last 30 days)

Show older comments

I'm trying to fit a function to some data using MultiStart in order to find more reliably the global minimum.

This is the code:

[~,~,CPSC,t] = generate_current(80,15,0,-70,-30,0.44,15,0.73,3,120); % Generate current

% Initial values

gmc = 50;

gmg = 50;

tde = 1;

tdi = 1;

tre = 1;

tri = 1;

G_max_chl = 80;

G_max_glu = 15;

EGlu = -70;

EChl = 0;

Vm = -30;

tau_rise_In = 0.44;

tau_decay_In = 15;

tau_rise_Ex = 0.73;

tau_decay_Ex = 3;

y = awgn(CPSC,25,'measured'); % Add white noise

%% Perform fit

[xdata, ydata] = prepareCurveData(t, y);

lb = [-70 0 1 1 -30 0 0 0 0]; % Lower bound

ub = [-70 0 150 150 -30 20 20 5 5]; % Upper bound

p0 = [-70 0 gmc gmg -30 tde tdi tre tri]; % Starting values

% Set up fittype and options.

fitfcn = @(varargin) ((G_max_chl) .* ((1 - exp(-t / tau_rise_In)) .* exp(-t / tau_decay_In)) * (Vm - EChl)) + ((G_max_glu) .* ((1 - exp(-t / tau_rise_Ex)) .* exp(-t / tau_decay_Ex)) * (Vm - EGlu));

[xfitted,errorfitted] = lsqcurvefit(fitfcn,p0,xdata,ydata,lb,ub);

problem = createOptimProblem('lsqcurvefit','x0',p0,'objective',fitfcn,...

'lb',lb,'ub',ub,'xdata',xdata,'ydata',ydata);

ms = MultiStart('PlotFcns',@gsplotbestf);

[xmulti,errormulti] = run(ms,problem,50)

%% Plot fit with data

figure( 'Name', 'Fit' );

h = plot( fitresult1, xdata, ydata );

legend( h, 'CPSC at -30mV', 'Fit to CPSC', 'Location', 'NorthEast', 'Interpreter', 'none');

subtitle('Realistic values')

% Label axes

xlabel( 'time', 'Interpreter', 'none' );

ylabel( 'pA', 'Interpreter', 'none' );

grid on

And this is the function that I call at the beginning:

function [EPSC, IPSC, CPSC, t] = generate_current(G_max_chl, G_max_glu, EGlu, EChl, Vm, tau_rise_In, tau_decay_In, tau_rise_Ex, tau_decay_Ex,tmax)

dt = 0.1; % time step duration (ms)

t = 0:dt:tmax-dt;

% Compute compound current

IPSC = ((G_max_chl) .* ((1 - exp(-t / tau_rise_In)) .* exp(-t / tau_decay_In)) * (Vm - EChl));

EPSC = ((G_max_glu) .* ((1 - exp(-t / tau_rise_Ex)) .* exp(-t / tau_decay_Ex)) * (Vm - EGlu));

CPSC = IPSC + EPSC;

end

The error that I get is:

Error using lsqcurvefit (line 269)

Function value and YDATA sizes are not equal.

Error in global_m_fit (line 32)

[xfitted,errorfitted] = lsqcurvefit(fitfcn,p0,xdata,ydata,lb,ub);

I'm not sure why that is the case.

Thanks!

Walter Roberson
on 15 Mar 2021

fitfcn = @(varargin) ((G_max_chl) .* ((1 - exp(-t / tau_rise_In)) .* exp(-t / tau_decay_In)) * (Vm - EChl)) + ((G_max_glu) .* ((1 - exp(-t / tau_rise_Ex)) .* exp(-t / tau_decay_Ex)) * (Vm - EGlu));

That ignores the input trial parameters, returning a constant expression. However the curve fitting routines pass in trial coefficients of a smaller size in order to validate the function, and your routine is failing to return something of the same size as the trial coefficients.

It is not clear to me what the point is in using a fitting function that ignores its inputs.

Alan Weiss
on 15 Mar 2021

I think that you need to have just one input variable, typically called x, and have each of your other named variables be a component of x. For example,

function y = objfun(x)

EGlu = x(1);

EChl = x(2);

G_max_chl = x(3);

G_max_glu = x(4);

Vm = x(5);

tau_rise_In = x(6);

tau_decay_In = x(7);

tau_rise_Ex = x(8);

tau_decay_Ex = x(9);

t = x(10);

y = ((G_max_chl) .* ((1 - exp(-t / tau_rise_In)) .* exp(-t / tau_decay_In)) * (Vm - EChl)) + ((G_max_glu) .* ((1 - exp(-t / tau_rise_Ex)) .* exp(-t / tau_decay_Ex)) * (Vm - EGlu));

end

For details, see Writing Scalar Objective Functions. But maybe I got it wrong, and you are using lsqnonlin. Make the appropriate modifications as in Writing Vector and Matrix Objective Functions.

Alan Weiss

MATLAB mathematical toolbox documentation

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

Start Hunting!