【问题标题】:Fast rolling correlation in MatlabMatlab中的快速滚动相关
【发布时间】:2015-04-21 22:20:35
【问题描述】:

我正在尝试导出一个函数来计算两个向量的移动/滚动相关性,并且速度是一个高优先级,因为我需要在数组函数中应用这个函数。我所拥有的(太慢了)是这样的:

Data1 = rand(3000,1);
Data2 = rand(3000,1); 

function y = MovCorr(Data1,Data2)

[N,~] = size(Data1);

correlationTS = nan(N, 1);

for t = 20+1:N
    correlationTS(t, :) = corr(Data1(t-20:t, 1),Data2(t-20:t,1),'rows','complete');
end
    y = correlationTS;
end

如果我知道如何生成滚动窗口索引然后应用accumarray,我认为for 循环可以更有效地完成。有什么建议吗?

【问题讨论】:

  • 这不是类似于将元素乘积与ones(1,21) 进行卷积吗?因为我不是很熟悉:你有移动相关性的公式吗?
  • 不确定您所说的“元素乘积与 (1,21)”是什么意思? MovCorr 上面的函数会产生正确的值。它太慢了。它在两个向量 Data1 和 Data2 之间产生 21 个观察值移动相关性。
  • 顺便说一句:你上面的代码甚至没有运行(因为Data1(.,2)
  • 啊,对不起....它现在应该可以工作了
  • 另外:这是 22 次观察。

标签: matlab correlation accumarray


【解决方案1】:

遵循@knedlsepp 的建议,并使用movingstd 中的过滤器,我找到了以下解决方案,速度非常快:

function Cor = MovCorr1(Data1,Data2,k)
y = zscore(Data2);
n = size(y,1);

if (n<k)
    Cor = NaN(n,1);
else
    x = zscore(Data1);
    x2 = x.^2;
    y2 = y.^2;
    xy = x .* y;
    A=1;
    B = ones(1,k);
    Stdx = sqrt((filter(B,A,x2) - (filter(B,A,x).^2)*(1/k))/(k-1));
    Stdy = sqrt((filter(B,A,y2) - (filter(B,A,y).^2)*(1/k))/(k-1));
    Cor = (filter(B,A,xy) - filter(B,A,x).*filter(B,A,y)/k)./((k-1)*Stdx.*Stdy);
    Cor(1:(k-1)) = NaN;
end
end

与我原来的解决方案相比,执行时间是:

tic
MovCorr(Data1,Data2);
toc
Elapsed time is 1.017552 seconds.

tic
MovCorr1(Data1,Data2,21);
toc
Elapsed time is 0.019400 seconds.

【讨论】:

    猜你喜欢
    • 2021-12-30
    • 2011-02-23
    • 2020-12-17
    • 2017-05-30
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    相关资源
    最近更新 更多