乘积在符号数量的变量上的偏导数之和
Sum of partial derivatives of a product over a symbolic number of variables
我希望 SymPy 计算如下表达式:
我该如何定义符号和表达式,以便 SymPy 能够很好地处理它?我想将 N
保留为一个符号,即不制作 x
的实际有限列表。我已经尝试了 IndexedBase
和 Sum
/Product
的各种组合,但没有让它正常工作。
理想情况下是这样的:
x = IndexedBase("x")
i, j, N = symbols("i j N")
expr = Sum(Product(exp(-x[j]**2), (j, 1, N)).diff(x[i]), (i, 1, N))
到目前为止这是未计算的,expr 是
Sum(Derivative(Product(exp(-x[j]**2), (j, 1, N)), x[i]), (i, 1, N))
可以用doit
的方法来评价。不幸的是,产品的差异化还不太奏效:expr.doit()
returns
N*Derivative(Product(exp(-x[j]**2), (j, 1, N)), x[i])
将乘积重写为微分之前的总和有助于:
expr = Sum(Product(exp(-x[j]**2), (j, 1, N)).rewrite(Sum).diff(x[i]), (i, 1, N))
expr.doit()
returns
Sum(Piecewise((-2*exp(Sum(log(exp(-x[j]**2)), (j, 1, N)))*x[i], (1 <= i) & (i <= N)), (0, True)), (i, 1, N))
这是微分的正确结果。遗憾的是,我们在 Piecewise 中有那个无关的条件,而且 log(exp(...))
本应被简化。 SymPy 不会从外部总和的上下文中推断出 (1 <= i) & (i <= N)
为 True,并且它还犹豫要简化 log(exp
认为 x[j]
可能很复杂。所以我求助于 Piecewise 的外科手术,用第一块替换它,并强行扩展日志:
e = expr.doit()
p = next(iter(e.atoms(Piecewise)))
e = expand_log(e.xreplace({p: p.args[0][0]}), force=True)
现在 e
是
Sum(-2*exp(Sum(-x[j]**2, (j, 1, N)))*x[i], (i, 1, N))
很遗憾,无法 exp(Sum(..))
再次成为产品。
我希望 SymPy 计算如下表达式:
我该如何定义符号和表达式,以便 SymPy 能够很好地处理它?我想将 N
保留为一个符号,即不制作 x
的实际有限列表。我已经尝试了 IndexedBase
和 Sum
/Product
的各种组合,但没有让它正常工作。
理想情况下是这样的:
x = IndexedBase("x")
i, j, N = symbols("i j N")
expr = Sum(Product(exp(-x[j]**2), (j, 1, N)).diff(x[i]), (i, 1, N))
到目前为止这是未计算的,expr 是
Sum(Derivative(Product(exp(-x[j]**2), (j, 1, N)), x[i]), (i, 1, N))
可以用doit
的方法来评价。不幸的是,产品的差异化还不太奏效:expr.doit()
returns
N*Derivative(Product(exp(-x[j]**2), (j, 1, N)), x[i])
将乘积重写为微分之前的总和有助于:
expr = Sum(Product(exp(-x[j]**2), (j, 1, N)).rewrite(Sum).diff(x[i]), (i, 1, N))
expr.doit()
returns
Sum(Piecewise((-2*exp(Sum(log(exp(-x[j]**2)), (j, 1, N)))*x[i], (1 <= i) & (i <= N)), (0, True)), (i, 1, N))
这是微分的正确结果。遗憾的是,我们在 Piecewise 中有那个无关的条件,而且 log(exp(...))
本应被简化。 SymPy 不会从外部总和的上下文中推断出 (1 <= i) & (i <= N)
为 True,并且它还犹豫要简化 log(exp
认为 x[j]
可能很复杂。所以我求助于 Piecewise 的外科手术,用第一块替换它,并强行扩展日志:
e = expr.doit()
p = next(iter(e.atoms(Piecewise)))
e = expand_log(e.xreplace({p: p.args[0][0]}), force=True)
现在 e
是
Sum(-2*exp(Sum(-x[j]**2, (j, 1, N)))*x[i], (i, 1, N))
很遗憾,无法 exp(Sum(..))
再次成为产品。