.. _cn_api_paddle_einsum:

einsum
------

.. py:function:: paddle.einsum(equation, *operands)

该函数用于对一组输入 Tensor 进行 Einstein 求和，**该函数目前仅适用于动态图**。

Einstein 求和是一种采用 Einstein 标记法描述的 Tensor 求和，输入单个或多个 Tensor，输出单个 Tensor。

如下的 Tensor 操作或运算均可视为 Einstein 求和的特例

    - 单操作数
        - 迹：trace
        - 对角元：diagonal
        - 转置：transpose
        - 求和：sum
    - 双操作数
        - 内积：dot
        - 外积：outer
        - 广播乘积：mul，*
        - 矩阵乘：matmul
        - 批量矩阵乘：bmm
    - 多操作数
        - 广播乘积：mul，*
        - 多矩阵乘：A.matmul(B).matmul(C)

**关于求和标记的约定**

    - 维度分量下标：Tensor 的维度分量下标使用英文字母表示，不区分大小写，如'ijk'表示 Tensor 维度分量为 i,j,k
    - 下标对应输入操作数：维度下标以`,`分段，按顺序 1-1 对应输入操作数
    - 广播维度：省略号`...`表示维度的广播分量，例如，'i...j'表示首末分量除外的维度需进行广播对齐
    - 自由标和哑标：输入标记中仅出现一次的下标为自由标，重复出现的下标为哑标，哑标对应的维度分量将被规约消去
    - 输出：输出 Tensor 的维度分量既可由输入标记自动推导，也可以用输出标记定制化
        - 自动推导输出
            - 广播维度分量位于维度向量高维位置，自由标维度分量按字母顺序排序，位于维度向量低纬位置，哑标维度分量不输出
        - 定制化输出
            - 维度标记中`->`右侧为输出标记
            - 若输出包含广播维度，则输出标记需包含`...`
            - 输出标记为空时，对输出进行全量求和，返回该标量
            - 输出不能包含输入标记中未出现的下标
            - 输出下标不可以重复出现
            - 哑标出现在输出标记中则自动提升为自由标
            - 输出标记中未出现的自由标被降为哑标
    - 例子
        - '...ij, ...jk'，该标记中 i,k 为自由标，j 为哑标，输出维度'...ik'
        - 'ij -> i'，i 为自由标，j 为哑标
        - '...ij, ...jk -> ...ijk'，i,j,k 均为自由标
        - '...ij, ...jk -> ij'，若输入 Tensor 中的广播维度不为空，则该标记为无效标记

**求和规则**

Einsum 求和过程理论上等价于如下四步，但实现中实际执行的步骤会有差异。

    - 第一步，维度对齐：将所有标记按字母序排序，按照标记顺序将输入 Tensor 逐一转置、补齐维度，使得处理后的所有 Tensor 其维度标记保持一致
    - 第二步，广播乘积：以维度下标为索引进行广播点乘
    - 第三步，维度规约：将哑标对应的维度分量求和消除
    - 第四步，转置输出：若存在输出标记，则按标记进行转置，否则按广播维度+字母序自由标的顺序转置，返回转之后的 Tensor 作为输出

**关于 trace 和 diagonal 的标记约定（待实现功能）**

    - 在单个输入 Tensor 的标记中重复出现的下标称为对角标，对角标对应的坐标轴需进行对角化操作，如'i...i'表示需对首尾坐标轴进行对角化
    - 若无输出标记或输出标记中不包含对角标，则对角标对应维度规约为标量，相应维度取消，等价于 trace 操作
    - 若输出标记中包含对角标，则保留对角标维度，等价于 diagonal 操作

参数
:::::

    - **equation** (str)：求和标记
    - **operands** (Tensor, [Tensor, ...])：输入 Tensor

返回
:::::

    Tensor：输出 Tensor

代码示例
:::::::::

COPY-FROM: paddle.einsum
