我需要循环移动矩阵的各个列。
如果你想将所有列移动相同的数量,这很容易,但是,在我的情况下,我需要将它们全部移动不同的数量。
目前我正在使用循环,如果可能的话,我想删除循环并使用更快的,基于矢量的方法。
我当前的代码
A = randi(2, 4, 2);
B = A;
for i = 1:size( A,2 );
d = randi( size( A,1 ));
B(:,i) = circshift( A(:,i), [d, 0] );
end
是否可以从此代码中删除循环?
更新我测试了所有三种方法,并将它们与此问题中描述的循环进行了比较。我计算了在1000x1000矩阵上按列循环移位100次执行列所需的时间。我重复了几次这个测试。
结果:
答案 0 :(得分:3)
追求是对的:使用for循环和适当的索引似乎是这里的方式。这是一种方法:
[m, n] = size(A);
D = randi([0, m - 1], [1, n]);
B = zeros(m, n);
for i = (1 : n)
B(:, i) = [A((m - D(i) + 1 : m), i); A((1 : m - D(i) ), i)];
end
之前我曾经找过类似的东西,但我从未遇到过一个好的解决方案。使用here之一的算法的修改在我的测试中略微提升了性能:
[m, n] = size(A);
mtxLinearIndices ...
= bsxfun(@plus, ...
mod(bsxfun(@minus, (0 : m - 1)', D), m), ...
(1 : m : m * n));
C = A(idxs);
丑?当然。就像我说的那样,它似乎稍快一些(对我来说要快2-3倍);但是这两种算法的时间都在m = 3000
和n = 1000
不到一秒钟(在一台相当旧的计算机上)。
值得注意的是,对我来说,这两种算法似乎都优于Ansari提供的算法,尽管他的回答肯定更直接。 (Ansari的算法输出与我的其他两种算法不一致;但这可能只是变换应用方式的差异。)一般来说,arrayfun
似乎很慢,当我尝试使用它时。细胞阵列对我来说似乎也很慢。但我的测试可能会有某种偏见。
答案 1 :(得分:0)
不确定这会有多快,但你可以试试这个:
[nr, nc] = size(A);
B = arrayfun(@(i) circshift(A(:, i), randi(nr)), 1:nc, 'UniformOutput', false);
B = cell2mat(B);
你必须对它进行基准测试,但使用arrayfun可能会加快它的速度。
答案 2 :(得分:-1)
我怀疑,你的循环移位,对随机整数矩阵的操作不再使它更随机,因为数字是均匀分布的。
所以我希望你的问题是使用randi()仅用于演示目的。