Интегрированная интеграция существует - где это задокументировано? - PullRequest
0 голосов
/ 03 октября 2018

Я только что случайно обнаружил, что могу смешивать выражения sympy с массивами numpy:

>>> import numpy as np
>>> import sympy as sym
>>> x, y, z = sym.symbols('x y z')
>>> np.ones(5)*x
array([1.0*x, 1.0*x, 1.0*x, 1.0*x, 1.0*x], dtype=object)
# I was expecting this to throw an error!

# sum works and collects terms etc. as I would expect
>>> np.sum(np.array([x+0.1,y,z+y]))
x + 2*y + z + 0.1
# dot works too
>>> np.dot(np.array([x,y,z]),np.array([z,y,x]))
2*x*z + y**2
>>> np.dot(np.array([x,y,z]),np.array([1,2,3]))
x + 2*y + 3*z

Это очень полезно для меня, потому что я выполняю как числовые, так и символьные вычисления в одной и той же программе.Однако мне любопытно, какие подводные камни и недостатки этого подхода - например, кажется, что ни np.sin, ни sym.sin не поддерживаются в массивах Numpy, содержащих объекты Sympy, поскольку оба выдают ошибку.

Тем не менее, эта полная интеграция, похоже, нигде не документирована.Это просто случайность того, как эти библиотеки реализованы, или это преднамеренная функция?Если последнее, когда оно предназначено для использования, и когда было бы лучше использовать sympy.Matrix или другие решения?Могу ли я рассчитывать сохранить некоторую скорость numpy при работе с массивами такого типа, или она просто вернется к циклам Python, как только появится символ sympy?

Короче говоря, я рад найти этофункция существует, но я хотел бы узнать о ней больше!

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Я только что натолкнулся на соответствующую заметку в последних numpy заметках о выпуске (https://docs.scipy.org/doc/numpy-1.15.1/release.html)

Comparison ufuncs accept dtype=object, overriding the default bool

This allows object arrays of symbolic types, which override == and other operators to return expressions, to be compared elementwise with np.equal(a, b, dtype=object).

Я думаю, это означает, что это работает, но раньше этого не было:

In [9]: np.array([x+.1, 2*y])==np.array([.1+x, y*2])
Out[9]: array([ True,  True])
0 голосов
/ 03 октября 2018

Это просто поддержка NumPy для массивов объектов.Это не специфично для SymPy.NumPy проверяет операнды и обнаруживает, что не все они являются скалярами;Есть некоторые объекты.Поэтому он вызывает этот объект __mul__ или __rmul__ и помещает результат в массив объектов.Например: объекты mpmath,

>>> import mpmath as mp
>>> np.ones(5) * mp.mpf('1.23')
array([mpf('1.23'), mpf('1.23'), mpf('1.23'), mpf('1.23'), mpf('1.23')],
      dtype=object)

или списки:

>>> np.array([[2], 3])*5
array([list([2, 2, 2, 2, 2]), 15], dtype=object)
>>> np.array([2, 3])*[[1, 1], [2]]
array([list([1, 1, 1, 1]), list([2, 2, 2])], dtype=object)

Могу ли я ожидать сохранения скорости numpy при работе с массивами такого типа,

Нет.Массивы объектов NumPy не имеют преимуществ в производительности по сравнению со списками Python;в доступе к элементам, вероятно, больше издержек, чем в списке. Хранение объектов Python в списке Python по сравнению с массивом Numpy фиксированной длины

Нет смысла использовать такие массивы, если доступна более конкретная структура данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...