从张量的每个正面切片中提取对角线元素
Extract diagonal element from each frontal slice of tensor
我有一个 p×p×n 张量。我想为每个 p-by-p 切片提取对角线元素。有没有人知道如何在不循环的情况下做到这一点?
谢谢。
我的一个建议是创建一个 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
您会注意到我们获取了第一个切片的对角线,然后是第二个切片的对角线,依此类推,直到最后一个切片。这些值都连接成一个向量。
Behold
永远的威武永远的强大bsxfun
for vectorizing MATLAB problems
to do this task very efficiently using MATLAB's linear indexing
-
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
的方法与 的大数据量进行比较 -
***** 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.
只是阅读 answer and trying to understand why he again is roughly 10 times faster than 我把两者混合在一起的代码,最后得到了更快的代码:
A=reshape(A,[],n);
diags2 = A(1:p+1:p*p,:);
对于 500x500x500 张量,我使用 Matlab 2013a 得到 0.008s 的 Divakar 解决方案和 0.005s 的解决方案。可能普通索引是击败 bsxfun
.
的唯一方法
我有一个 p×p×n 张量。我想为每个 p-by-p 切片提取对角线元素。有没有人知道如何在不循环的情况下做到这一点?
谢谢。
我的一个建议是创建一个 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
您会注意到我们获取了第一个切片的对角线,然后是第二个切片的对角线,依此类推,直到最后一个切片。这些值都连接成一个向量。
Behold
永远的威武永远的强大bsxfun
for vectorizing MATLAB problems
to do this task very efficiently using MATLAB's linear indexing
-
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
的方法与
***** 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.
只是阅读
A=reshape(A,[],n);
diags2 = A(1:p+1:p*p,:);
对于 500x500x500 张量,我使用 Matlab 2013a 得到 0.008s 的 Divakar 解决方案和 0.005s 的解决方案。可能普通索引是击败 bsxfun
.