Definir uma matriz evitando o uso de loops for

Nov 27 2020

Tenho uma matriz 3D X de tamanho a x b x c.

Quero criar uma matriz 3D Y no MATLAB da seguinte maneira:

X = rand(10, 10, 5);
[a, b, c] = size(X);

for i = 1 : c
    for j = 1 : a
        for k = 1 : b

            if j<a && k<b
            Y(j, k, i) = X(j+1, k, i) + X(j, k+1, i).^4;
        
            else
            Y(j, k, i) = X(a, b, i) + X(a, b, i).^4;
            end

         end
    end
end

Como posso fazer isso evitando o uso de muitos loops for? Em outras palavras, como posso reescrever o código acima de maneira mais rápida sem usar muitos loops?

Respostas

2 MichaelTr7 Nov 28 2020 at 06:59

Matrizes / matrizes de indexação

Abaixo, adicionei uma parte ao seu script que cria um array Zidêntico ao array Y, usando a indexação que cobre os índices equivalentes e as operações de elemento que são indicadas pelo ponto que .precede a operação. Operações como multiplicação *e divisão /podem ser especificadas elemento a elemento como .*e ./respectivamente. A adição e a subtração agem de acordo com o elemento e não precisam do ponto .. Também adicionei uma instrução if para verificar se os arrays são os mesmos e se os loops for e os métodos de indexação fornecem resultados equivalentes. A indexação usando endrefere-se ao último índice na dimensão correspondente / respectiva.

Snippet:

Y = zeros(a,b,c);
Y(1:end-1,1:end-1,:) = X(2:end,1:end-1,:) + X(1: end-1, 2:end,:).^4;
Y(end,1:end,:) = repmat(X(a,b,:) + X(a,b,:).^4,1,b,1);
Y(1:end,end,:) = repmat(X(a,b,:) + X(a,b,:).^4,a,1,1);

Script Completo: Incluindo Métodos e Verificação

X = rand(10, 10, 5);
[a, b, c] = size(X);

%Initialed for alternative result%
Z = zeros(a,b,c);

%Looping method%
for i = 1 : c
    for j = 1 : a
        for k = 1 : b
            if j < a && k < b
            Y(j, k, i) = X(j+1, k, i) + X(j, k+1, i).^4;
            
            else
            Y(j, k, i) =  X(a, b, i) + X(a, b, i).^4;
            end
         end
    end
end

%Indexing and element-wise method%
Z(1:end-1,1:end-1,:) = X(2:end,1:end-1,:) + X(1: end-1, 2:end,:).^4;
Z(end,1:end,:) = repmat(X(a,b,:) + X(a,b,:).^4,1,b,1);
Z(1:end,end,:) = repmat(X(a,b,:) + X(a,b,:).^4,a,1,1);

%Checking if results match%
if(Z == Y)
   fprintf("Matched result\n"); 
end

Executou usando MATLAB R2019b