快速拟合线性函数。 MATLAB

时间:2018-02-15 08:30:18

标签: matlab curve-fitting linear

在我的代码中,我有一个瓶颈,我在其中为我的数据拟合线性函数。只需在数据点上插入一条线,然后找到方程k的参数bR^2y=k*x+b

MATLAB中有很多功能可以做到这一点。我使用polyfit()函数。但对我的需求来说似乎有些过分。问题是我必须执行大量的这些拟合(10 ^ 8或接近它)。

以下是我的代码示例:

nLines=5; % may be up to 10^8;
X=cellfun(@(x) rand(randi([50 100]),1),num2cell([1:nLines]'),...
    'UniformOutput',false);
Y=cellfun(@(x) rand(numel(x),1),X,...
    'UniformOutput',false);
K=nan(numel(X),1);
B=nan(numel(X),1);
R=nan(numel(X),1);
for iLine=1:numel(X)   
   coefs = polyfit(X{iLine}, Y{iLine}, 1);
   yf=polyval(coefs,X{iLine});
   K(iLine)=coefs(1);
   B(iLine)=coefs(2);
   R(iLine)=corr(Y{iLine},yf);
end

你能为这种大规模的线性拟合提供更快的解决方案吗?

P.S。我正在使用MATLAB R2017b,其中包含以下工具箱:

Optimization Toolbox 
Signal Processing Toolbox 
Statistics and Machine Learning Toolbox  

1 个答案:

答案 0 :(得分:0)

我似乎找到了答案。我可以使我的seqs大小相同,只是添加NaN到最后这个变体非常快,然后是polyfit解决方案。

%% Generate data
nLines=10^3; % may be up to 10^8;
X=cellfun(@(x) rand(randi([50 100]),1),num2cell([1:nLines]'),...
    'UniformOutput',false);
Y=cellfun(@(x) rand(numel(x),1),X,...
    'UniformOutput',false);
K=nan(numel(X),1);
B=nan(numel(X),1);
R=nan(numel(X),1);
dur1=[];
dur2=[];
%% Small hack 
% elongate all seqs by NaNs to obtain same size
longestLineSize=max(cellfun(@(x) numel(x),X));
matrixX=[];
matrixY=[];
N=[];
for iLine=1:numel(X)
    matrixX=[matrixX,[X{iLine};nan(longestLineSize-numel(1,X{iLine}),1)]];
    matrixY=[matrixY,[Y{iLine};nan(longestLineSize-numel(1,X{iLine}),1)]];
    N=[N, numel(1,X{iLine})];
end
for iRep=1:100
%% Vectorized approach
start=tic;
sumX=nansum(matrixX);
sumY=nansum(matrixY);
sumX2=nansum(matrixX.^2);
sum2X=sumX.^2;

sum2Y=sumY.^2;
XY=matrixX.*matrixY;
sumXY=nansum(XY);
nominator=N.*sumXY-sumX.*sumY;
denominator=(N.*sumX2-sum2X);

k=nominator./denominator;
b=(sumY-k.*sumX)./N;
r=nominator./sqrt(denominator.*(N.*nansum(matrixY.^2)-sum2Y));
dur1(end+1)=toc(start);
%% polyfit solution
start=tic;
for iLine=1:numel(X)   
   coefs = polyfit(X{iLine}, Y{iLine}, 1);
   yf=polyval(coefs,X{iLine});
   K(iLine)=coefs(1);
   B(iLine)=coefs(2);

   R(iLine)=corr(Y{iLine},yf);
end
dur2(end+1)=toc(start);
end

enter image description here