这个for循环可以进一步矢量化吗?
for i = 1:length(formula)
ttable(i,abs(formula(i,:))) = -1*formula(i,:);
end
formula
是矩阵和ttable = NaN(length(formula),max(max(abs(formula))))
。谢谢!
答案 0 :(得分:3)
根据代码判断,您正在做的是ttable
的每一行,您希望使用abs(formula(i,:))
访问的索引,并将每个位置设置为-1*formula(i,:)
。
注意到@Divakar的聪明之处,我将假设每一行都有唯一的绝对值。换句话说,每行不应包含连续a
或-a
行的实例,其中a
是从1
到size(formula,2)
的任意数字}。原因是因为在计算abs(formula(i,:))
时,-a
和a
会映射到同一列。这将发生冲突并允许覆盖相同的条目(Thanks @Divakar!)
我们可以为formula
的每一行做什么,将这些位置转换为列主要索引以访问ttable
。之后,将-1*formula
的相应值分配到ttable
。换句话说:
%// Find those columns that should be accessed
columnIndices = reshape(abs(formula).', 1, []);
%// For each column we are accessing, find the corresponding row
rowIndices = reshape(repmat(1:size(formula,2), size(formula, 1), 1), 1, []);
%// Find the column major indices we need to access overall
indices = sub2ind(size(formula), rowIndices, columnIndices);
%// Take those indices that we have computed above, and map them
%// to those columns we found earlier
ttable(indices) = -1*formula.';
这是我创建的一个小测试。这也是基于我之前做出的唯一绝对值的相同假设:
formula = [1 2 -3 4; 4 -2 3 1; 3 2 4 -1; -4 1 2 3];
ttable = NaN(length(formula),max(max(abs(formula))));
formula =
1 2 -3 4
4 -2 3 1
3 2 4 -1
-4 1 2 3
ttable =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
使用您的方法,我们得到:
for i = 1:length(formula)
ttable(i,abs(formula(i,:))) = -1*formula(i,:);
end
ttable =
-1 -2 3 -4
-1 2 -3 -4
1 -2 -3 -4
-1 -2 -3 4
使用我的方法,我们得到:
columnIndices = reshape(abs(formula).', 1, []);
rowIndices = reshape(repmat(1:size(formula,2), size(formula, 1), 1), 1, []);
indices = sub2ind(size(formula), rowIndices, columnIndices);
ttable(indices) = -1*formula.';
ttable =
-1 -2 3 -4
-1 2 -3 -4
1 -2 -3 -4
-1 -2 -3 4
如果您的矩阵很小,那么通过这样做而不是for
循环的计算开销可能会更大,因此这将是低效的。但是,如果矩阵较大,则此代码可能更快。无论哪种方式,我认为你的for
循环方法仍然很好。 JIT应该启动for
循环。如果您在对一个算法进行定时测试时看一下这篇文章,其中for
循环被用作算法之一,for
循环是最快的算法之一。点击此处:MATLAB: Subtracting matrix subsets by specific rows
答案 1 :(得分:0)
另一种方法,使用bsxfun
生成线性索引:
ind = bsxfun(@plus, (1:size(ttable,1)).' , (abs(formula)-1)*size(ttable,1));
ttable(ind) = -formula;