【发布时间】:2015-02-09 03:05:24
【问题描述】:
我有一个 p×p×n 张量。我想为每个 p-by-p 切片提取对角线元素。有没有人知道如何在不循环的情况下做到这一点?
谢谢。
【问题讨论】:
-
为什么要不循环执行?
p和n会有多大?
标签: matlab matrix vectorization
我有一个 p×p×n 张量。我想为每个 p-by-p 切片提取对角线元素。有没有人知道如何在不循环的情况下做到这一点?
谢谢。
【问题讨论】:
p 和 n 会有多大?
标签: matlab matrix vectorization
Behold 强大而强大的bsxfun 让vectorizing MATLAB problems 使用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 的方法和 repmat + eye based approach 的大数据大小 -
***** 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.
【讨论】:
indexing 而不是masking。可爱的:)
masking,但你选择了不同的路线;)
我的一个建议是创建一个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
您会注意到我们抓取了第一个切片的对角线,然后是第二个切片的对角线,依此类推,直到最后一个切片。这些值都连接到一个向量中。
【讨论】:
"pet"! ;)
【讨论】:
reshape 会不会有点昂贵的事情?
permute 之类的东西相比,reshape 的成本并不高,但肯定不是免费的。您是否在时间安排中包括了重塑?
reshape 根本不会触及内存中的数据。