python符号求和和参数大小向量的区分

时间:2016-04-13 08:28:49

标签: python sympy

这个问题涉及迭代和区分参数中参数大小的矢量变量。他们没有给予,也永远不会。

例如,采取以下简单设置:

我有M个向量x,每个维度为K. 我有一个权重向量w,也是维数K. (M和K永远不会取值,他们只会留下M和K)。

我的函数对x向量求和,然后用权重w执行求和的点积:

tmpsyms = numbered_symbols("tmp")
symbols_list, assignements = cse((grad_0), symbols=tmpsyms)
for (symb, ass) in symbols_list:
    print (str(symb) + ' = ' + str(ass))
print(assignements)

函数的导数w.r.t w_i应为sum(x_i),i = 1..M

我如何在同情中编码?总结和分化。

修改

由于弗朗西斯科的伟大答案明确表示目前无法做到这一点,我正在寻找一种解决方法。 换句话说:是否有可能:

  1. 定义固定尺寸(例如,M = 100,K = 200);
  2. 在sympy中定义我的函数f
  3. 计算f.diff(w_1),f.diff(w_2)等
  4. 从输出中推断自动 f.diff(w_i)的常用表单? (通过收集条款或类似的东西)?
  5. 我已经做了第4步手动,将衍生品分解为更简单的术语,使其更具可读性,然后寻找“模式”。我正在使用此代码taken from this answer来提高可读性:

    id

1 个答案:

答案 0 :(得分:2)

您可以使用SymPy 1.0版中引入的新张量阵列模块。

我认为您的 K M 参数是数字,而不是符号(否则我建议使用 sympy.tensor.Indexed )。

考虑这个例子: X 是两个向量的数组,每个向量的长度为3.因此 X 是秩2和形状(2,3)的张量。 我还选择了一个带有符号的权重向量的简单例子:

In [1]: from sympy import *
In [2]: from sympy.tensor.array import *

In [3]: var("a,b,c,d,e,f")
Out[3]: (a, b, c, d, e, f)

In [4]: X = Array([[a, b, c], [d, e, f]])

In [5]: var("w1,w2,w3")
Out[5]: (w1, w2, w3)

In [6]: W = Array([w1, w2, w3])

现在创建一个包含三个索引的产品张量(2个来自 X ,1个来自 W ):

In [7]: tp = tensorproduct(X, W)

In [8]: tp
Out[8]: [[[a*w1, a*w2, a*w3], [b*w1, b*w2, b*w3], [c*w1, c*w2, c*w3]], [[d*w1, d*w2, d*w3], [e*w1, e*w2, e*w3], [f*w1, f*w2, f*w3]]]

In [9]: tp.shape
Out[9]: (2, 3, 3)

让我们对第2和第3个索引求和(Python表示法中的索引1和2,因为索引从零开始),这相当于你所谓的 dot 产品:

In [10]: tensorcontraction(tp, (1, 2))
Out[10]: [a*w1 + b*w2 + c*w3, d*w1 + e*w2 + f*w3]

相同的表达式可以总结:

In [12]: stc = sum(tensorcontraction(tp, (1, 2)))

In [13]: stc
Out[13]: a*w1 + b*w2 + c*w3 + d*w1 + e*w2 + f*w3

对于数组的衍生物,您可以使用 derive_by_array(...)。它将创建一个更高级别的张量,其每个组件都由后一个参数的一个组成部分派生:

In [14]: derive_by_array(stc, W)
Out[14]: [a + d, b + e, c + f]

修改

由于现在已经指定参数 M K 是符号,我将添加此部分。

X W 声明为 IndexBase

In [1]: X = IndexedBase("X")

In [2]: W = IndexedBase("W")

In [3]: var("i,j,M,K", integer=True)
Out[3]: (i, j, M, K)

您的表达式是产品 X W 与索引 i j 的总和,表示如下:

In [4]: s = Sum(X[i, j]*W[j], (i, 1, M), (j, 1, K))

In [5]: s
Out[5]: 
  K     M               
 ___   ___              
 ╲     ╲                
  ╲     ╲   W[j]⋅X[i, j]
  ╱     ╱               
 ╱     ╱                
 ‾‾‾   ‾‾‾              
j = 1 i = 1    

现在,人们会派生s.diff(W[j])或使用不同的索引s.diff(W[k]),遗憾的是,这还没有在SymPy中实现。 在github上有一个PR,它会增加对索引对象的派生的支持,但到目前为止还没有合并: https://github.com/sympy/sympy/pull/9314