我目前正在研究一些MatLab代码,以根据this paper中描述的方法将实验数据拟合到指数之和。
根据该论文,数据必须遵循以下等式(用伪代码编写):
y = sum(v(i)*exp(-x/tau(i)),i=1..n)
此处tau(i)
是一组n
预定义常量。常数的数量也决定了求和的大小,因此也决定了v
的大小。例如,我们可以尝试拟合100个指数的总和,每个指数与我们的数据具有不同的tau(i)
。然而,由于拟合的性质和指数和,我们需要为问题添加另一个约束,因此需要使用最小二乘法的成本函数。
通常,最小二乘法的成本函数由下式给出:
(y_data - sum(v(i)*exp(-x/tau(i)),i=1..n)^2
这必须最小化。然而,为了防止过度拟合会使时间常数频谱极其嘈杂,本文将以下约束添加到成本函数中:
|v(i) - v(i+1)|^2
由于这个额外的限制,据我所知,常规算法,如lsqcurvefit
不再可用,我必须使用fminsearch
来搜索我的最小值具有约束的最小二乘成本函数。根据我的说法,必须最小化的功能如下:
(y_data - sum(v(i)*exp(-x/tau(i)),i=1..n)^2 + sum(|v(j) - v(j+1)|^2,j=1..n-1)
我在MatLab中对此进行编码的尝试如下。最初我们在函数脚本中定义函数,然后我们使用fminsearch
来实际最小化函数并获取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))
然而,这段代码给了我不准确的结果(没有错误,只是不准确的结果),这使我相信我在编码或解释最小二乘法的附加约束时犯了错误。 / p>
答案 0 :(得分:0)
我会尝试以下列方式介绍其他约束:
res_2 = max((v(1:(end-1))-v(2:end)).^2);
e.g。它不是最小化积分(总计)误差,而是最小值。
您也可以通过
使这种约束变得僵硬if res_2 > some_number
k = a_very_big_number;
else
k=0; % or k = a_small_number
end;