【问题标题】:Inserting and shifting rows in a matrix在矩阵中插入和移动行
【发布时间】:2016-05-26 12:45:57
【问题描述】:

根据 Matlab 分析器,以下两个操作在我的代码中占用的时间最多。


我有一个矩阵 A,我始终保持固定大小(N 行和2 列)。我必须删除由两个实数值组成的第一行,将所有行向上移动一个并将[ Inf Inf ] 作为最后一行插入。我不明白为什么下面一行这么慢。

A = [ A(2:end,:) ; [ Inf Inf ] ];

我遇到的第二个问题是当我同时需要在同一个矩阵 A 中插入一行并删除最后一行时。假设我想在idx 行插入row。然后下面的行会大大减慢代码的速度。

A = [ A(1:(idx - 1),:) ; row ; A(idx:(end - 1),:) ];

知道为什么这两个相似的操作很慢吗?我确实知道慢是相对的,但可能是这样的操作是不好的做法,我可以改进它们。

【问题讨论】:

  • N的大小是多少?需要多少时间?
  • 这是否更快:A(1:end-1) = A(2:end); A(end,:) = Inf?即在原地进行操作?
  • 您也可以尝试circshift 并覆盖最后一行:A = circshift(A, -1, 1); A(end,:) = Inf; 从一个非常快速的测试来看,它似乎比当前和@Dan 的 50k 行方法快约 2 倍。对于第二部分,我不明白为什么你不能只覆盖该行:A(idx,:) = row;
  • N 是任意的,但不是很大,比如说 10。不过我必须调用它 10^6 次。从一个非常简短的测试来看,@Dan 的方法似乎并不快。我将尝试@excaza 现在为第一部分提出的方法。对于第二部分,我无法覆盖该行,我需要通过将行 idx 或以上的所有行向上移动一个并丢弃最后一行来腾出空间。
  • @ritz 或许可以解释为什么你需要这样做,或许有办法完全避免这种情况?

标签: matlab matrix insert


【解决方案1】:

这两个操作都会生成一个大小为 nx2 的新矩阵,并将旧矩阵的内容复制到新矩阵中。在这两种情况下都完成了 O(n) 操作。这并不理想,尤其是在一个紧密的循环中。

如果您对数据的每一行都执行此操作,则为 O(n^2) 操作。即使对于像 10k 或 100k 这样的小 ns,您也会开始遇到问题。

【讨论】:

    【解决方案2】:

    在热身之后,对于您的第一个问题(在 2016a 上),大多数情况下这种速度会快 1.5-2 倍。

    N = 10;
    M = rot90(blkdiag(rot90(eye(N-1)),inf),-1);
    ind = 10000;
    t = zeros(ind,1);
    indarr = 1:ind;
    
    for i = indarr
        A = rand(N,2);
        B = rand(N,2);
    
        tic,A = [ A(2:end,:) ; [ Inf Inf ] ];t1=toc;
        tic,B = M*B;t2 = toc;
    
        t(i) = t1-t2;
    end
    
    plot(t)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-03
      • 2016-01-26
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      相关资源
      最近更新 更多