为了账号安全,请及时绑定邮箱和手机立即绑定

使用 SymPy 简化索引指数

使用 SymPy 简化索引指数

慕尼黑5688855 2021-07-12 12:27:29
我正在尝试使用 SymPy 来处理一些求和和乘积,但我无法使用 SymPy 来简化涉及索引符号的表达式。这是一个简单的例子:A = symbols('A', real=True)A_i = Indexed(A, i)expr_1 = exp(-1/A)**Aexpr_2 = exp(-1/A_i)**A_i然后,运行powsimp(expr_1)按预期返回 e^-1 但powsimp(expr_2)只返回原始的未简化表达式。在尝试简化索引变量时,使用索引变量的正确方法是什么?注意:引入实际求和,因为这是我想要做的,运行powsimp(summation(expr_1, (i, 1, I)))按预期返回 I/e 但powsimp(summation(expr_2, (i, 1, I)))仍返回未简化的表达式。
查看完整描述

1 回答

?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

如果 A 是实数,则表达式exp(-1/A)**A等于exp(-1),但一般情况下不是。例如,


a = symbols('a')

expr = (exp(-1/a)**a).subs(a, I/(2*pi))    # returns 1

(这里I是一个内置的 SymPy 常数I,虚数单位)。


因此,为了简化,必须假设为实数。目前 (v1.3) SymPy不支持对索引符号的假设。尽管powsimp有一个标志force=True旨在通过忽略假设来强制简化,但这对exp(-1/a)**a.


作为一种解决方法,我提供了一个powsimp_indexed接受表达式和可选参数的函数:force如上,和indexed_assumptions. 表达式中的所有索引符号都被替换为带有 的“哑元” indexed_assumptions,进行简化,然后撤消替换。


例子:


>>> powsimp_indexed(expr_2)

exp(-1/A[i])**A[i]

>>> powsimp_indexed(expr_2, real=True)

exp(-1)

>>> powsimp_indexed(Sum(expr_2, (i, 1, M)), real=True).doit()

exp(-1)*M

在后者中,需要在求和之前进行简化:因此,这Sum是一个惰性(未评估)和,它首先被简化,然后doit()执行求和。


def powsimp_indexed(expr, force=False, **indexed_assumptions):

    indexed_syms = {t for t in expr_2.free_symbols if isinstance(t, Indexed)}

    subs = {}

    inverse_subs = {}

    for s in indexed_syms:

        d = Dummy('xi', **indexed_assumptions)

        subs[s] = d

        inverse_subs[d] = s

    return powsimp(expr.xreplace(subs), force=force).xreplace(inverse_subs)


查看完整回答
反对 回复 2021-07-28
  • 1 回答
  • 0 关注
  • 151 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信