如何在没有循环的情况下进行矩阵的逐列循环移位 [英] How to perform a column by column circular shift of a matrix without a loop

查看:148
本文介绍了如何在没有循环的情况下进行矩阵的逐列循环移位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to circularly shift individual columns of a matrix.

如果您想将所有列都移位相同的数量,这很容易,但是,在我的情况下,我需要将所有列都移位不同的数量.

This is easy if you want to shift all the columns by the same amount, however, in my case I need to shift them all by a different amount.

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

Currently I'm using a loop and if possible I'd like to remove the loop and use a faster, vector based, approach.

我当前的代码

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

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

Is is possible to remove the loop from this code?

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

Update I tested all three methods and compared them to the loop described in this question. I timed how long it would take to execute a column by column circular shift on a 1000x1000 matrix 100 times. I repeated this test several times.

结果:

  • 我的循环花了12秒钟以上
  • 追求的建议不到一秒钟
  • Zroth的原始回答花了2秒钟多一点
  • Ansari的建议比原始循环慢

推荐答案

编辑

追求是正确的:使用for循环和适当的索引似乎是解决问题的方法.这是一种实现方法:

Edit

Pursuit is right: Using a for-loop and appropriate indexing seems to be the way to go here. Here's one way of doing it:

[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

原始答案

我之前一直在寻找类似的东西,但是我从来没有遇到过一个好的解决方案. 此处在我的测试中提供了轻微的性能提升:

Original answer

I've looked for something similar before, but I never came across a good solution. A modification of one of the algorithms used here gives a slight performance boost in my tests:

[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 = 3000n = 1000的两种算法都在不到一秒的时间内运行(同样在较旧的计算机上).

Ugly? Definitely. Like I said, it seems to be slightly faster (2--3 times faster for me); but both algorithms are clocking in at under a second for m = 3000 and n = 1000 (on a rather old computer, too).

可能值得一提的是,对我来说,这两种算法似乎都比Ansari提供的算法要好,尽管他的回答肯定更简单. (对于我来说,Ansari的算法输出与其他两种算法不一致;但这可能只是如何应用移位的差异.)通常,arrayfun在我尝试使用它时似乎很慢.细胞阵列对我来说似乎也很慢.但是我的测试可能会因某种原因而产生偏差.

It might be worth noting that, for me, both algorithms seem to outperform the algorithm provided by Ansari, though his answer is certainly more straightforward. (Ansari's algorithm's output does not agree with the other two algorithms for me; but that could just be a discrepancy in how the shifts are being applied.) In general, arrayfun seems pretty slow when I've tried to use it. Cell arrays also seem slow to me. But my testing might be biased somehow.

这篇关于如何在没有循环的情况下进行矩阵的逐列循环移位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆