So, I have this code
所以,我有这个代码
from __future__ import division, print_function
import sympy as sp
import numpy as np
from sympy.utilities.lambdify import *
u = np.random.uniform(4, 6, 500)
w, k = sp.symbols('w k')
f = sp.log((k - w) * sp.exp((k - w)**5))
l = sum(f.subs(dict(k=k)) for k in u)
And now I want to use l
as a function of w
. So I know of some options
现在我想用l作为w的函数。所以我知道一些选择
z_lambdify = lambdify(w, l)
z_subs = lambda x: l.subs(w, x)
The first function gives an error
第一个函数给出错误
>>> z_lambdify(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <lambda>
OverflowError: math range error
>>> z_lambdify(4)
40.862695278600114
While the second gives answers
而第二个给出答案
>>> z_subs(1)
11469.9130597554
>>> z_subs(4)
40.8626952786003
I would just use this, but it is very slow. Any way to get around this (fixing the lamdify error or a way of using l
as a function that is not so slow)?
我会用它,但它很慢。任何解决这个问题的方法(修复lamdify错误或使用l作为一个不那么慢的函数的方法)?
Version: Python 2.7.6, NumPy 1.8.1, SymPy 0.7.4.1
版本:Python 2.7.6,NumPy 1.8.1,SymPy 0.7.4.1
1 个解决方案
#1
1
Answering your question:
The problem is that:
问题是:
z_lambdify = lambdify(w, l)
tells the new function to perform the calculations using the built-in math
functions, which you can check running with cProfile.run('z_lambdify(1)')
; while doing z_subs(1)
calls sympy
functions. To get the same behavior you should tell lambdify()
to use the same module:
告诉新函数使用内置数学函数执行计算,您可以使用cProfile.run('z_lambdify(1)')检查运行;在做z_subs(1)时调用sympy函数。要获得相同的行为,您应该告诉lambdify()使用相同的模块:
z_lambdify = lambdify(w, l, "sympy")
Important suggestion:
You should simplify your function already at its definition and then useNumPy
to perform the calculations much more efficiently. Using some simple algebra your function can be rewritten in a "non-overflowing" format as:
您应该在其定义中简化您的功能,然后使用NumPy更有效地执行计算。使用一些简单的代数,您的函数可以以“非溢出”格式重写,如:
f = lambda k, w: np.log(k - w) + (k - w)**5
such that your desired answer can be achieved doing:
这样你可以实现你想要的答案:
f(k=u, w=1).sum()
when you do f(k=u, w=1)
you get an array with the same shape of u
, where each value represents the result of the function evaluated with each value of u
. You can use this function to simultaneously evaluate f()
for different values of k
and w
, i.e. passing w
as another array with the same shape of u
instead of using a constant value.
当你做f(k = u,w = 1)时,你得到一个具有相同u形状的数组,其中每个值代表用u的每个值计算的函数的结果。您可以使用此函数同时为不同的k和w值评估f(),即将w作为另一个具有相同u形状的数组而不是使用常量值。
#1
1
Answering your question:
The problem is that:
问题是:
z_lambdify = lambdify(w, l)
tells the new function to perform the calculations using the built-in math
functions, which you can check running with cProfile.run('z_lambdify(1)')
; while doing z_subs(1)
calls sympy
functions. To get the same behavior you should tell lambdify()
to use the same module:
告诉新函数使用内置数学函数执行计算,您可以使用cProfile.run('z_lambdify(1)')检查运行;在做z_subs(1)时调用sympy函数。要获得相同的行为,您应该告诉lambdify()使用相同的模块:
z_lambdify = lambdify(w, l, "sympy")
Important suggestion:
You should simplify your function already at its definition and then useNumPy
to perform the calculations much more efficiently. Using some simple algebra your function can be rewritten in a "non-overflowing" format as:
您应该在其定义中简化您的功能,然后使用NumPy更有效地执行计算。使用一些简单的代数,您的函数可以以“非溢出”格式重写,如:
f = lambda k, w: np.log(k - w) + (k - w)**5
such that your desired answer can be achieved doing:
这样你可以实现你想要的答案:
f(k=u, w=1).sum()
when you do f(k=u, w=1)
you get an array with the same shape of u
, where each value represents the result of the function evaluated with each value of u
. You can use this function to simultaneously evaluate f()
for different values of k
and w
, i.e. passing w
as another array with the same shape of u
instead of using a constant value.
当你做f(k = u,w = 1)时,你得到一个具有相同u形状的数组,其中每个值代表用u的每个值计算的函数的结果。您可以使用此函数同时为不同的k和w值评估f(),即将w作为另一个具有相同u形状的数组而不是使用常量值。