Multiplicação de Polinómios
Depois de um breve hiato, volto a este Blol colocar pensamentos inúteis. E hoje pensei na multiplicação de polinómios - em particular, polinómios com coeficientes mod 2, i.e. [latex]\mathbb{F}_2[x][/latex]. Como é que representamos estes polinómios?
Dado que cada coeficiente apenas pode ser 0 ou 1, podemos utilizar apenas um bit para estes. Assim, se tivermos um polinómio [latex]x^3 + x + 1[/latex], representamos o mesmo por 0b1011 ou 0x0B.
A adição de polinómios é trivial - consiste unicamente em aplicar a operação XOR, dado que XOR é adição mod 2. A multiplicação pode ser efectuada como efectuamos multiplicações de inteiros, excepto que ignoramos todos os transportes (carries). Podemos então implementar uma multiplicação de polinómios como:
u32 polymul(u32 a, u32 b) { u32 z = 0; while(b != 0) { if(b&1 != 0) z ^= a; b >>= 1; a <<= 1; } return z; }
Isto, no entanto, contém branching e operações condicionais. Se usarmos C++, podemos criar uma função sem qualquer loop que nos permita efectuar a mesma operação:
template<u32 N> inline u32 mul(u32 a, u32 b) { return (a & -(b&1)) ^ mul<N-1>(a<<1, b>>1); } template<> inline u32 mul<0>(u32 a, u32 b) { return 0; }
O parâmetro N, utilizado na instanciação da função, corresponde ao grau máximo dos polinómios de entrada. No caso de um inteiro de 32 bits, a soma dos graus de a e b não poderá exceder 32, de forma a evitar overflows.
Ganda PINTA !!!!! Adorei este post.
[...] a multiplicação de polinómios em . O algoritmo considerado no post anterior é conhecido há milénios e tem uma complexidade quadrática, i.e., operações para multiplicar [...]