Matlab 从张量的每个正面切片中提取对角线元素

Matlab 从张量的每个正面切片中提取对角线元素,matlab,matrix,vectorization,Matlab,Matrix,Vectorization,我有一个p-by-p-by-n张量。我想为每个p-by-p切片提取对角线元素。有人知道如何做到这一点而不循环吗 谢谢。我的一个建议是创建一个pxp逻辑标识矩阵,在第三维中复制该n次,然后使用该矩阵访问张量。类似这样,假设你的张量存储在A: ind = repmat(logical(eye(p)), [1 1 n]); out = A(ind); 示例用法: 你会注意到,我们抓取第一个切片的对角线,然后是第二个切片的对角线,等等,直到最后一个切片。这些值都连接到一个向量中。看永远强大的可以非常有

我有一个p-by-p-by-n张量。我想为每个p-by-p切片提取对角线元素。有人知道如何做到这一点而不循环吗


谢谢。

我的一个建议是创建一个
pxp
逻辑标识矩阵,在第三维中复制该
n次
,然后使用该矩阵访问张量。类似这样,假设你的张量存储在
A

ind = repmat(logical(eye(p)), [1 1 n]);
out = A(ind);
示例用法:
你会注意到,我们抓取第一个切片的对角线,然后是第二个切片的对角线,等等,直到最后一个切片。这些值都连接到一个向量中。

永远强大的可以非常有效地使用-

使用
4x4x3
大小的输入阵列运行示例-

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.
只是阅读答案并试图理解为什么他再次比我把两者混合起来的代码快大约10倍,最终得到了更快的代码:

A=reshape(A,[],n);
diags2 = A(1:p+1:p*p,:);

对于500x500x500张量,使用Matlab2013a,Divakar的解得到0.008s,我的解得到0.005s。可能普通索引是打败
bsxfun

的唯一方法,为什么要在不循环的情况下执行它?
p
n
会有多大?我在这里也用了我的
“宠物”
)好宠物!很好,很听话+1.直接
索引
而不是
屏蔽
。可爱:)@SanthanSalai是的!更少的内存需求,仍然是矢量化的,只是其中的一种特殊情况。任何看到这种问题的人显然都会想到
屏蔽
,但你采取了不同的方法;)@SanthanSalai我没有选择不同的路线,我选择了我本能的默认路线,bsxfun路线!;)啊,包括重塑索引,很好。那不是有点昂贵吗?重塑基本上不是零成本吗?我从未见过它添加任何实质性的运行时。好吧,与
permute
之类的东西相比,重塑的成本并不高,但肯定不是免费的。你在计时中包括重塑吗?是的,它包括在我的计时中。
重塑
完全不涉及内存中的数据。@迪瓦卡:昨天在聊天中与安德·比古里进行了类似的讨论。现在意识到,即使你不知道重塑的速度,我想我应该
***** 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,:);