简体   繁体   English

Sympy - 加速表达式评估

[英]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_kcompute_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM