Sympy-numpy集成存在-在哪里记录?

时间:2018-10-03 04:49:37

标签: python numpy sympy

我只是偶然发现我可以将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

这对我来说非常有用,因为我在同一程序中同时进行了数值和符号计算。但是,我很好奇这种方法的缺陷和局限性,例如,似乎包含Sympy对象的Numpy数组均不支持np.sinsym.sin,因为两者都会出错。 / p>

但是,这种numpy-sympy集成似乎在任何地方都没有记录。这些库是如何实现的只是偶然的情况,还是故意的功能?如果是后者,则何时设计使用它?何时使用sympy.Matrix或其他解决方案会更好?使用这种类型的数组时,我是否可以期望保持numpy的速度?或者一旦涉及sympy符号,它是否会立即回到Python循环?

简而言之,我很高兴发现此功能存在,但是我想了解更多!

2 个答案:

答案 0 :(得分:2)

这只是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列表没有性能优势;访问元素的开销可能比列表中要大。 Storing Python objects in a Python list vs. a fixed-length Numpy array

如果有更具体的数据结构,则没有理由使用此类数组。

答案 1 :(得分:0)

我刚刚在最新的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])