如何使用缓存减少sympy符号计算问题?

问题描述 投票:0回答:2
import sympy as sp
from fuanctools import lru_cache

s = []
for i in range(4):
    s.append(sp.Symbol('s%s'%i)

@lru_cache
def some_calculation(input1, input2):
    '''
    some calculation code
    '''
    return calculation_result

#First calculation
some_calculation(sp.sin(s[0]),sp.sin(s[1]))
#Second calculation
some_calculation(sp.sin(s[2]),sp.sin(s[3]))


在第二次计算中,它与第一次的不同之处仅在于变量。实际计算过程是一样的。在当前方法中,它具有不同的因变量,因此需要重新计算。如何使用缓存的方式,让计算过程不必重复,不改变计算结果

附言这里的计算是为了保留变量的原始形式,而不是代入后的数值解。这里有一些例子:

def example_calculation(input1, input2):
    return sp.simplify(input1(input1+input2) + input2(input1-input2))     
python caching hash sympy symbols
2个回答
1
投票

在那种情况下,我建议使用

lambdify
模块中的
sympy
函数将符号表达式转换为可调用函数,然后使用 memoization(缓存)存储先前计算的结果...

所以,它看起来像这样:

import sympy as sp
from functools import lru_cache

s = []
for i in range(4):
s.append(sp.Symbol('s%s'%i))

@lru_cache(maxsize=None)
def some_calculation(input1, input2):
x, y = sp.symbols('x y')
# Define symbolic expressions
expr1 = sp.sin(input1 * x)
expr2 = sp.cos(input2 * y)
# Convert to callable functions
func1 = sp.lambdify(x, expr1, 'numpy')
func2 = sp.lambdify(y, expr2, 'numpy')
# Compute and return result
return func1(0.5) * func2(1.5)

# First calculation
  print(some_calculation(s[0], s[1]))
# Second calculation
  print(some_calculation(s[2], s[3]))
# Repeated calculation
  print(some_calculation(s[0], s[1]))

lru_cache
装饰器用于缓存之前函数调用的结果。
lambdify
函数用于将符号表达式转换为可以进行数值计算的可调用函数。
numpy
函数中的
lambdify
参数告诉
sympy
使用
numpy
模块进行数值评估...无论如何,如果这不起作用,请告诉我:)


0
投票

我建议通过将符号

x
y
传递给计算来获得符号结果,然后该结果在某种意义上是 您的缓存。只需用您想要的值替换
x
y
.

def f(x,y):
  return x + y

from sympy.abc import x, y
from sympy import symbols
s = symbols('s:4')
v = f(x, y)

>>> v
x + y
>>> v.subs(dict(zip((x,y),(s[0],s[1]))))
s0 + s1

或更复杂

f

def f(x,y):
  g, h = map(Function, 'gh')
  return g(x + y) + h(x - y)

s=symbols('s:5')
C=lambda i,j: cos(s[i])*cos(s[j]);S=lambda i,j: sin(s[i])*sin(s[j])

>>> eq = f(x, y); eq
g(x + y) + h(x - y)
>>> eq.subs(x,S(0,1)).subs(y,C(2,4))
g(sin(s0)*sin(s1) + cos(s2)*cos(s4)) + h(sin(s0)*sin(s1) - cos(s2)*cos(s4))
>>> eq.subs(x,S(1,2)).subs(y,C(3,4))
g(sin(s1)*sin(s2) + cos(s3)*cos(s4)) + h(sin(s1)*sin(s2) - cos(s3)*cos(s4))
© www.soinside.com 2019 - 2024. All rights reserved.