page-wise matrix determinant or eigenvalues
42 次查看(过去 30 天)
显示 更早的评论
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!
0 个评论
采纳的回答
Heiko Weichelt
2023-3-16
R2023a, released March 15th 2023, ships PAGEEIG as new function in the page* family:
Try it out and let us know if it meets your requirements. We're happy to hear about more use-cases and workflows for further page* functions.
2 个评论
David Ober
2023-3-28
I use determinant to solve items in the decomposition of the projection matrix for over 100k 3x3 matricies. So I wrote my own det33 (for the 3x3 that is vectorized) using the Rule of Sarrus. My custom version is faster (0.5X the time) than the following one liner for 100k matricies.
fvdet = prod(pageeig(mmM,'vector'),1);
a Page-wise "diag" would be very helpful to check the signs of the decomposition. Thankfully, since the decomposition is a 3x3, I can write my own vectorized "diag33".
更多回答(3 个)
Henry Brinkerhoff
2023-3-10
2 个评论
John D'Errico
2023-3-10
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
John D'Errico
2023-3-10
@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.
0 个评论
lala
2023-10-24
编辑:Walter Roberson
2023-10-24
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
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!