张量规范化

sympy.combinatorics.tensor_can.canonicalize(g, dummies, msym, *v)[源代码][源代码]

由张量形成的规范张量

参数:
g表示张量的排列
dummies表示虚拟指标的列表

它可以是相同类型的哑指标列表,或者是哑指标列表的列表,每个指标类型对应一个列表;哑指标必须放在自由指标之后,并按逆变、协变顺序排列 [d0, -d0, d1, -d1, …]

msym度规的对称性

它可以是一个整数或一个列表;在第一种情况下,它是哑指标度量的对称性;在第二种情况下,它是每种指标度量的对称性列表。

v : 列表, (base_i, gens_i, n_i, sym_i) 用于类型 \(i\) 的张量列表, (base_i, gens_i, n_i, sym_i) 用于张量类型
base_i, gens_i此类张量的BSGS。

BSGS 在字典序排序下应具有最小的基;如果不是,则尝试获取最小的 BSGS;如果失败,则使用 canonicalize_naive,这要慢得多。

n_i : 类型为 \(i\) 的张量数量。类型张量的数量
sym_i : 在交换类型 \(i\) 的组成部分张量下的对称性。在交换类型组件张量下的对称性
对于 msym 和 sym_i 的情况是
  • None 无对称性

  • 0 通勤

  • 1 反对易

返回:
如果张量为零,则返回0,否则返回数组形式。
表示张量规范形式的排列。

示例

一种具有交换度量的索引类型;

\(A_{a b}\)\(B_{a b}\) 是反对称且对易的

\(T = A_{d0 d1} * B^{d0}{}_{d2} * B^{d2 d1}\)

\(ord = [d0,-d0,d1,-d1,d2,-d2]\) 索引的顺序

g = [1, 3, 0, 5, 4, 2, 6, 7]

\(T_c = 0\)

>>> from sympy.combinatorics.tensor_can import get_symmetric_group_sgs, canonicalize, bsgs_direct_product
>>> from sympy.combinatorics import Permutation
>>> base2a, gens2a = get_symmetric_group_sgs(2, 1)
>>> t0 = (base2a, gens2a, 1, 0)
>>> t1 = (base2a, gens2a, 2, 0)
>>> g = Permutation([1, 3, 0, 5, 4, 2, 6, 7])
>>> canonicalize(g, range(6), 0, t0, t1)
0

toctree 是一个 reStructuredText 指令 ,这是一个非常多功能的标记。指令可以有参数、选项和内容。

\(T_c = -A^{d0 d1} * B_{d0}{}^{d2} * B_{d1 d2}\)

can = [0,2,1,4,3,5,7,6]

>>> t1 = (base2a, gens2a, 2, 1)
>>> canonicalize(g, range(6), 0, t0, t1)
[0, 2, 1, 4, 3, 5, 7, 6]

两种类型的索引 \([a,b,c,d,e,f]\)\([m,n]\),按此顺序,两者都具有交换度量

\(f^{a b c}\) 反对称,交换

\(A_{m a}\) 无对称性,可交换

\(T = f^c{}_{d a} * f^f{}_{e b} * A_m{}^d * A^{m b} * A_n{}^a * A^{n e}\)

ord = [c, f, a, -a, b, -b, d, -d, e, -e, m, -m, n, -n]

g = [0,7,3, 1,9,5, 11,6, 10,4, 13,2, 12,8, 14,15]

规范张量是 \(T_c = -f^{c a b} * f^{f d e} * A^m{}_a * A_{m d} * A^n{}_b * A_{n e}\)

can = [0,2,4, 1,6,8, 10,3, 11,7, 12,5, 13,9, 15,14]

>>> base_f, gens_f = get_symmetric_group_sgs(3, 1)
>>> base1, gens1 = get_symmetric_group_sgs(1)
>>> base_A, gens_A = bsgs_direct_product(base1, gens1, base1, gens1)
>>> t0 = (base_f, gens_f, 2, 0)
>>> t1 = (base_A, gens_A, 4, 0)
>>> dummies = [range(2, 10), range(10, 14)]
>>> g = Permutation([0, 7, 3, 1, 9, 5, 11, 6, 10, 4, 13, 2, 12, 8, 14, 15])
>>> canonicalize(g, dummies, [0, 0], t0, t1)
[0, 2, 4, 1, 6, 8, 10, 3, 11, 7, 12, 5, 13, 9, 15, 14]
sympy.combinatorics.tensor_can.double_coset_can_rep(
dummies,
sym,
b_S,
sgens,
S_transversals,
g,
)[源代码][源代码]

Butler-Portugal 算法用于带有哑指标的张量规范化。

参数:
dummies

每个类型的索引都有一个列表的列表,虚拟索引按逆变、协变顺序排列 [d0, -d0, d1, -d1, …]。

sym

每种类型索引度量的对称性列表。

度规的可能对称性
  • 0 对称

  • 1 反对称

  • None 无对称性

b_S

最小槽对称 BSGS 的基础。

sgens

槽对称 BSGS 的生成器。

S_transversals

槽 BSGS 的横截面。

g

表示张量的排列。

返回:
如果张量为零则返回0,否则返回数组形式。
表示张量规范形式的排列。

注释

带有虚拟索引的张量可以用多种等价的方式表示,通常随着索引数量的增加,等价方式的数量呈指数增长。在没有高效算法的情况下,判断两个具有多个索引的张量是否相等在计算上会变得非常缓慢。

Butler-Portugal 算法 [3] 是一种将张量置于标准形式的高效算法,解决了上述问题。

葡萄牙观察到,张量可以用排列表示,并且在槽和哑元对称性下等价于它的张量类等价于双陪集 \(D*g*S\) (注意:在本文档中,我们使用排列 p, q 的乘法约定 (p*q)(i) = p[q[i]],这与 Permutation 类中使用的约定相反)

使用Butler的算法来找到双陪集的代表,可以找到张量的典范形式。

要查看这种对应关系,设 \(g\) 为数组形式的排列;一个带有索引 \(ind\) 的张量(索引包括逆变和协变索引)可以写成

\(t = T(ind[g[0]], \dots, ind[g[n-1]])\),

其中 \(n = len(ind)\)\(g\) 的大小为 \(n + 2\),最后两个索引用于张量的符号(技巧引自 [4])。

槽对称变换 \(s\) 是对槽 \(t \rightarrow T(ind[(g*s)[0]], \dots, ind[(g*s)[n-1]])\) 进行置换的操作。

一个虚拟的对称变换作用于 \(ind\) \(t \rightarrow T(ind[(d*g)[0]], \dots, ind[(d*g)[n-1]])\)

只对张量在这些对称性下的变换感兴趣,可以用 \(g\) 来表示张量,它按照这种方式变换。

\(g -> d*g*s\),因此它属于陪集 \(D*g*S\),换句话说,它属于由槽和虚拟对称性允许的所有排列的集合。

让我们通过一个例子来解释这些约定。

给定一个张量 \(T^{d3 d2 d1}{}_{d1 d2 d3}\) ,具有槽对称性

\(T^{a0 a1 a2 a3 a4 a5} = -T^{a2 a1 a0 a3 a4 a5}\)

\(T^{a0 a1 a2 a3 a4 a5} = -T^{a4 a1 a2 a3 a0 a5}\)

并且对称度量,找到其等价的张量,该张量在指标排序下是最低的:字典序 \(d1, d2, d3\),然后是逆变指标在协变指标之前;即张量的规范形式。

标准形式是 \(-T^{d1 d2 d3}{}_{d1 d2 d3}\) ,通过 \(T^{a0 a1 a2 a3 a4 a5} = -T^{a2 a1 a0 a3 a4 a5}\) 获得。

要将此问题转换为该函数的输入,请使用以下索引名称顺序(- 表示协变量简写)`d1, -d1, d2, -d2, d3, -d3`

\(T^{d3 d2 d1}{}_{d1 d2 d3}\) 对应于 \(g = [4, 2, 0, 1, 3, 5, 6, 7]\),其中最后两个索引用于符号

\(sgens = [Permutation(0, 2)(6, 7), Permutation(0, 4)(6, 7)]\)

sgens[0] 是槽对称 \(-(0, 2)\) \(T^{a0 a1 a2 a3 a4 a5} = -T^{a2 a1 a0 a3 a4 a5}\)

sgens[1] 是槽对称性 \(-(0, 4)\) \(T^{a0 a1 a2 a3 a4 a5} = -T^{a4 a1 a2 a3 a0 a5}\)

虚拟对称群 D 由强基生成元 \([(0, 1), (2, 3), (4, 5), (0, 2)(1, 3), (0, 4)(1, 5)]\) 生成,其中前三个交换相同指标的协变和逆变位置(d1 <-> -d1),最后两个交换虚拟指标本身(d1 <-> d2)。

虚对称性从左边作用 \(d = [1, 0, 2, 3, 4, 5, 6, 7]\) 交换 \(d1 \leftrightarrow -d1\) \(T^{d3 d2 d1}{}_{d1 d2 d3} == T^{d3 d2}{}_{d1}{}^{d1}{}_{d2 d3}\)

\(g=[4, 2, 0, 1, 3, 5, 6, 7] -> [4, 2, 1, 0, 3, 5, 6, 7] = _af_rmul(d, g)\)\(_af_rmul(g, d)\) 不同。

槽对称性从右边 \(s = [2, 1, 0, 3, 4, 5, 7, 6]\) 交换槽 0 和 2 并改变符号 \(T^{d3 d2 d1}{}_{d1 d2 d3} == -T^{d1 d2 d3}{}_{d1 d2 d3}\)

\(g=[4,2,0,1,3,5,6,7] -> [0, 2, 4, 1, 3, 5, 7, 6] = _af_rmul(g, s)\)

张量为零的例子,与上述相同的槽对称性:\(T^{d2}{}_{d1 d3}{}^{d1 d3}{}_{d2}\)

\(= -T^{d3}{}_{d1 d3}{}^{d1 d2}{}_{d2}\) 在槽对称性 \(-(0,4)\) 下;

\(= T_{d3 d1}{}^{d3}{}^{d1 d2}{}_{d2}\) 在槽对称性 \(-(0,2)\) 下;

\(= T^{d3}{}_{d1 d3}{}^{d1 d2}{}_{d2}\) 对称度量;

\(= 0\) 因为这两行中的张量仅在符号上不同。

双陪集 D*g*S 由排列 \(h = d*g*s\) 组成,对应于等价张量;如果存在两个 \(h\) 除了符号不同外相同,则返回零;否则选择代表张量为按 \([d1, -d1, d2, -d2, d3, -d3]\) 字典顺序排列的张量,即 rep = min(D*g*S) = min([d*g*s for d in D for s in S])

索引是逐一固定的;首先为槽位0选择最低的索引,然后为槽位1选择剩余的最低索引,依此类推。这样做可以得到一个稳定器链

\(S \rightarrow S_{b0} \rightarrow S_{b0,b1} \rightarrow \dots\)\(D \rightarrow D_{p0} \rightarrow D_{p0,p1} \rightarrow \dots\)

其中 [b0, b1, ...] = range(b) 是对称群的一个基;S 的强基 \(b_S\) 是其有序子列表;因此,使用 Schreier-Sims 算法计算一次 S 的强基生成元就足够了;强基生成元的稳定子是稳定子子群的强基生成元。

dbase = [p0, p1, ...] 通常不是按字典顺序排列的,因此每次都必须重新计算强基生成元;然而这很简单,不需要使用 Schreier-Sims 算法来处理 D。

算法维护一个元素表 \((s_i, d_i, h_i)\),其中 \(h_i = d_i \times g \times s_i\) 满足 \(h_i[j] = p_j\) 对于 \(0 \le j < i\),从 \(s_0 = id, d_0 = id, h_0 = g\) 开始。

方程 \(h_0[0] = p_0, h_1[1] = p_1, \dots\) 按此顺序求解,每次选择可能的最小 p_i 值

对于 \(j < i\),有 \(d_i*g*s_i*S_{b_0, \dots, b_{i-1}}*b_j = D_{p_0, \dots, p_{i-1}}*p_j\),因此对于 \(D_{p_0,\dots,p_{i-1}}\) 中的 \(dx\)\(S_{base[0], \dots, base[i-1]}\) 中的 \(sx\),有 \(dx*d_i*g*s_i*sx*b_j = p_j\)

寻找 dx, sx 使得对于 \(j = i\) 这个方程成立;它可以写成 \(s_i*sx*b_j = J, dx*d_i*g*J = p_j\) \(sx*b_j = s_i**-1*J; sx = trace(s_i**-1, S_{b_0,...,b_{i-1}})\) \(dx**-1*p_j = d_i*g*J; dx = trace(d_i*g*J, D_{p_0,...,p_{i-1}})\)

\(s_{i+1} = s_i*trace(s_i**-1*J, S_{b_0,...,b_{i-1}})\) \(d_{i+1} = trace(d_i*g*J, D_{p_0,...,p_{i-1}})**-1*d_i\) \(h_{i+1}*b_i = d_{i+1}*g*s_{i+1}*b_i = p_i\)

\(h_n*b_j = p_j\) 对所有 j 成立,因此 \(h_n\) 是解。

将找到的 \((s, d, h)\) 添加到 TAB1。

在迭代结束时,根据 \(h\) 对 TAB1 进行排序;如果 TAB1 中有两个连续的 \(h\) 仅符号不同,则张量为零,返回 0;如果 TAB1 中有两个连续的 \(h\) 相等,则只保留一个。

然后稳定 \(i\) 下的槽生成器和 \(p_i\) 下的虚拟生成器。

在迭代步骤的末尾,赋值 \(TAB = TAB1\)

在最后,\(TAB\) 包含一个唯一的 \((s, d, h)\),因为张量 \(h\) 的所有槽位都已根据对称性固定为最小值。算法返回 \(h\)

重要的是,槽 BSGS 具有字典序最小基,否则存在一个 \(i\),它不属于槽基,对于该 \(i\)\(p_i\) 仅由虚拟对称性固定,而 \(i\) 不是槽稳定器的固定点,因此 \(p_i\) 通常不是最小值。

该算法与原始算法 [3] 略有不同:

规范形式在字典序上是最小的,并且BSGS在字典序下具有最小的基。相等的张量 \(h\) 从TAB中被消除。

示例

>>> from sympy.combinatorics.permutations import Permutation
>>> from sympy.combinatorics.tensor_can import double_coset_can_rep, get_transversals
>>> gens = [Permutation(x) for x in [[2, 1, 0, 3, 4, 5, 7, 6], [4, 1, 2, 3, 0, 5, 7, 6]]]
>>> base = [0, 2]
>>> g = Permutation([4, 2, 0, 1, 3, 5, 6, 7])
>>> transversals = get_transversals(base, gens)
>>> double_coset_can_rep([list(range(6))], [0], base, gens, transversals, g)
[0, 1, 2, 3, 4, 5, 7, 6]
>>> g = Permutation([4, 1, 3, 0, 5, 2, 6, 7])
>>> double_coset_can_rep([list(range(6))], [0], base, gens, transversals, g)
0
sympy.combinatorics.tensor_can.get_symmetric_group_sgs(n, antisym=False)[源代码][源代码]

返回最小BSGS的基,(反)对称张量的生成元

参数:
n张量的秩
antisym布尔

antisym = False 对称张量 antisym = True 反对称张量

示例

>>> from sympy.combinatorics.tensor_can import get_symmetric_group_sgs
>>> get_symmetric_group_sgs(3)
([0, 1], [(4)(0 1), (4)(1 2)])
sympy.combinatorics.tensor_can.bsgs_direct_product(
base1,
gens1,
base2,
gens2,
signed=True,
)[源代码][源代码]

两个BSGS的直积。

参数:
基础1第一个BSGS的基础。
gens1第一个BSGS的强生成序列。
base2, gens2同样适用于第二个BSGS。
已签名带符号排列的标志。

示例

>>> from sympy.combinatorics.tensor_can import (get_symmetric_group_sgs, bsgs_direct_product)
>>> base1, gens1 = get_symmetric_group_sgs(1)
>>> base2, gens2 = get_symmetric_group_sgs(2)
>>> bsgs_direct_product(base1, gens1, base2, gens2)
([1], [(4)(1 2)])