简体   繁体   English

使用 SymPy 简化索引指数

[英]Simplifying indexed exponents with SymPy

I am trying to use SymPy to work with some summations and products but I cannot get SymPy to simplify the expressions involving indexed symbols.我正在尝试使用 SymPy 来处理一些求和和乘积,但我无法使用 SymPy 来简化涉及索引符号的表达式。

Here is a simple example:这是一个简单的例子:

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

expr_1 = exp(-1/A)**A
expr_2 = exp(-1/A_i)**A_i

Then, running powsimp(expr_1) returns e^-1 as expected but powsimp(expr_2) just returns the original unsimplified expression.然后,运行powsimp(expr_1)按预期返回 e^-1 但powsimp(expr_2)只返回原始的未简化表达式。

What is the right way to work with indexed variables when trying to simplify them?在尝试简化索引变量时,使用索引变量的正确方法是什么?

Note: Bringing in an actual summation since that is what I am trying to do, running powsimp(summation(expr_1, (i, 1, I))) returns I/e as expected but powsimp(summation(expr_2, (i, 1, I))) still returns the unsimplified expression.注意:引入实际求和,因为这是我想要做的,运行powsimp(summation(expr_1, (i, 1, I)))按预期返回 I/e 但powsimp(summation(expr_2, (i, 1, I)))仍然返回未简化的表达式。

The expression exp(-1/A)**A is equal to exp(-1) if A is real, but not in general.如果 A 是实数,则表达式exp(-1/A)**A等于exp(-1) ,但一般情况下并非如此。 For example,例如,

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

(here I is a built-in SymPy constant I , the imaginary unit). (这里I是一个内置的 SymPy 常数I ,虚数单位)。

So the assumption of being real is necessary for simplification.因此,为了简化,必须假设为实数。 And at present (v1.3) SymPy does not support assumptions on indexed symbols .目前 (v1.3) SymPy不支持对索引符号的假设 Although powsimp has a flag force=True meant to force simplification by ignoring assumptions, this does not have an effect on exp(-1/a)**a .尽管powsimp有一个标志force=True意味着通过忽略假设来强制简化,但这对exp(-1/a)**a

As a workaround, I offer a function powsimp_indexed which takes an expression and optional parameters: force as above, and indexed_assumptions .作为一种解决方法,我提供了一个函数powsimp_indexed ,它接受一个表达式和可选参数: force如上,和indexed_assumptions All indexed symbols in the expression are replaced by "dummies" with indexed_assumptions , simplification is made, and then the substitution is undone.表达式中的所有索引符号都被替换为带有indexed_assumptions的“哑元”,进行简化,然后撤消替换。

Examples:例子:

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

In the latter, simplification needs to happen before summation: hence, the Sum is an inert (non-evaluated) sum, it first gets simplified, and then doit() performs summation.在后者中,需要在求和之前进行化简:因此, 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM