发布于2019-12-04 09:04 阅读(1235) 评论(0) 点赞(11) 收藏(4)
我正在使用SymPy 1.0和Python 2.7。我想计算前100个整数的总和:
此代码成功运行
import sympy as sy
from sympy.tensor import IndexedBase, Idx
import numpy as np
x = sy.IndexedBase('x')
i = sy.symbols('i', cls=Idx)
s = sy.Sum(x[i], (i, 0, 100))
s_lambda = sy.lambdify(sy.DeferredVector('x'), s, 'numpy')
s_lambda(np.arange(101))
并给出5050
了预期的结果。但是当我尝试使用a Product
而不是a 进行相同操作时Sum
:
import sympy as sy
from sympy.tensor import IndexedBase, Idx
import numpy as np
x = sy.IndexedBase('x')
i = sy.symbols('i', cls=Idx)
s = sy.Product(x[i], (i, 0, 100))
s_lambda = sy.lambdify(sy.DeferredVector('x'), s, 'numpy')
s_lambda(np.arange(101))
我知道NameError: global name 'Product' is not defined
我在做什么错?是否有解决方法来获取我想要的?
编辑1:如果我事先不知道的限制,该怎么办Product
。比方说
import sympy as sy
from sympy.tensor import IndexedBase, Idx
import numpy as np
x = sy.IndexedBase('x')
i = sy.symbols('i', cls=Idx)
n = sy.symbols('n', integer=True, positive=True)
s = sy.Product(x[i], (i, 0, n))
s_lambda = sy.lambdify((sy.DeferredVector('x'), n) s.doit(), 'numpy')
s_lambda(np.arange(101), 5)
编辑2:我试图找到一种解决方法。NameError: global name 'Product' is not defined
由于以下原因而给出错误:
lambdastr((sy.DeferredVector('x'), n), p)
这给出了:
lambda x,n: (Product(x[i], (i, 0, n)))
而对于Sum
我们,我们有一个有效的lambda函数:
lambda x,n: ((builtins.sum(x[i] for i in range(0, n+1))))
此时,问题围绕Product
功能的定义。根据手册,我可以通过dict
我对函数的定义进行
注入
def my_prod(a, b):
# my implementation
pass
my_fun = {"Product" : my_prod}
f = sy.lambdify((sy.DeferredVector('x'), n), p, modules=['numpy', my_fun])
f([1,2,3,4,5], 2)
问题是,list indices must be integers, not Symbol
当我尝试使用lambdified函数时会引发错误f
。我猜这是由于i
它是一个符号,而它应该是整数。我不明白为什么integer
在尝试调用之前,它没有通过实际my_prod
的Sum
情况。
Product
事先知道的极限时您可以通过调用.doit()
将扩展Product
成其组成部分来解决此问题:
In [104]: s = sy.Product(x[i], (i, 1, 10)); s
Out[104]: Product(x[i], (i, 1, 10))
In [105]: s.doit()
Out[105]: x[1]*x[2]*x[3]*x[4]*x[5]*x[6]*x[7]*x[8]*x[9]*x[10]
例如,
import sympy as sy
from sympy.tensor import IndexedBase, Idx
import numpy as np
x = sy.IndexedBase('x')
i = sy.symbols('i', cls=Idx)
s = sy.Product(x[i], (i, 1, 10))
s_lambda = sy.lambdify(sy.DeferredVector('x'), s.doit(), 'numpy')
print(s_lambda(np.arange(11)))
版画
3628800
但是,如果.doit()
与with一起使用,sy.Product(x[i], (i, 1, 100))
则由于np.arange(101)
dtype int32
或int64
(取决于您的操作系统)和产品,您将获得算术溢出100!
In [109]: math.factorial(100)
Out[109]: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
太大,无法存储在int32
或int64
数组值中。
In [118]: np.iinfo('int64').max
Out[118]: 9223372036854775807
In [119]: np.iinfo('int64').max < math.factorial(100)
Out[119]: True
从而,
s = sy.Product(x[i], (i, 1, 100))
s_lambda = sy.lambdify(sy.DeferredVector('x'), s.doit(), 'numpy')
print(s_lambda(np.arange(101)))
提出一个
RuntimeWarning: overflow encountered in long_scalars
并且错误地打印0
。
如果将输入从dtype数组更改int64
为Python列表,int
则可以正确计算乘积:
import sympy as sy
from sympy.tensor import IndexedBase, Idx
import numpy as np
x = sy.IndexedBase('x')
i = sy.symbols('i', cls=Idx)
s = sy.Product(x[i], (i, 1, 100))
s_lambda = sy.lambdify(sy.DeferredVector('x'), s.doit(), 'numpy')
print(s_lambda(np.arange(101).tolist()))
版画
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Product
都没有预先已知解决方法(AFAICS)变得更加复杂。如果使用调试器跟踪使用时Sum
所遵循的代码路径,则会发现该
路径LambdaPrinter._print_Sum
被转换Sum(x[i], (i, 0, n))
为表达式builtins.sum(x[i] for
i in range(0, n+1))
。
如果将_print_Product
方法添加到NumPyPrinter
的子类中LambdaPrinter
,那么我们可以lambdify
成功地转换Product
为NumPy可以评估的表达式:
import sympy as sy
from sympy.tensor import IndexedBase, Idx
import numpy as np
import sympy.printing.lambdarepr as SPL
def _print_Product(self, expr):
loops = (
'for {i} in range({a}, {b}+1)'.format(
i=self._print(i),
a=self._print(a),
b=self._print(b))
for i, a, b in expr.limits)
return '(prod([{function} {loops}]))'.format(
function=self._print(expr.function),
loops=' '.join(loops))
SPL.NumPyPrinter._print_Product = _print_Product
x = sy.IndexedBase('x')
i = sy.symbols('i', cls=Idx)
n = sy.symbols('n', integer=True, positive=True)
s = sy.Product(x[i], (i, 1, n))
s_lambda = sy.lambdify((sy.DeferredVector('x'), n), s, 'numpy')
print(s_lambda(np.arange(101), 5))
版画
120
作者:黑洞官方问答小能手
链接:https://www.pythonheidong.com/blog/article/167120/207c9ae31fc410cee9da/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!