page-wise matrix determinant or eigenvalues
Show older comments
I'm really loving the vectorized improvement in a lot of my code from incorporating Matlab's new page-wise matrix operations, since I'm regularly running code where I need to do, for example, inverses of each of the M*N number of 3x3 matrices in a 3x3xMxN array.
I'd really like to also be able to take a determinant of each matrix in this same fashion, or at least get the eigenvalues so I can quickly compute the determinant as their product. pagesvd.m has been implemented, and it seems straightforward to similarly implement a pageeigs.m or pagedet.m in a vectorized fashion, but unfortunately it doesn't seem like these functions exist.
Has anybody else encountered this issue and found a workaround for a quick, vectorized way (without "for" loops) to implement a page-wise determinant?
Thanks!
Accepted Answer
More Answers (3)
Henry Brinkerhoff
on 10 Mar 2023
0 votes
2 Comments
Um, close. In fact, the product of the singular values will be the absolute value of the determinant. And that will apply regardless of whether your matrix is positive definite. For example:
A = randn(4)
A is clearly never going to be positive definite.
det(A)
prod(svd(A))
But, as I said, the product of the singular values is the same, to within a factor of -1
Henry Brinkerhoff
on 10 Mar 2023
@Henry Brinkerhoff seems to have found a semi-viable solution, in the form of pagesvd. It will be valid, within a factor of -1. However, that are other methods around that would work as well, and maybe better.
For example, the determinant can also be gained from the product of the diagonal elements of the U factor in an LU decomposition, times the number of column swaps involved in the permutation matrix P. For example:
A = rand(4);
[L,U,P] = lu(A)
[det(A),prod(diag(U))]
And see that we can convert the matrix P into an identity matrix by swapping one pair of the columns. So there is one column swap, and therefore one factor of -1. If you don't care about the sign of the determinant, you can ignore the permutation matrix P.
But a nice thing is, if we could convert the matrix A into a block diagonal matrix., then we could compute the determinants of MANY pages quickly.
For example,
A = rand(5,5,1000);
C = mat2cell(A,5,5,ones(1,1000));
[L,U] = lu(blkdiag(C{:}));
D = prod(reshape(diag(U),5,1000),1)
det(A(:,:,1))
det(A(:,:,2))
Again, to within an arbitrary factor of -1, the two are the same. Unfortunately, there is no paged version of the LU. The only thing missing is the fact that we need the matrix to be a sparse block diagonal matrix. Then it would be very efficient. We can fix that too.
tic
C = sparse(reshape(A,5,5*1000));
S = mat2cell(C,5,repmat(5,1,1000));
[L,U] = lu(blkdiag(S{:}));D1 = prod(reshape(diag(U),5,1000),1);
toc
tic,D2 = squeeze(prod(pagesvd(A),1));toc
Surprisingly, PAGESVD is still faster than the sparse block diagonal LU. I guess we need a paged LU to be competitive.
lala
on 24 Oct 2023
Edited: Walter Roberson
on 24 Oct 2023
det with for-loop is fatest.
format long g
[tmr,tf] = testpagemdet(100000)
function [tmr,tf] = testpagemdet(times)
A = rand(3,3,8);
tmr = zeros(1,3);
for i = 1:times
t = tic;
d1 = pagemdet(A);
tmr(1) = toc(t);
t = tic;
d2 = det33(A);
tmr(2) = toc(t);
t = tic;
d3 = real(prod(pageeig(A,'vector'),1));
tmr(3) = toc(t);
end
tol = 1e-6;
tf = all(abs(d1-d2)<tol & abs(d1-d3)<tol);
end
function d = pagemdet(A)
sz = size(A);
d = zeros([1,1,sz(3:end)]);
nm = prod(sz(3:end));
for i = 1:nm
d(i) = det(A(:,:,i));
end
end
function d = det33(A)
d = A(1,1,:).*A(2,2,:).*A(3,3,:)...
+A(1,2,:).*A(2,3,:).*A(3,1,:)...
+A(1,3,:).*A(2,1,:).*A(3,2,:)...
-A(1,3,:).*A(2,2,:).*A(3,1,:)...
-A(1,2,:).*A(2,1,:).*A(3,3,:)...
-A(1,1,:).*A(2,3,:).*A(3,2,:);
end
Categories
Find more on Linear Algebra in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!