简体   繁体   中英

Matlab - Least Squares data fitting - Cost function with extra constraint

I am currently working on some MatLab code to fit experimental data to a sum of exponentials following a method described in this paper .

According to the paper, the data has to follow the following equation (written in pseudo-code):

y = sum(v(i)*exp(-x/tau(i)),i=1..n)

Here tau(i) is a set of n predefined constants. The number of constants also determines the size of the summation, and hence the size of v . For example, we can try to fit a sum of 100 exponentials, each with a different tau(i) to our data. However, due to the nature of the fitting and the exponential sum, we need to add another constraint to the problem, and hence to the cost function of the least-squares method used.

Normally, the cost function of the least-squares method is given by:

(y_data - sum(v(i)*exp(-x/tau(i)),i=1..n)^2

And this has to be minimized. However, to prevent over-fitting that would make the time-constant spectrum extremely noisy, the paper adds the following constraint to the cost function:

|v(i) - v(i+1)|^2

Because of this extra constraint, as far as I know, the regular algorithms, like lsqcurvefit aren't useable any longer, and I have to use fminsearch to search the minimum of my least-squares cost function with a constraint. The function that has to be minimized, according to me, is the following:

(y_data - sum(v(i)*exp(-x/tau(i)),i=1..n)^2 + sum(|v(j) - v(j+1)|^2,j=1..n-1)

My attempt to code this in MatLab is the following. Initially we define the function in a function script, then we use fminsearch to actually minimize the function and get values for v .

function res = funcost( v )
%FUNCOST Definition of the function that has to be minimised

%We define a function yvalues with 2 exponentials with known time-constants
% so we know the result that should be given by minimising.
xvalues = linspace(0,50,10000);
yvalues = 3-2*exp(-xvalues/1)-exp(-xvalues/10);

%Definition of 30 equidistant point in the logarithmic scale  
terms = 30;
termsvector = [1:terms];
tau = termsvector;
for i = 1:terms
    tau(i) = 10^(-1+3/terms*i);
end

%Definition of the regular function
res_1 = 3;

for i=1:terms
    res_1 =res_1+ v(i).*exp(-xvalues./tau(i));
end

res_1 = res_1-yvalues;

%Added constraint
k=1;
res_2=0;

for i=1:terms-1
    res_2 = res_2 + (v(i)-v(i+1))^2;
end

res=sum(res_1.*res_1) + k*res_2;

end

fminsearch(@funcost,zeros(30,1),optimset('MaxFunEvals',1000000,'MaxIter',1000000))

However, this code is giving me inaccurate results (no error, just inaccurate results), which leads me to believe I either made a mistake in the coding or in the interpretation of the added constraint for the least-squares method.

I would try to introduce the additional constrain in following way:

res_2 = max((v(1:(end-1))-v(2:end)).^2);

eg instead of minimizing an integrated (summed up) error, it does minmax.

You may also make this constrain stiff by

if res_2 > some_number
    k = a_very_big_number;
else
    k=0; % or k = a_small_number
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM