Эффективные числовые массивы с множественной точностью

Numpy - это библиотека для эффективных числовых массивов.

mpmath, при поддержке gmpy, является библиотекой для эффективных многоточных чисел.

Как мне их эффективно соединить? Или уже эффективно просто использовать массив Numpy с числами mpmath?

Не имеет смысла просить "столь же эффективно, как нативные операции с плавающей запятой", но вы можете попросить, чтобы он был близок к эффективности эквивалентного кода C (или, в случае неудачи, кода Java/C#). В частности, эффективный массив чисел с множественной точностью будет означать, что вы можете выполнять векторизованные операции и не искать, скажем, __add__ миллион раз в глобальном переводчике.

Редактировать: Для близкого избирателя: Мой вопрос об эффективном способе их объединения. Ответ в возможном дубликате конкретно указывает на то, что наивный подход неэффективен.

Наличие пустого массива dtype=object может ввести в заблуждение, потому что мощный мощный numpy механизм, который делает операции со стандартными dtypes суперскоростными, теперь позаботится о python-операторах объекта по умолчанию, а это означает, что скорости не будет. больше не

3 ответа

Решение

Отказ от ответственности: я утверждаю gmpy2, Следующие тесты были выполнены с версией разработки.

a а также b 1000 списков элементов, содержащих псевдослучайный gmpy2.mpfr значения с 250 битами точности. Тест выполняет поэлементное умножение двух списков.

Первый тест использует понимание списка:

%timeit [x*y for x,y in zip(a,b)]
1000 loops, best of 3: 322 µs per loop

Второй тест использует map Функция для выполнения цикла:

%timeit list(map(gmpy2.mul, a, b))
1000 loops, best of 3: 299 µs per loop

Третий тест - реализация C понимания списка:

%timeit vector2(a,b)
1000 loops, best of 3: 243 µs per loop

В третьей попытке vector2 пытается быть хорошо управляемой функцией Python. Числовые типы обрабатываются с использованием gmpy2правила преобразования типов, выполняется проверка ошибок и т. д. Проверяются настройки контекста, создаются ненормальные числа, если требуется, возбуждаются исключения, если это необходимо, и т. д. Если вы игнорируете все улучшения Python и предполагаете, что все значения уже gmpy2.mpfrЯ смог сократить время с четвертой попытки:

%timeit vector2(a,b)
10000 loops, best of 3: 200 µs per loop

Четвертая версия не выполняет достаточную проверку ошибок для общего использования, но возможна версия между третьей и четвертой попытками.

Можно уменьшить накладные расходы Python, но с увеличением точности эффективная экономия уменьшается.

Текущий проект - это qd, который сможет встраивать высокоточные числа в массивы Numpy, используя фиксированный размер в памяти его значений. Прямо сейчас, тип доступен для Numpy, но еще не как dtype; однако вы уже можете использовать его с объектом dtype.

(Если вы хотите посмотреть, как будет выглядеть dtype, вы можете уже раскомментировать соответствующую строку для его компиляции с поддержкой Numpy; это должно сработать, если у вас есть взгляд, но еще не реализована какая-либо функция; следующий выпуск должен быть в сентябре или октябрь).

Насколько мне известно, не существует библиотеки Python, которая поддерживает операции векторизованного массива с несколькими значениями точности. К сожалению, не существует особенно эффективного способа использовать значения с множественной точностью в numpy ndarray, и это крайне маловероятно, что когда-либо будет, поскольку значения с множественной точностью несовместимы с базовой моделью массива numpy.

Каждый элемент в numpy ndarray с плавающей запятой занимает одинаковое количество байтов, поэтому массив может быть представлен в терминах адреса памяти первого элемента, размеров и регулярного смещения (или шага) байта между последовательными элементами массива.

Эта схема имеет существенные преимущества в производительности - смежные элементы массива расположены по соседним адресам памяти, поэтому последовательное чтение / запись в массив выигрывает от лучшей локализации ссылки. Разметка также очень важна для удобства использования, поскольку позволяет выполнять такие операции, как работа с представлениями одного и того же массива без создания новых копий в памяти. Когда вы делаете x[::2]на самом деле вы просто удваиваете шаг по первой оси массива, так что вы обращаетесь к любому другому элементу.

В отличие от этого, массив, содержащий значения множественной точности, должен содержать элементы неравного размера, поскольку значения с более высокой точностью занимают больше байтов, чем значения с низкой точностью. Массив с множественной точностью, следовательно, не может регулярно перемещаться, и теряет преимущества, упомянутые выше.

Помимо проблем с построением массивов, даже простая арифметика для скаляров с множественной точностью, вероятно, будет намного медленнее, чем для скаляров с плавающей запятой. Почти все современные процессоры имеют специализированные блоки с плавающей запятой, тогда как арифметика с множественной точностью должна быть реализована в программном, а не аппаратном обеспечении.

Я подозреваю, что эти проблемы с производительностью могут быть в значительной степени причиной того, почему еще нет библиотеки Python, обеспечивающей нужную вам функциональность.

Другие вопросы по тегам