page-wise matrix determinant or eigenvalues
42 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Henry Brinkerhoff
el 10 de Mzo. de 2023
Editada: Walter Roberson
el 24 de Oct. de 2023
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 comentarios
Respuesta aceptada
Heiko Weichelt
el 16 de Mzo. de 2023
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 comentarios
David Ober
el 28 de Mzo. de 2023
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".
Más respuestas (3)
Henry Brinkerhoff
el 10 de Mzo. de 2023
2 comentarios
John D'Errico
el 10 de Mzo. de 2023
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
el 10 de Mzo. de 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.
0 comentarios
lala
el 24 de Oct. de 2023
Editada: Walter Roberson
el 24 de Oct. de 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
0 comentarios
Ver también
Categorías
Más información sobre Linear Algebra en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!