矢量化for循环以填充行

时间:2018-04-05 06:01:18

标签: matlab optimization vectorization nested-loops

我试图对以下内容进行矢量化:

for i = 2:n
    mat = NaN(m,i);
    for j = 1:m
        mat(j,:) = getVal(i);
    end
    num(i) = max(mat(:));
end

for i = 2:n
    mat = NaN(m,i);
    j = 1:m;
    mat(j,:) = getVal(i);
    num(i) = max(mat(:));
end

但是,MATLAB给了我一个错误:“订阅的分配维度不匹配”我不确定我的代码出错了什么?

另外,是否可以对整个嵌套for循环进行矢量化,而不仅仅是内循环?

谢谢!

编辑:道歉,函数getVal()返回一个大小为'i'的随机向量。这用于填充提供的代码中的矩阵行,因此这篇文章的标题为“向量化一个for循环以填充行”。对不起,如果不清楚的话。

示例数据: 对于i = 2,输出如下: Matrix Output 1矩阵的行在内循环中一次填充一个。 对于i = 3,它与上面相同,而是使用3列: Matrix Output 2

希望这很清楚?

编辑2:我刚刚尝试使用Cris Luengo解决方案建议的repmat。这是我的输出:Matrix Output with repmat。我需要每次都运行getVal函数,而不是简单地运行一次并将其内容复制到行中。

编辑3:好的,这是我的函数getVal(i):

function [A] = getVal(m)
    X = normrnd(0,1,[m,m]);
    A = triu(X) + triu(X)';
    A = A - diag(diag(A))/2;
    A = eig(A)';
end

1 个答案:

答案 0 :(得分:0)

从您的示例中,getVal(i)不会为重复调用返回相同的输出。由于我没有您的代码,我使用以下方法模拟了该行为:

impl

现在,如果您无法触摸getVal但希望将所有内容都矢量化,我会使用impl<T> Vec<T> { pub fn new() -> Vec<T> { /* ... */ } } impl<T> Vec<T> where T: Clone, { pub fn resize(&mut self, new_len: usize, value: T) { /* ... */ } } https://www.mathworks.com/help/matlab/ref/arrayfun.html

function out = getVal(i)
   out = rand(1, i);
end

您的其余代码是相同的。请注意,一切都像以前一样工作,你只是没有循环。

但你还有外循环。另一个arrayfun处理:

arrayfun

请注意,这不会计算mat = cell2mat(arrayfun(@getVal, repmat(i, m, 1), 'UniformOutput', false)); % UniformOutput is needed because output isn't a scalar. Cell2mat is used to convert to the same matrix as previously. ,但我认为它不是真正需要的,因为它会不断重写num = arrayfun(@(i, m) max(max(cell2mat(arrayfun(@getVal, repmat(i, m, 1), 'UniformOutput', false)))), 1:n, repmat(m, 1, n));

但是......它不是更快。我用n = 1000,m = 1000定时,你的代码有2个循环给我7.3s,第一个向量化方法在10.8s完成,最后一个在10.7s完成,2循环方法再次在7.1结束这一次。

真正加速代码的明显步骤是对getVal进行矢量化 - 这是我无法帮助你的,只要我不知道它到底是做什么的。但是如果这个上部rand方法在大约5秒内完成,如果它在一个步骤中返回整个垫子。