python - 使用 SymPy 简化索引指数

标签 python sympy

我正在尝试使用 SymPy 来处理一些求和和乘积,但我无法让 SymPy 简化涉及索引符号的表达式。

这是一个简单的例子:

A = symbols('A', real=True)
A_i = Indexed(A, i)

expr_1 = exp(-1/A)**A
expr_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))) 仍然返回未简化的表达式。

最佳答案

如果 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 does not support assumptions on indexed symbols 。尽管 powsimp 有一个标志 force=True 意味着通过忽略假设来强制简化,但这对 exp(-1/a)**a 没有影响

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

示例:

>>> 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)

关于python - 使用 SymPy 简化索引指数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52968391/

相关文章:

python - 如何使用 symPy 和 numPy 将符号替换为矩阵

python - Sympy - 求解器的不可预测的行为

python - Python 中的 Zip 列表

python - Ipython %matplotlib 给出 "ImportError: No module named moves"尽管通过 pip 安装了移动

python - 在 Pandas 中,我如何在两个不同的轴上按两次分组?

python - Sympy:从数值上找到符号函数的根

python-3.x - Sympy:如何解析 '2x' 等表达式?

python - sympy 矩阵中的 sympy 矩阵在替换时保持未计算状态

python - 无法将代理和链接传递到线程池以获取结果

python - 将 Fernet key 写入文本文件会生成字节字符串而不是 ASCII 字符串