Best way to calculate the determinants of a series of matrices?

28 ビュー (過去 30 日間)
I've got a series of time-dependent matrices which I'd like to calculate the determinants of. These matrices are stored as a three-dimensional array, where the first dimension indicates the period; in other words, the matrix at time t is given by
Gt = squeeze(G(t, :, :))
I'd now like a snippet of code which, being run, will ensure that
Delta(t) = det(squeeze(G(t, :, :)))
holds for all t. Of course I could do this with a loop, but I feel that there must be a more succinct, vectorized way of doing it. Sadly, MATLAB's det function itself is of no help. Is there something else I could use, or will I have to bite the proverbial bullet and use a loop after all?

採用された回答

Bruno Luong
Bruno Luong 2019 年 9 月 5 日
編集済み: Bruno Luong 2019 年 9 月 5 日
I reverse the order and put the page in third dimension (avoid to use squeeze).
For small size, you can save CPU time by 4 fold using MultipleQR available on FEX
A=rand(3,3,1e5);
tic
n = size(A,1);
% FEX https://fr.mathworks.com/matlabcentral/fileexchange/68976-multipleqr
[Q,R] = MultipleQR(A);
R = reshape(R,n*n,[]);
d1 = (-1)^n * prod(R(1:n+1:end,:),1);
toc % Elapsed time is 0.087167 seconds.
tic
d2 = arrayfun(@(k) det(A(:,:,k)), 1:size(A,3));
toc % Elapsed time is 0.376470 seconds.
% Check correctness
norm(d1-d2)/norm(d2) % 4.2026e-16
MultipleQR will be less efficient for large n.
  1 件のコメント
Christian Schröder
Christian Schröder 2019 年 9 月 5 日
Excellent! Thank you!

サインインしてコメントする。

その他の回答 (3 件)

Alex Mcaulley
Alex Mcaulley 2019 年 9 月 5 日
delta = arrayfun(@(t) det(squeeze(G(t,:,:))),1:size(G,1));
  1 件のコメント
Christian Schröder
Christian Schröder 2019 年 9 月 5 日
Thanks! This is exactly what I need.

サインインしてコメントする。


Fabio Freschi
Fabio Freschi 2019 年 9 月 5 日
Not sure if it you can speedup your code, but a single line code to do the job is
Delta = arrayfun(@(i)det(squeeze(G(i,:,:))),1:size(G,1));
  1 件のコメント
Christian Schröder
Christian Schröder 2019 年 9 月 5 日
Thank you! I wasn't aware of arrayfun --- this is just what I need.

サインインしてコメントする。


Jos (10584)
Jos (10584) 2019 年 9 月 5 日
Elaborating on the answers using arrayfun, you can avoid the multiple squeeze operations by permuting the dimension order first:
G = permute(G,[2 3 1]) ; % last dimension is running fastest
D = arrayfun(@(k) det(G(:,:,k)), 1:size(G,3)) % per Fabio and Alex
  1 件のコメント
Christian Schröder
Christian Schröder 2019 年 9 月 5 日
Good to know, I hadn't previously been aware that squeeze() could be avoided if the singleton dimension was in fact last --- or that you could use permute to rearrange the dimensions of an array. Still very much a MATLAB newbie, so thanks to you and everyone who pointed this out!

サインインしてコメントする。

製品


リリース

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by