向量化 for 循环以填充行

Vectorize a for loop to fill row

我试图向量化以下内容:

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 给我一个错误:"Subscripted assignment dimension mismatch"我不确定我的代码哪里出错了?

此外,是否可以向量化整个嵌套 for 循环,而不仅仅是内部循环?

谢谢!

编辑: 抱歉,函数 getVal() returns 大小为 'i' 的随机向量。这用于在提供的代码中填充矩阵的行,因此这个 post 的问题标题 "Vectorize a for loop to fill row"。抱歉,如果不清楚。

示例数据: 对于 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

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

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

现在,如果您无法触及 getVal 但希望对所有内容进行矢量化,我会使用 arrayfun (https://www.mathworks.com/help/matlab/ref/arrayfun.html)

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.

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

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

num = arrayfun(@(i, m) max(max(cell2mat(arrayfun(@getVal, repmat(i, m, 1), 'UniformOutput', false)))), 1:n, repmat(m, 1, n));

请注意,这不会计算 mat,但我认为它并不是真正需要的,因为它会不断为每个 i.

重写

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

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