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))
在那种情况下,我建议使用
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
模块进行数值评估...无论如何,如果这不起作用,请告诉我:)
我建议通过将符号
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))