Применение функции к каждой матрице в массиве матриц (MATLAB) - PullRequest
0 голосов
/ 19 января 2020

В MATLAB у меня есть массив (512x512x512) матриц (3x3). То есть у меня есть массив размера (512x512x512x3x3) с матрицами 3x3 в качестве элементов. Я хотел бы взять матрицу, обратную в каждом элементе массива. Есть ли способ, которым я мог бы go сделать это без перебора всех трех измерений? Например, метод "грубой силы" для выполнения этого будет следующим псевдокодом:

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

Массив CoB выше - это массив матриц изменения базиса (где столбцы являются собственными векторами). Мне нужны инверсии этих матриц, которые будут использоваться вместе с другой диагональной матрицей для получения массива матриц в их исходном базисе с использованием M=SDS^(-1). S и S^(-1) представлены CoB и CoB_inv соответственно. Есть ли способ выполнить вышеупомянутое быстрее или эффективнее в MATLAB?

Ответы [ 2 ]

1 голос
/ 20 января 2020

РЕДАКТИРОВАТЬ: Мой ответ ниже применяется в целом, но вы утверждаете, что ваши матрицы являются коллекциями собственных векторов. Это подразумевает, что матрицы ортогональны и, следовательно, транспонирование является обратным. В этом случае вы можете просто использовать permute для транспонирования матриц и получения инверсии всех матриц, то есть что-то вроде

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

Исходный ответ: Если у вас есть Графический процессор в вашем компьютере вы можете использовать pagefun. Основное использование c состоит в том, что сначала два измерения задают матрицу, а затем она проходит по остальным измерениям

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

Таким образом, вам придется использовать permute для переключения размеры, располагающие матрицу 3x3 в первых двух измерениях, а не в двух последних, используйте pagefun, а затем переключитесь обратно.

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

Отказ от ответственности: у меня в моем ноутбуке нет графического процессора, из которого я сейчас нахожусь работает, поэтому я не проверял выше.

0 голосов
/ 19 января 2020

Использование ; в конце строк и отсутствие печати результатов значительно ускорит код. Кроме этого, я не вижу много возможностей для улучшения. Векторизация будет полагаться на одну и ту же операцию, применяемую к нескольким элементам, но инвертирование матрицы не может быть выполнено с одинаковыми шагами для всех матриц. Если вы, например, используете гаусс, вам иногда приходится менять строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...