Я хочу реализовать следующее выражение в Python:
где и - массивы numpy размером , а - массив numpy размером . Размер может составлять примерно до 10000, и функция является частью внутреннего цикла, который будет оцениваться много раз, поэтому важна скорость.
В идеале я бы хотел вообще избежать цикла for, хотя, думаю, это еще не конец света, если он есть. Проблема в том, что я не могу понять, как это сделать, не имея пары вложенных циклов, и это, вероятно, сделает его довольно медленным.
Кто-нибудь может увидеть, как выразить вышеприведенное уравнение, используя numpy, таким образом, чтобы он был эффективным и желательно также читабельным? В целом, как лучше всего подойти к такого рода вещам?
Ответы:
Вот решение Numba. На моей машине версия Numba> в 1000 раз быстрее, чем версия Python без декоратора (для матрицы 200x200, k и вектора длиной 200 a). Вы также можете использовать декоратор @autojit, который добавляет около 10 микросекунд на вызов, чтобы один и тот же код работал с несколькими типами.
Раскрытие: я один из разработчиков Numba.
источник
Вот начало. Во-первых, мои извинения за любые ошибки.
Я экспериментировал с парой разных подходов. Меня немного смутили ограничения суммирования - должен ли верхний предел быть , а не i - 1 ?я я - 1
Изменить: нет, верхний предел был правильным, как указано в вопросе. Я оставил все как есть, потому что другой ответ теперь использует тот же код, но исправить это просто.
Сначала зацикленная версия:
Я сделал это один цикл с кусочками:
Цифровая версия с одним явным циклом примерно в 25 раз быстрее на моем компьютере, когда .n = 5000
Затем я написал версию (более читабельного) зацикленного кода на Cython.
На моем ноутбуке этот примерно в 200 раз быстрее, чем зацикленная версия (и в 8 раз быстрее, чем одноконтурная векторизованная версия). Я уверен, что другие могут сделать лучше.
Я играл с версией Julia, и она казалась (если я правильно рассчитал время) сопоставимой с кодом Cython.
источник
То, что вы хотите, кажется, свертка; Я думаю, что самым быстрым способом достижения этой цели была бы
numpy.convolve
функция.Возможно, вам придется исправить индексы в соответствии с вашими потребностями, но я думаю, что вы хотели бы попробовать что-то вроде:
источник