- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 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
。但是,当我尝试对 Product
而不是 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
注入(inject)我对函数的定义
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)
问题是,当我尝试使用 lambdified 函数 f
时,list indices must be integers, not Symbol
出现错误。我想这是由于 i
是一个符号,而它应该是一个整数。我不明白为什么它在尝试调用 my_prod
之前没有传递实际的 integer
,因为它是针对 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()
与 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
.
我在范围 (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
关于python - SymPy 不能 lambdify Product,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37846492/
下面的 python 脚本计算表达式中的第一项, 4.939e-3xAxB+8.7989 在 (A,B) = (1.0,1.0): import sympy from sympy import *
使用 Java 和 Apache Spark(已在 Scala 中重写),面对旧的 API 方法(org.apache.spark.rdd.JdbcRDD 构造函数),其参数为 AbstractFun
假设我有一个符号变量(来自sympy)定义为 z = r/p * (p-c)/(r-c) 更正式地说,将其表示为 z=z(p; c, r):c 和 r 是我想要的参数保持不变,并且 z 实际上是 p
假设我想用单个符号创建一个表达式,用 Latex 编写(因为在 Jupyter Notebook 中可视化它真的很有帮助)。然后我使用 lambdify 获得一个函数,我可以计算多个值。问题是此函数将
假设您已经计算了 fu 作为 sympy 计算的结果: fu= sy.cos(x)+sy.sin(y)+1 在哪里 x,y = sy.symbols("x y") 是符号。现在您想将 fu 转换为(显
我有一个包含多个变量的表达式,假设如下所示: import numpy as np import sympy as sym from sympy import Symbol, Add, re, lam
我有两个用 sympy 的 lamdify 创建的函数 a = sympy.lambdify((x, y), K / (2 * math.pi) * sympy.cos(theta) / r) b =
如何计算 Sympy CoordSys3D 表达式上的点? 使用 Sympy 物理模块,这个过程按预期工作: from sympy import * from sympy.physics.vector
我有这个代码: var = ['a','b','c'] arr = np.array([ [1,2,3,4,5,6,7,8,9], [0.1,0.2,0.3,0.4,0.5,0.6,0
我想在 sympy 中创建一个符号矩阵的函数,然后对其进行 lambdify 以在 numpy 中进行评估。让我们试试这个简单的函数,它返回我输入的值 f(x) = x,但最终我想做一些事情,比如获取
我正在尝试提供一个数组作为输入,并期望一个数组作为以下代码的输出。 from sympy import symbols from sympy.utilities.lambdify import lam
我用 python 编写了一个脚本,它使用 sympy 来计算几个向量/矩阵公式。但是,当我尝试将它们转换为可以使用 sympy.lambdify 评估的函数时,我得到了一个 SyntaxError
我知道 sympy 的 lambdify函数可以创建一个带有参数 variables 和 body expression 的 lambda,如下所示: lambdify(variables, expr
我有以下问题:我想lambdify 一个包含参数积分的sympy 表达式,例如Integral(tanh(a*x),(x,0 ,1))。我尝试手动实现 like here. 本质上,我们想要的是将积分
我无法对包含导数的表达式进行 lambdify。这是解释问题的最少代码: import sympy x = sympy.symbols('x', real=True) a = sympy.Functi
我无法理解以下数值评估。我有一个包含两个变量的函数,r 和 gamma。我现在希望将该函数的根绘制为从 0 到 500 的 gamma 函数。我知道如何使用 lambdify 来评估一维变量数组上的函
获取一个恰好名为dot的未定义函数,并将其作为lambdify的一部分: import numpy import sympy class dot(sympy.Function): pass x
我正在使用 SymPy 1.0 和 Python 2.7。我想计算前 100 个整数的总和: 这段代码运行成功 import sympy as sy from sympy.tensor import
我正在尝试使用 modules 关键字参数让 lambdify 理解期望不止一种类型的输入。根据 lambdify ( http://docs.sympy.org/dev/_modules/sympy
标题说明了一切。有什么方法可以序列化由 sympy.lambdify 生成的函数吗?: import sympy as sym import pickle import dill a, b = sym
我是一名优秀的程序员,十分优秀!