我可以相对于向量A
中的值移动矩阵v
中的行吗?
例如A
和v
指定如下:
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
功能,但我无法弄清楚如何单独移动行。
答案 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
移动向量,迭代行索引。