【问题标题】:How to perform a column by column circular shift of a matrix without a loop如何在没有循环的情况下执行矩阵的逐列循环移位
【发布时间】:2023-03-03 11:54:01
【问题描述】:

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

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

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

我当前的代码

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 次逐列循环移位需要多长时间。我重复了几次这个测试。

结果

  • 我的循环耗时超过 12 秒
  • Pursuit 的建议不到一秒
  • Zroth 的原始答案只用了 2 秒多一点
  • Ansari 的建议比原来的循环慢

【问题讨论】:

  • 我认为没有循环是不可能的。如果您需要它更快,您可以在 c 中编写自己的扩展。
  • 我会不理会循环。 Matlab 实际上非常擅长循环和低级操作。我会尝试删除对circshift 的调用,并将其替换为适当的索引操作。 circshift 包含有用的错误检查和输入解析,您可以不用。

标签: matlab


【解决方案1】:

编辑

追求是正确的:使用 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 = 3000n = 1000(在相当旧的计算机上也是如此),这两种算法都在不到一秒的时间内完成。

值得注意的是,对我来说,这两种算法似乎都优于 Ansari 提供的算法,尽管他的回答肯定更直接。 (对我来说,Ansari 算法的输出与其他两种算法不一致;但这可能只是应用转换方式的差异。)一般来说,arrayfun 在我尝试使用它时似乎很慢。单元阵列对我来说似乎也很慢。但我的测试可能会以某种方式存在偏差。

【讨论】:

    【解决方案2】:

    不确定这会快多少,但你可以试试这个:

    [nr, nc] = size(A);
    B = arrayfun(@(i) circshift(A(:, i), randi(nr)), 1:nc, 'UniformOutput', false);
    B = cell2mat(B);
    

    您必须对其进行基准测试,但使用 arrayfun 可能会加快一点速度。

    【讨论】:

      【解决方案3】:

      我怀疑,您对随机整数矩阵的循环移位操作不会使其变得更加随机,因为这些数字是均匀分布的。

      所以我希望你的问题是使用 randi() 仅用于演示目的。

      【讨论】:

      • 我的实际应用程序比这个复杂得多。当我提出问题时,我喜欢将它们归结为描述问题的简单的最低限度的示例。
      • 我怀疑这与问题无关,绝对不是答案。我也怀疑答案对OP有帮助。我想给-100,但是因为-1是最多的:-1。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-16
      • 1970-01-01
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 2019-12-06
      相关资源
      最近更新 更多