在Octave / MATLAB中相对于矢量值移动矩阵中的行

时间:2016-08-20 16:59:11

标签: matlab matrix octave

我可以相对于向量A中的值移动矩阵v中的行吗?

例如Av指定如下:

A =
    1   0   0
    1   0   0
    1   0   0

v =
    0   1   2

在这种情况下,我想从A:

获得这个矩阵
A = 
    1   0   0
    0   1   0
    0   0   1

i中的每A行已被i移位v

我可以使用本机功能执行此操作吗? 或者我应该自己写呢?

我已尝试circshift功能,但我无法弄清楚如何单独移动行。

4 个答案:

答案 0 :(得分:4)

函数circshift无法正常工作,即使您使用向量作为移位量,也可以将其解释为每个维度的移位量。虽然可以循环遍历矩阵的行,但效率不高。

如果计算每一行的索引效率更高,实际上非常简单:

## First, prepare all your input
octave> A = randi (9, 4, 6)
A =

   8   3   2   7   4   5
   4   4   7   3   9   1
   1   6   3   9   2   3
   7   4   1   9   5   5

octave> v = [0 2 0 1];
octave> sz = size (A);


## Compute how much shift per row, the column index (this will not work in Matlab)
octave> c_idx = mod ((0:(sz(2) -1)) .- v(:), sz(2)) +1
c_idx =

   1   2   3   4   5   6
   5   6   1   2   3   4
   1   2   3   4   5   6
   6   1   2   3   4   5

## Convert it to linear index    
octave> idx = sub2ind (sz, repmat ((1:sz(1))(:), 1, sz(2)) , c_idx);

## All you need is to index
octave> A = A(idx)
A =

   8   3   2   7   4   5
   9   1   4   4   7   3
   1   6   3   9   2   3
   5   7   4   1   9   5

答案 1 :(得分:3)

% A and v as above. These could be function input arguments
A = [1 0 0; 1 0 0; 1 0 0]; 
v = [0 1 2];                                          
assert (all (size (v) == [1, size(A, 1)]), ...
        'v needs to be a horizontal vector with as many elements as rows of A');

% Calculate shifted indices
[r, c] = size (A);
tmp = mod (repmat (0 : c-1, r, 1) - repmat (v.', 1, c), c) + 1;
Out = A(sub2ind ([r, c], repmat ([1 : r].', 1, c), tmp))  

  Out =

       1     0     0
       0     1     0
       0     0     1

如果性能有问题,您可以将repmat替换为更有效的等效bsxfun调用(为了简单起见,我在这里使用repmat来演示该方法)。

答案 2 :(得分:1)

关注性能,这是使用bsxfun/broadcasting -

的一种方法
[m,n] = size(A);
idx0 = mod(bsxfun(@plus,n-v(:),1:n)-1,n);
out = A(bsxfun(@plus,(idx0*m),(1:m)'))

示例运行 -

A =
     1     7     5     7     7
     4     8     5     7     6
     4     2     6     3     2
v =
     3     1     2
out =
     5     7     7     1     7
     6     4     8     5     7
     3     2     4     2     6

使用automatic broadcasting的等效Octave版本看起来像这样 -

[m,n] = size(A);
idx0 = mod( ((n-v(:)) + (1:n)) -1 ,n);
out = A((idx0*m)+(1:m)')

答案 3 :(得分:0)

在循环中使用circshift移动向量,迭代行索引。