SymPy lambdify with dot()

时间:2016-06-27 19:10:23

标签: python matrix sympy

取一个恰好名为SELECT * FROM excel.construction where construction.startDate BETWEEN '2012-01-01' AND '2012-01-10' OR construction.endDate BETWEEN '2012-01-01' AND '2012-01-10' group by startDate,endDate UNION ALL select * FROM excel.misc where misc.startDate BETWEEN '2012-01-01' AND '2012-01-10' OR misc.endDate BETWEEN '2012-01-01' AND '2012-01-10';m group by startDate, endDate UNION ALL select * from excel.spawar group by startDate, endDate 的未定义函数,并使其成为dot的一部分:

lambdify

惊喜:这确实有效!

显然,字符串import numpy import sympy class dot(sympy.Function): pass x = sympy.Symbol('x') a = sympy.Matrix([1, 0, 0]) f = sympy.lambdify(x, dot(a.T, x)) x = numpy.array([3, 2, 1]) print(f(x)) 以某种方式被提取并被点积的实现取代。有谁知道哪个?

上述结果为"dot"。但是,我想得到标量[3]。 (如何)我可以修改3来实现这一目标吗?

1 个答案:

答案 0 :(得分:2)

我不是sympy用户,但引用了lambdify的文档说:

  

如果用户未另行指定,则 SymPy功能将被替换   尽可能python-mathnumpy(如果可用)或   mpmath函数 - 完全按此顺序。要更改此行为,请执行此操作   可以使用“modules”参数。它接受:

     
      
  • 字符串“math”,“mpmath”,“numpy”,“numexpr”,“sympy”
  •   
  • 任何模块(例如数学)
  •   
  • 将sympy函数名称映射到任意函数的字典
  •   
  • 包含上述参数混合的列表,优先考虑首先出现的条目。
  •   

所以,如果你安装了python-math它会使用它,如果没有,但是你安装了numpy它将使用numpy的版本,否则mpmat然后介绍如何修改此行为。

在您的情况下,只提供一个modules值,该值是一个字典,将名称dot映射到一个可以根据需要返回标量的函数。

我的意思的一个例子:

>>> import numpy as np
>>> import sympy
>>> class dot(sympy.Function): pass
... 
>>> x = sympy.Symbol('x')
>>> a = sympy.Matrix([1,0,0])
>>> f = sympy.lambdify(x, dot(a.T, x), modules=[{'dot': lambda x, y: np.dot(x, y)[0]}, 'numpy'])
>>> y = np.array([3,2,1])
>>> print(f(y))
3
>>> print(type(f(y)))
<class 'numpy.int64'>

正如您可以通过操纵modules参数看到的,您可以实现您想要的效果。我在这里的实现绝对天真,但你可以概括为:

>>> def my_dot(x, y):
...     res = np.dot(x, y)
...     if res.ndim == 1 and res.size == 1:
...         return res[0]
...     return res

此函数检查正常dot的结果是否为标量,如果是,则返回普通标量,否则返回与np.dot相同的结果。