我有一个p-by-p-by-n张量。我想为每个p-by-p切片提取对角元素。有没有人知道怎么做而不循环?
谢谢。
答案 0 :(得分:8)
Behold
bsxfun
vectorizing MATLAB problems
MATLAB's linear indexing
repmat + eye
based approach 3>} {{3}} <{3}} } -
diags = A(bsxfun(@plus,[1:p+1:p*p]',[0:n-1]*p*p))
使用4 x 4 x 3
大小的输入数组运行示例 -
A(:,:,1) =
0.7094 0.6551 0.9597 0.7513
0.7547 0.1626 0.3404 0.2551
0.2760 0.1190 0.5853 0.5060
0.6797 0.4984 0.2238 0.6991
A(:,:,2) =
0.8909 0.1493 0.8143 0.1966
0.9593 0.2575 0.2435 0.2511
0.5472 0.8407 0.9293 0.6160
0.1386 0.2543 0.3500 0.4733
A(:,:,3) =
0.3517 0.9172 0.3804 0.5308
0.8308 0.2858 0.5678 0.7792
0.5853 0.7572 0.0759 0.9340
0.5497 0.7537 0.0540 0.1299
diags =
0.7094 0.8909 0.3517
0.1626 0.2575 0.2858
0.5853 0.9293 0.0759
0.6991 0.4733 0.1299
<强>基准强>
这里有一些运行时测试,将这种基于bsxfun
的方法与大数据量的{{3}}进行比较 -
***** Datasize: 500 x 500 x 500 *****
----------------------- With BSXFUN
Elapsed time is 0.008383 seconds.
----------------------- With REPMAT + EYE
Elapsed time is 0.163341 seconds.
***** Datasize: 800 x 800 x 500 *****
----------------------- With BSXFUN
Elapsed time is 0.012977 seconds.
----------------------- With REPMAT + EYE
Elapsed time is 0.402111 seconds.
***** Datasize: 1000 x 1000 x 500 *****
----------------------- With BSXFUN
Elapsed time is 0.017058 seconds.
----------------------- With REPMAT + EYE
Elapsed time is 0.690199 seconds.
答案 1 :(得分:6)
我的一个建议是创建一个p x p
逻辑单位矩阵,在第三维中复制此n
次,然后使用此矩阵访问张量。这样的事情,假设你的张量存储在A
:
ind = repmat(logical(eye(p)), [1 1 n]);
out = A(ind);
>> p = 5; n = 3;
>> A = reshape(1:75, p, p, n)
A(:,:,1) =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
A(:,:,2) =
26 31 36 41 46
27 32 37 42 47
28 33 38 43 48
29 34 39 44 49
30 35 40 45 50
A(:,:,3) =
51 56 61 66 71
52 57 62 67 72
53 58 63 68 73
54 59 64 69 74
55 60 65 70 75
>> ind = repmat(logical(eye(p)), [1 1 n]);
>> out = A(ind)
out =
1
7
13
19
25
26
32
38
44
50
51
57
63
69
75
你会注意到我们抓住第一个切片的对角线,然后抓住第二个切片的对角线等,直到最后一个切片。这些值都连接成一个向量。
答案 2 :(得分:2)