有人可以帮助矢量化这个matlab循环吗?

时间:2015-04-29 06:39:58

标签: matlab vectorization

我正在尝试学习如何向量化matlab循环,所以我只是做了一些小例子。

这是我试图矢量化的标准循环:

__declspec

我已经能够矢量化一个循环,但无法解决如何处理第二个循环。这是我到目前为止所处的位置:

function output = moving_avg(input, N)
    output = [];
    for n = N:length(input) % iterate over y vector
        summation = 0;
            for ii = n-(N-1):n % iterate over x vector N times
                summation += input(ii);
            endfor
        output(n) = summation/N;
    endfor 
endfunction

有人可以帮助我进一步简化吗?

修改
输入只是一维向量,可能最多100个数据点。 N是一个整数,小于输入的大小(通常可能大约为5)

我实际上不打算将它用于任何特定的应用程序,它只是一个简单的嵌套循环,我认为用它来学习矢量化很好..

3 个答案:

答案 0 :(得分:1)

好像你在那里表现convolution operation。所以,只需使用conv -

output = zeros(size(input1))
output(N:end) = conv(input1,ones(1,N),'valid')./N

请注意,我已将变量名称input替换为input1,因为input已被用作MATLAB中内置函数的名称,因此这是一个很好的做法避免此类冲突

通用案例:对于一般情况,您可以查看bsxfun来创建此类组,然后选择您打算在最后阶段执行的操作。以下是滑动/移动平均操作的代码如何 -

%// Create groups of indices for each sliding interval of length N
idx = bsxfun(@plus,[1:N]',[0:numel(input1)-N])  %//'

%// Index into input1 with those indices to get grouped elements from it along columns
input1_indexed = input1(idx)

%// Finally, choose the operation you intend to perform and apply along the
%// columns. In this case, you are doing average, so use mean(...,1).
output = mean(input1_indexed,1)
%// Also pre-append with zeros if intended to match up with the expected output

答案 1 :(得分:0)

Matlab作为一种语言很难做到这种类型的操作 - 你总是需要一个外部O(N)循环/操作,涉及至少O(K)副本,这在性能上不值得进一步矢量化,因为matlab是一个重量级语言。相反,考虑使用 in seperate classes函数,其中这些东西通常在C中实现,这使得这种类型的操作几乎是免费的。

答案 2 :(得分:0)

对于滑动平均值,您可以使用cumsum来最小化操作次数:

x = randi(10,1,10);                      %// example input
N = 3;                                   %// window length
y = cumsum(x);                           %// compute cumulative sum of x
z = zeros(size(x));                      %// initiallize result to zeros
z(N:end) = (y(N:end)-[0 y(1:end-N)])/N;  %// compute order N difference of cumulative sum