matlab - 如何向量化依赖的 For 循环

标签 matlab for-loop vectorization

我正在开发一个函数,该函数接受 1xn 向量 x 作为输入并返回 nxn 矩阵 L
我想通过向量化循环来加快速度,但有一个问题让我困惑:循环索引 b 取决于循环索引 a。任何帮助将不胜感激。

x = x(:); 
n = length(x);
L = zeros(n, n);
for a = 1 : n,
    for b = 1 : a-1,
        c = b+1 : a-1;
        if all(x(c)' < x(b) + (x(a) - x(b)) * ((b - c)/(b-a))),
            L(a,b) = 1;
        end
    end
end

最佳答案

从快速测试来看,您似乎只对下三角形进行了一些操作。您也许可以使用与此类似的 ind2subarrayfun 等丑陋技巧进行矢量化

tril_lin_idx = find(tril(ones(n), -1));
[A, B] = ind2sub([n,n], tril_lin_idx);
C = arrayfun(@(a,b) b+1 : a-1, A, B, 'uniformoutput', false); %cell array
f = @(a,b,c) all(x(c{:})' < x(b) + (x(a) - x(b)) * ((b - c{:})/(b-a)));
L = zeros(n, n);
L(tril_lin_idx) = arrayfun(f, A, B, C);

我无法测试它,因为我没有 x 并且我不知道预期的结果。我通常喜欢矢量化解决方案,但这可能有点太过了:)。我会坚持使用你的显式 for 循环,这可能会更清晰,并且 Matlab 的 JIT 应该能够轻松加速。您可以将 if 替换为 L(a,b) = all(...)

编辑1

更新版本,以防止浪费 C 上的 ~ n^3 空间:

tril_lin_idx = find(tril(ones(n), -1));
[A, B] = ind2sub([n,n], tril_lin_idx);
c = @(a,b) b+1 : a-1;
f = @(a,b) all(x(c(a, b))' < x(b) + (x(a) - x(b)) * ((b - c(a, b))/(b-a)));
L = zeros(n, n);
L(tril_lin_idx) = arrayfun(f, A, B);

编辑2

轻微变体,不使用 ind2sub,并且应该更容易修改,以防 b 以更复杂的方式依赖于 a。我内联了 c 以提高速度,似乎特别是调用函数句柄的成本很高。

[A,B] = ndgrid(1:n);
v = B<A; % which elements to evaluate
f = @(a,b) all(x(b+1:a-1)' < x(b) + (x(a) - x(b)) * ((b - (b+1:a-1))/(b-a)));
L = false(n);
L(v) = arrayfun(f, A(v), B(v));

关于matlab - 如何向量化依赖的 For 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18472555/

相关文章:

for-loop - Golang for循环中按索引构造变量名的最有效方法

r - 如何向量化模数?

matlab - 是否可以在不将单元格加载到内存的情况下将数据添加到 matlab 单元格中?

matlab - waitbar -> 条形图的长度?

python - 比较 3 个不同列表的位置和元素

python - 打印全名python的第一个字母

arrays - 数组中列的矢量化 reshape

python - 可以对数据框中的每一列应用百分位切割吗?

matlab - Matlab 可以进行惰性求值吗?

matlab - 用线分隔点/簇