0
votes

In MATLAB, I have an array (512x512x512) of matrices (3x3). That is, I have an array of size (512x512x512x3x3) with 3x3 matrices as elements. I would like to take the matrix inverse at each element of the array. Is there a way I could go about doing this without iterating through the three dimensions? For example, the "brute-force" method of doing this would be the following pseudo-code:

CoB_inv_size = size(CoB);
CoB_inv = zeros(CoB_inv_size); % array of size (512x512x512x3x3)

for i = 1:CoB_inv_size(1) % 512
    for j = 1:CoB_inv_size(2) % 512
        for k = 1:CoB_inv_size(3) % 512

            CoB_inv(i,j,k,:,:) = inv(CoB(i,j,k,:,:));

        end
    end
end

The array CoB above is an array of change-of-basis matrices (where the columns are eigenvectors). I need the inverses of these matrices which will be utilized along with another diagonal matrix to obtain an array of matrices in their original basis using M=SDS^(-1). S and S^(-1) are represented by CoB and CoB_inv respectively. Is there a way to perform the above faster or more efficiently in MATLAB?

2
No, (short answer). The arrayfun function applies a function to every element of a matrix/array. Although, you could use the workaround and create an array of cells that stores your 3x3 matrices and then use the cellfun-function with cellfun(@inv,YourCellArray)max

2 Answers

1
votes

EDIT: My below answer applies in general, but you state that your matrices are collections of eigenvectors. This implies that the matrices are orthogonal and thus the transpose is the inverse. In this case, you can just use permute to transpose the matrices and obtain the inverse of all of the matrices, i.e. something like

CoBinv = permute(CoB,[1,2,3,5,4]);

Original answer: If you have a GPU in your computer you can use pagefun. The basic usage is that the first two dimensions specify the matrix and then it loops over the remaining dimensions,

A = rand(3,3,512,512,512,'gpuArray');
B = pagefun(@inv,A);
s = size(B) % 3 x 3 x 512 x 512 x 512

You will thus have to use permute to switch the dimensions arranging the 3x3 matrix in the first two dimensions rather than the two last, use pagefun and then switch back.

CoBtmp = permute(CoB,[4,5,1,2,3]);
CoBinv = pagefun(@inv,CoBtmp);
CoBinv = permute(CoBinv,[3,4,5,1,2]);

Disclaimer: I do not have GPU in my laptop from where I am currently working, so I have not tested the above.

0
votes

Using ; at the end of the lines and not printing the results will significantly speed up the code. Other than that, I don't see much room for improvement. Vectorization would rely on the same operation being applied to multiple elements, but inverting a matrix can't be done with exactly the same steps for all matrices. If you for example use gauss, you sometimes have to swap rows.