[英]Sympy - speed up expressions evaluation
I compute something in python with sympy but this require too much time.我用 sympy 在 python 中计算了一些东西,但这需要太多时间。 The code looks like this:
代码如下所示:
def compute_aux_lyupanov_val_k(y, A, B, C, D, k):
res = []
res.append(y)
for i in range(k-1):
y = (C + D * y) / (A + B * y)
res.append(y)
return res
def compute_lyupanov_val(y, A, B, C, D, n):
res = 0
y_values = compute_aux_lyupanov_val_k(y, A, B, C, D, n) # values for y'_0. y'_1...
for i in range(n):
T = ( (A + B * y_values[i])**2 + (C + D * y_values[i])**2 ) / (1 + y_values[i]**2)
res = res + math.log(T, 10) # default is base e = 2.71
res = res * (1/(2*n))
return res
n = 1000
y_inital = 0.01
beta_set_values = np.linspace(0, 6, 1000)
alpha_set_values = np.linspace(0, 5, 1000)
points = it.product(beta_set_values, alpha_set_values)
for point in points:
alpha_val = point[1]
beta_val = point[0]
A_val = A.subs([ (beta, beta_val), (alpha, alpha_val) ])
B_val = B.subs([ (beta, beta_val), (alpha, alpha_val) ])
C_val = C.subs([ (beta, beta_val), (alpha, alpha_val) ])
D_val = D.subs([ (beta, beta_val), (alpha, alpha_val) ])
lyupanov_val = compute_lyupanov_val(y_inital, A_val, B_val, C_val, D_val, n)
if lyupanov_val > 0:
plt.scatter([beta_val], [alpha_val], color = 'r', s=1)
plt.show()
Maybe it seems long, but let me explain clearly: A, B, C, D are expression which can be evaluated depending on alpha, beta values.也许看起来很长,但让我解释清楚: A,B,C,D是表达式,可以根据alpha,beta值进行评估。 For a set of points (alphas and betas) I compute a value ( lyupanov_val ) and scatter the (beta, alpha) point only if computed value lyupanov_val is greater than 0. The computations which happened in auxiliary functions ( compute_aux_lyupanov_val_k and compute_lyupanov_val ) are only numerical ( A, B, C, D and other parameters are scalars now - inside of these functions, not symbols)
对于一组点(alphas 和 beta),我计算一个值( lyupanov_val )并仅在计算值lyupanov_val大于 0 时才分散(beta,alpha)点。辅助函数( compute_aux_lyupanov_val_k和compute_lyupanov_val )中发生的计算仅数字( A、B、C、D和其他参数现在是标量 - 在这些函数内部,而不是符号)
I think the expensive computation part happen because of the substitution at every iteration.我认为昂贵的计算部分是由于每次迭代时的替换而发生的。 I know that sympy provide a special plot function which can speed up the computations sp.plot_implicit(expresion > 0, (beta, 0, 6), (alpha, 0, 5) but the problem with this approach is the fact that I don't use a direct expression (eg alpha + beta / 2), I use auxiliary functions for numerical computations (eg compute_aux_lyupanov_val_k )
我知道 sympy 提供了一个特殊的 plot function 可以加速计算sp.plot_implicit(expresion > 0, (beta, 0, 6), (alpha, 0, 5)但这种方法的问题是我不知道不使用直接表达式(例如 alpha + beta / 2),我使用辅助函数进行数值计算(例如compute_aux_lyupanov_val_k )
If I used如果我用
sp.plot_implicit(compute_lyupanov_val(y_inital, A, B, C, D, n) > 0, (beta, 0, 6), (alpha, 0, 5))
then the python raise TypeError: can't convert expression to float然后 python 引发TypeError: can't convert expression to float
Any ideas?有任何想法吗?
subs
does a symbolic substitution but the result is still a symbolic expression. subs
执行符号替换,但结果仍然是符号表达式。 May be what you want is instead可能是你想要的
A_val = A.subs([ (beta, beta_val), (alpha, alpha_val) ]).evalf()
and so on for the 4 variables. 4 个变量依此类推。
Even better would be to use更好的是使用
A_val = A.evalf(subs={beta: beta_val, alpha: alpha_val})
( subs
does a replacement and a symbolic simplification; if what you want is instead just the numeric value a direct computation is better). (
subs
进行了替换和符号简化;如果您想要的只是数值,那么直接计算会更好)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.