Multiplicação De Matrize - Multiplicação de matrizes - Como multiplicar duas matrizes, exemplos
Multiplicação de matrizes - Como multiplicar duas matrizes, exemplos

O que realmente acontece quando você multiplica matrizes

Multiplicação de matrizes é uma operação linear onde cada elemento do resultado vem do produto interno entre uma linha da primeira matriz e uma coluna da segunda. A regra básica é simples de memorizar, mas o que as pessoas subestimam é como ela escala quando as dimensões crescem. Se você já tentou fazer isso manualmente com matrizes 4x4 ou maiores, sabe que o erro mais comum não é conceitual, é de atenção. Um sinal trocado, uma linha que você cruzou com a coluna errada, e tudo que veio depois fica inutilizável. A condição necessária para que a multiplicação exista é que o número de colunas da matriz da esquerda seja igual ao número de linhas da matriz da direita. O resultado terá as linhas da primeira e as colunas da segunda. Isso é regra fixa. Não tem margem para negociação. O que muita gente não entende no começo é que a ordem importa drasticamente. A *multiplicação de matrizes* não é comutativa. A *AB* pode existir enquanto a *BA* nem sequer é definida, ou pode ter dimensões diferentes, ou simplesmente dar um resultado completamente distinto. Isso causa confusão até em quem já usa álgebra linear no dia a dia.

Passo a passo da multiplicação de matrize na prática

Vou explicar pelo meio do processo, porque começar pela definição formal geralmente confunde mais do que ajuda. Pegue a matriz A de dimensão m x n e a matriz B de dimensão n x p. O elemento na posição (i, j) da matriz resultado C é calculado somando os produtos ai1·b1j + ai2·b2j + ... + ain·bnj. Em outras palavras, você pega a linha i de A, a coluna j de B, multiplica termo a termo e soma tudo. Pra facilitar visualmente, considere esta situação concreta. Matriz A é 2x3:

A = [[1, 3, 2], [4, 0, 5]] Matriz B é 3x2:

B = [[2, 1], [3, 4], [0, 2]] O elemento C11 vem de (1·2) + (3·3) + (2·0) = 2 + 9 + 0 = 11.

O elemento C12 vem de (1·1) + (3·4) + (2·2) = 1 + 12 + 4 = 17. O elemento C21 vem de (4·2) + (0·3) + (5·0) = 8 + 0 + 0 = 8.

O elemento C22 vem de (4·1) + (0·4) + (5·2) = 4 + 0 + 10 = 14. Resultado final: C = [[11, 17], [8, 14]].

👉 Clique no botão abaixo para saber mais sobre o assunto!

Repetir esse procedimento manualmente para cada posição da matriz resultante é mecanicamente trivial. O problema aparece quando as matrizes saem do tamanho didático. Eu trabalhei numa integração de simulação estrutural onde precisávamos multiplicar matrizes de rigidez 120x120 contra vetores de deslocamento em um loop que rodava milhares de vezes por segundo. O código parecia correto, mas os resultados não convergiam. Descobriu-se que a matriz de rigidez tinha sido construída em formato linha-major e o módulo de multiplicação esperava coluna-major. O produto era computado, mas os dados estavam interpretados de forma invertida, gerando valores numericamente plausíveis mas fisicamente sem sentido. A correção foi apenas uma transposição antes da chamada da função de multiplicação, mas levar duas semanas pra chegar aí não foi por falta de conhecimento teórico, foi por falta de experiência prática com layouts de memória.

Detalhes que livros não destacam

A propriedade associativa vale: *(AB)C = A(BC)*. A distributiva também: *A(B + C) = AB + AC*. Mas a propriedade que mais causa dor de cabeça é a não-comutatividade combinada com a sensibilidade numérica. Duas matrizes que parecem idênticas dentro da precisão da máquina podem gerar produtos radicalmente diferentes se tiverem condition numbers altos. Matrizes mal condicionadas são o tipo de cenário onde uma multiplicação aparentemente inocente destrói a precisão dos seus dados. Outro ponto cego: o custo computacional. Multiplicação ingênua de duas matrizes n x n tem complexidade O(n³). Isso significa que dobrar o tamanho da matriz aumenta o trabalho em oito vezes. Matrizes 1000x1000 já exigem consideração séria sobre qual algoritmo usar. Algoritmos como Strassen reduzem a complexidade teórica para cerca de O(n^2.807), mas na prática só valem a pena para matrizes muito grandes porque a constante multiplicativa é alta. Para a maioria das aplicações reais, bibliotecas como BLAS (Basic Linear Algebra Subprograms) usam estratégias de *tiling* que exploram o cache do processador e entregam performance muito superior à implementação ingênua, mesmo sem redução assintótica.

A multiplicação de matrizes também não preserva propriedades óbvias. O produto de duas matrizes simétricas não é necessariamente simétrico. O produto de duas matrizes invertíveis é invertível, sim, mas a inversa do produto é a multiplicação das inversas na ordem invertida: *(AB)^(-1) = B^(-1)A^(-1)*. Esquecer essa inversão de ordem é um erro frequente em implementações que manipulam transformações geométricas encadeadas.

Quando a multiplicação de matrizes não é a resposta certa

Existem cenários onde você pensa que precisa de multiplicação de matrizes mas na verdade está usando a ferramenta errada. Se as suas matrizes são esparsas — a maior parte dos elementos é zero — a representação densa tradicional desperdiça memória e tempo de cálculo. Matrizes esparsas de sistemas de elementos finitos, por exemplo, podem ter mais de 99% de zeros. Multiplicar nesse formato denso é ineficiente. O workaround adequado é usar estruturas esparsas (CSR, CSC, COO) e bibliotecas especializadas como SuiteSparse ou spmatrix. A economia de memória e processamento pode ser da ordem de dezenas de vezes. Outro caso onde a abordagem padrão falha é quando você precisa multiplicar matrizes que não cabem na memória principal. Isso acontece rotineiramente em processamento de dados geoespaciais e simulações climáticas. A solução não é "usar matrizes menores", é particionar o problema: dividir as matrizes em blocos que cabem no cache ou na RAM, multiplicar bloco a bloco, e acumular os resultados parciais. Esse é exatamente o princípio por trás de bibliotecas como CuBLAS para GPU e dos kernels otimizados do OpenBLAS.

Se o seu objetivo é somente aplicar transformações lineares sucessivas em vetores, às vezes fazer a multiplicação explícita das matrizes primeiro e depois aplicar ao vetor é mais caro do que aplicar cada transformação diretamente ao vetor na sequência. A diferença é significativa quando você tem dezenas de transformações. Multiplicar todas as matrizes entre si antes gera uma matriz densa custosa; aplicar uma por vez em O(n²) por etapa evita esse custo intermediário.

Dica prática de verificação

Depois de calcular um produto, faça uma verificação rápida com traço e propriedades. O traço do produto AB não é igual ao traço de BA em geral, mas se A e B são quadradas do mesmo tamanho, *tr(AB) = tr(BA)*. Isso serve como cheque rápido. Outro teste útil: multiplique por uma matriz identidade e confirme que o resultado não mudou. Se mudou, houve erro de indexação ou de layout de memória. Testes unitários automáticos com matrizes conhecidas — como multiplicar uma matriz por sua inversa e verificar se o resultado é a identidade dentro de uma tolerância razoável — economizam horas de depuração posterior.