matlab – 如何在没有循环的情况下逐列循环移位

我需要循环移动矩阵的各个列.

如果你想将所有列移动相同的数量,这很容易,但是,在我的情况下,我需要将它们全部移动不同的数量.

目前我正在使用循环,如果可能的话,我想删除循环并使用更快的,基于矢量的方法.

我目前的代码

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

是否可以从此代码中删除循环?

更新我测试了所有三种方法,并将它们与本问题中描述的循环进行了比较.我计算了在1000×1000矩阵上按列循环移位100次执行列所需的时间.我重复了几次这个测试.

结果:

>我的循环耗时超过12秒
> Pursuit的建议不到一秒钟
> Zroth的原始答案仅用了2秒多
>安萨里的建议比原始循环慢

最佳答案 编辑

追求是正确的:使用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似乎相当慢.细胞阵列对我来说似乎也很慢.但我的测试可能会有所偏见.

点赞