lambda - sympy 和 lambda() 的区别
问题描述
我一直在尝试优化最初使用 Sympy 编写的一段代码(它是正确的,但速度很慢)。我用lambda()
函数替换了方程(它要快得多)。但是,输出并不完全相同。这似乎是一个微小的偏差,但对我来说,它有所作为。我将非常感谢有关如何使两个结果相同的任何想法或建议。请看下面的代码:
# --------- Parameters ----------------
s_1_value = 0.9
s_2_value = 1.2
s_eq_pre = 11.628616990912533
history = 471.88639640808105
# --------- Sympy ----------------
t = sympy.Symbol('t', positive = True)
s_1, s_2 = sympy.symbols('s_1 s_2', real = True)
s_eq = + 6.11513442504139 * s_1 ** 3 + 0.764837815685049 * s_1 + 0.0319169512850692 * s_2 ** 3 + 0.00409678596174992 * s_2 + 0.0837906906442538
exponential = sympy.exp(1.73847894065589 * t) * sympy.exp(-1.74850463949595 * t)
s_eq_cur = s_eq.subs([(s_1, s_1_value), (s_2, s_2_value)])
DELTA = (s_eq_pre - s_eq_cur) * (1 / exponential.subs(t, history))
print("sympy: ", DELTA)
# --------- lambda ----------------
s_eq = lambda s_1, s_2: + 6.11513442504139 * s_1 ** 3 + 0.764837815685049 * s_1 + 0.0319169512850692 * s_2 ** 3 + 0.00409678596174992 * s_2 + 0.0837906906442538
exponential = lambda t: mpmath.exp(1.73847894065589 * t) * mpmath.exp(-1.74850463949595 * t)
DELTA_ = lambda s_eq_pre_, s_eq_cur_: (s_eq_pre_ - s_eq_cur_) * (1 / exponential(history))
s_eq_cur = s_eq(s_1_value, s_2_value)
DELTA = DELTA_(s_eq_pre, s_eq_cur)
print("lambda: ", DELTA)
和输出:
sympy: 718.832531350073
lambda: 718.83253135012
谢谢...
解决方案
不同之处在于 SymPy 在评估之前自动简化 lambda 表达式的能力:
>>> exp(1.73847894065589 * t) * exp(-1.74850463949595 * t)
exp(-0.01002569884006*t)
>>> 1/_.subs(t, history)
113.407882233341
该单个函数的计算结果与两个函数的乘积略有不同。如果您不希望发生这种情况,您要么必须对表达式使用 unevaluate-Mul,要么可以将 lambda 设置为 2-arg lambda 并在函数exp
调用时提供要用于的函数:
>>> e1, e2 = sympy.exp(1.73847894065589 * t), sympy.exp(-1.74850463949595 * t)
>>> uneval = lambda x: Mul(e1, e2, evaluate=False).subs(t, x)
>>> two_args = lambda e, t: e(1.73847894065589 * t)*e(-1.74850463949595 * t)
>>> 1/uneval(history)
113.407882233349
>>> 1/two_args(sympy.exp, history)
113.407882233349
>>> 1/two_args(mpmath.exp, history)
113.407882233349
推荐阅读
- android-studio - 如何在 Android Studio 中移动代码的换行行?
- java - 使用 docker-compose 时 Spring Boot 和 MySQL 无法在 Docker 上连接 - 显示“无法创建/设置连接:通信链接失败”
- java - Java程序反转字符串中的单词
- python - 使用表单时 Django 冻结
- python - Cython 自动展开循环
- java - Java中小数点后的ceil或四舍五入
- matlab - Matlab中RCNN检测器的混淆矩阵
- python - 检查并设置 Python 中的全局变量
- python - 如何在 python 中通过 sympy 集成一个 max 函数?
- python - 对嵌套列表的元素求和并创建一个新列表