Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract diagonal element from each frontal slice of tensor

I have a p-by-p-by-n tensor. I want to extract diagonal element for each p-by-p slice. Are there anyone know how to do this without looping?

Thank you.

like image 966
aaa Avatar asked Dec 04 '22 04:12

aaa


1 Answers

Behold the ever mighty and ever powerful 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))

Sample run with 4 x 4 x 3 sized input array -

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

Benchmarking

Here's few runtime tests comparing this bsxfun based approach against repmat + eye based approach for big datasizes -

***** 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.
like image 148
Divakar Avatar answered Jan 08 '23 02:01

Divakar