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

参数大小向量的python符号求和与微分,python,sympy,Python,Sympy,这个问题涉及在Symphy中迭代和微分参数大小的向量变量。他们没有得到,也永远不会得到 例如,采用以下简单设置: 我有M个向量x,每个向量的维数都是K。 我有一个权重向量w,也是维数K。 (M和K永远不会有值,它们只会保持M和K) 我的函数在x向量上求和,然后用权重w对和执行点积: f = dot(sum(x),w) 函数的导数w.r.t w_i应该是和(x_i),i=1..M 我该如何用sympy编码?求和和和微分 编辑 由于Francesco的伟大回答清楚地表明,这目前是不可能的,我正在

这个问题涉及在Symphy中迭代和微分参数大小的向量变量。他们没有得到,也永远不会得到

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

我有M个向量x,每个向量的维数都是K。 我有一个权重向量w,也是维数K。 (M和K永远不会有值,它们只会保持M和K)

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

f = dot(sum(x),w)
函数的导数w.r.t w_i应该是和(x_i),i=1..M

我该如何用sympy编码?求和和和微分


编辑 由于Francesco的伟大回答清楚地表明,这目前是不可能的,我正在寻找一个解决办法。 换句话说:是否有可能:

  • 定义固定尺寸(例如,M=100,K=200)
  • 在sympy中定义我的函数f
  • 计算f.diff(w_1)、f.diff(w_2)等
  • 从输出自动推断出f.diff(w_i)的通用形式?(通过收集术语或类似的方式)
  • 我已经在手动执行第4步了,将导数分解为更简单的术语,使其更具可读性,然后寻找“模式”。为了可读性,我使用了以下代码:

    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)
    

    您可以使用SymPy 1.0版中引入的新张量数组模块

    我假设K和M参数是数字,而不是符号(否则我建议使用sympy.tensor.index)

    考虑这个例子: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])
    
    现在创建一个具有三个索引的乘积张量(X为2,W为1):

    让我们对第二个和第三个索引求和(Python表示法中的索引1和2,因为索引从零开始),这相当于您所称的点积:

    相同的表达式可以通过以下公式求和:

    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
    
    对于数组的导数,可以使用派生数组(…)。它将创建一个更高秩的张量,其每个分量都由后一个参数的分量派生:

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

    因为现在已经指定参数M和K是符号的,所以我将添加这一部分

    将X和W声明为索引数据库:

    您的表达式是指数i和j的乘积X W之和,表示如下:

    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,它将增加对索引对象派生的支持,但到目前为止尚未合并:

    感谢您的详细回答;但是,实际上,我的K和M参数不是数字;那是我的困难。我编辑了原始问题来反映这一点。哇,谢谢你提供了两个详细的答案。这真是帮了大忙;非常感谢你。在你的回答之后,我现在更新了我的问题。但我不敢问第三个好答案……:)您是否尝试过在步骤4中按数组()派生_?从未听说过。我试试看。再次感谢!
    In [14]: derive_by_array(stc, W)
    Out[14]: [a + d, b + e, c + f]
    
    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)
    
    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