Desejo implementar o seguinte expressão em Python: onde x e y são matrizes numpy de tamanho n , e k é uma matriz numpy de tamanho n × n . O tamanho n pode ser de até 10000, e a função faz parte de um loop interno que será avaliado muitas vezes, portanto a velocidade é importante.
Idealmente, eu gostaria de evitar um loop for completamente, embora eu ache que não é o fim do mundo, se houver um. O problema é que estou tendo problemas para ver como fazer isso sem ter alguns loops aninhados, e isso provavelmente tornará o processo bastante lento.
Alguém pode ver como expressar a equação acima usando numpy de maneira eficiente e, de preferência, também legível? De maneira mais geral, qual é a melhor maneira de abordar esse tipo de coisa?
Respostas:
Aqui está a solução Numba. Na minha máquina, a versão Numba é> 1000x mais rápida que a versão python sem o decorador (para uma matriz de 200x200, 'k' e vetor de comprimento 200 'a'). Você também pode usar o decorador @autojit, que adiciona cerca de 10 microssegundos por chamada, para que o mesmo código funcione com vários tipos.
Divulgação: Sou um dos desenvolvedores do Numba.
fonte
Aqui está um começo. Primeiro, peço desculpas por qualquer erro.
Edit: Não, o limite superior estava correto conforme fornecido na pergunta. Deixei como está aqui, porque outra resposta agora usa o mesmo código, mas a correção é simples.
Primeiro uma versão em loop:
Eu fiz um único loop com fatias numpy:
Então eu escrevi uma versão Cython do código em loop (mais legível).
No meu laptop, este é cerca de 200x mais rápido que a versão em loop (e 8x mais rápido que a versão vetorizada em 1-loop). Tenho certeza que outros podem fazer melhor.
Eu joguei com uma versão Julia, e parecia (se eu cronometrasse corretamente) comparável ao código Cython.
fonte
O que você quer parece ser uma convolução; Eu acho que a maneira mais rápida de conseguir isso seria a
numpy.convolve
função.Talvez você precise corrigir os índices de acordo com suas necessidades exatas, mas acho que você gostaria de tentar algo como:
fonte