SymPy 1.13 中文文档(十)
置换群
原文:
docs.sympy.org/latest/modules/combinatorics/perm_groups.html
class sympy.combinatorics.perm_groups.PermutationGroup(*args, dups=True, **kwargs)
定义置换群的类。
解释
PermutationGroup([p1, p2, ..., pn]) 返回由置换列表生成的置换群。如果希望装饰与置换索引相关的元素,则可以将此群提供给Polyhedron。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> from sympy.combinatorics import Polyhedron
定义作用于(2 \times 2)魔方的前、右和底面的置换:
>>> F = Permutation(2, 19, 21, 8)(3, 17, 20, 10)(4, 6, 7, 5)
>>> R = Permutation(1, 5, 21, 14)(3, 7, 23, 12)(8, 10, 11, 9)
>>> D = Permutation(6, 18, 14, 10)(7, 19, 15, 11)(20, 22, 23, 21)
将它们作为置换传递给PermutationGroup:
>>> G = PermutationGroup(F, R, D)
>>> G.order()
3674160
可以将此群提供给Polyhedron以跟踪正在移动的对象。在那里给出了一个涉及(2 \times 2)魔方的示例,但这里是一个简单的演示:
>>> a = Permutation(2, 1)
>>> b = Permutation(1, 0)
>>> G = PermutationGroup(a, b)
>>> P = Polyhedron(list('ABC'), pgroup=G)
>>> P.corners
(A, B, C)
>>> P.rotate(0) # apply permutation 0
>>> P.corners
(A, C, B)
>>> P.reset()
>>> P.corners
(A, B, C)
或者可以将置换作为选定置换的乘积,并直接将它们应用于可迭代对象:
>>> P10 = G.make_perm([0, 1])
>>> P10('ABC')
['C', 'A', 'B']
参见
sympy.combinatorics.polyhedron.Polyhedron, sympy.combinatorics.permutations.Permutation
参考文献
[R62]
Holt, D., Eick, B., O’Brien, E. “计算群论手册”
[R63]
Seress, A. “置换群算法”
[R64]
en.wikipedia.org/wiki/Schreier_vector
[R65]
en.wikipedia.org/wiki/Nielsen_transformation#Product_replacement_algorithm
[R66]
Frank Celler, Charles R.Leedham-Green, Scott H.Murray, Alice C.Niemeyer, 和 E.A.O’Brien. “生成有限群的随机元素”
[R67]
en.wikipedia.org/wiki/Block_%28permutation_group_theory%29
[R68]
algorithmist.com/wiki/Union_find
[R69]
en.wikipedia.org/wiki/Multiply_transitive_group#Multiply_transitive_groups
[R70]
en.wikipedia.org/wiki/Center_%28group_theory%29
__contains__(i)
如果i包含在PermutationGroup中,则返回True。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> p = Permutation(1, 2, 3)
>>> Permutation(3) in PermutationGroup(p)
True
__mul__(other)
返回两个置换群的直积作为一个置换群。
解释
这个实现通过移动第二个群生成器的索引集来实现直积:因此,如果我们有G作用于n1个点,H作用于n2个点,那么G*H作用于n1 + n2个点。
示例
>>> from sympy.combinatorics.named_groups import CyclicGroup
>>> G = CyclicGroup(5)
>>> H = G*G
>>> H
PermutationGroup([
(9)(0 1 2 3 4),
(5 6 7 8 9)])
>>> H.order()
25
static __new__(cls, *args, dups=True, **kwargs)
默认构造函数。接受循环和置换形式。除非dups关键字为False,否则会删除重复项。
__weakref__
对对象的弱引用列表
_coset_representative(g, H)
返回由self.coset_transversal(H)计算的 Hg 的代表。
classmethod _distinct_primes_lemma(primes)
子例程用于测试是否只有一个循环群的顺序。
_eval_is_alt_sym_monte_carlo(eps=0.05, perms=None)
使用蒙特卡罗算法进行测试。
参数:
eps:浮点数,可选
错误的判定标准是
False返回。
perms:列表[置换],可选
如果明确给出,它会对给定的测试候选进行测试。
如果
None,则随机计算N_eps并从群的样本中选择N_eps个置换。
另见。
_check_cycles_alt_sym
_eval_is_alt_sym_naive(only_sym=False, only_alt=False)
使用群的顺序的朴素测试。
_p_elements_group(p)
对于阿贝尔 p-群,返回由所有 p 阶元素(和单位元素)组成的子群。
_random_pr_init(r, n, _random_prec_n=None)
初始化产品替换算法的随机生成器。
说明
该实现使用了 Leedham-Green 修改过的原始产品替换算法,详见[1]第 69-71 页;另请参阅[2]第 27-29 页对原始产品替换算法的详细理论分析,以及[4]。
产品替换算法用于生成群( G )的随机、均匀分布的元素。对于初始化_random_pr_init,创建一个包含(\max{r, |S|})个群生成器的列表R作为属性G._random_gens,如有必要重复( S )的元素,并将( G )的单位元素附加到R - 我们将最后一个元素称为累加器。然后调用函数random_pr() n次,随机化列表R,同时保持由R生成( G )。random_pr()函数本身从R的所有元素中选取两个随机元素g, h(除了累加器),并用({gh, g(~h), hg, (~h)g})中随机选择的元素替换g。然后累加器乘以被替换的g。random_pr()然后返回累加器的新值。
返回的元素最终(对于足够大的n)将在( G )中均匀分布([5])。然而,对于实际目的,建议在[1]中使用n = 50, r = 11。
注释
此函数具有副作用:它改变了属性self._random_gens。
另见。
random_pr
_sylow_alt_sym(p)
返回对称或交替群的 p-希罗亚子群。
说明
该算法在[1]章节 4 练习 4 中有提示。
对于 Sym(n),其中 n = p^i,其思想如下。将区间[0..n-1]分成 p 个相等的部分,每部分长度为 p^(i-1):[0..p^(i-1)-1],[p^(i-1)..2*p^(i-1)-1]…[(p-1)*p^(i-1)..p^i-1]。找到 Sym(p^(i-1))的 p-Sylow 子群(作为self的子群)作用于每个部分。称这些子群为 P_1,P_2…P_p。可以通过将“移位”置换应用到它们上,即将[0..p^(i-1)-1]映射到第二部分(其他部分通过多次移位获得)。这些置换与 P_1 的生成器的并集是self的 p-Sylow 子群。
对于 n 不等于 p 的幂的情况,按照 n 在 p 进制中的表示方式对[0..n-1]进行分区。例如,对于 p=2 和 n=11,11 = 2³ + 2² + 1,所以分区是[[0..7],[8..9],{10}]。要生成 p-Sylow 子群,取每个部分的生成器的并集。对于上述示例,来自第一个部分的{(0 1),(0 2)(1 3),(0 4),(1 5)(2 7)},来自第二个部分的{(8 9)},第三个部分没有生成器。总共有 4 个生成器,它们生成的子群是 p-Sylow。
交替群在 p=2 时被视为相同,除非(p=2)。在这种情况下,应为适当的 s(部分的起始点),为每个部分添加(0 1)(s s+1)。
另请参阅
sylow_subgroup,is_alt_sym
_union_find_merge(first, second, ranks, parents, not_rep)
合并两个类在并查集数据结构中。
说明
在 Atkinson 算法的实现中使用,如[1]建议的,第 83-87 页。类合并过程使用了按秩合并作为优化。([7])
注意
此函数有副作用:类代表列表parents,类大小列表ranks和非代表元素列表not_rep由于类合并而发生改变。
另请参阅
minimal_block,_union_find_rep
参考文献
[R71]
Holt, D., Eick, B., O’Brien, E. 的“计算群论手册”。
[R77]
algorithmist.com/wiki/Union_find的解释。
_union_find_rep(num, parents)
在并查集数据结构中查找类的代表。
解释
在 Atkinson 算法的实现中使用,如[1]建议的,第 83-87 页。在找到num所属类的代表后,进行路径压缩以优化([7])。
注意
此函数有副作用:类代表列表parents由于路径压缩而被更改。
另请参阅
minimal_block, _union_find_merge
参考文献
[R73]
Holt, D., Eick, B., O’Brien, E. “计算群论手册”
[R79]
algorithmist.com/wiki/Union_find
_verify(K, phi, z, alpha)
返回在生成器 pygens`_h` that are mapped to ``H.generators 下由 phi 给出的关系列表 rels,以便给定 K 在 gens_h 的子集上的有限表示 <gens_h | rels_k + rels> 是 H 的有限表示。
解释
H 应由 K.generators 和 z(一个单一的生成器)的并集生成,并且 H.stabilizer(alpha) == K;phi 是从自由群到包含 H 的置换群的规范注入。
算法见 [1],第六章。
示例
>>> from sympy.combinatorics import free_group, Permutation, PermutationGroup
>>> from sympy.combinatorics.homomorphisms import homomorphism
>>> from sympy.combinatorics.fp_groups import FpGroup
>>> H = PermutationGroup(Permutation(0, 2), Permutation (1, 5))
>>> K = PermutationGroup(Permutation(5)(0, 2))
>>> F = free_group("x_0 x_1")[0]
>>> gens = F.generators
>>> phi = homomorphism(F, H, F.generators, H.generators)
>>> rels_k = [gens[0]**2] # relators for presentation of K
>>> z= Permutation(1, 5)
>>> check, rels_h = H._verify(K, phi, z, 1)
>>> check
True
>>> rels = rels_k + rels_h
>>> G = FpGroup(F, rels) # presentation of H
>>> G.order() == H.order()
True
另请参阅
strong_presentation, presentation, stabilizer
abelian_invariants()
返回给定群的阿贝尔不变量。设 G 是一个非平凡有限阿贝尔群。那么 G 同构于有限多个非平凡循环群的素数幂次序的直积。
解释
出现为因子次序的素数幂次唯一确定了 G。更确切地说,出现在 G 的任何此类分解的因子次序中的素数,正好是整除 |G| 的素数,并且对于任何这样的素数 p,如果在 G 的一种这样的分解中是 p^{t_1} >= p^{t_2} >= ... p^{t_r} 的因子次序,那么在 G 的任何这样的分解中是 p^{t_1} >= p^{t_2} >= ... p^{t_r}。
对于非平凡群 G,对所有整除 |G| 的素数取唯一确定的整数 p^{t_1} >= p^{t_2} >= ... p^{t_r},如 ([14], p. 542) 所建议的,称为其不变量。
注意事项
我们采用的惯例是一个平凡群的不变量为 []。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1])
>>> b = Permutation([1, 0, 2])
>>> G = PermutationGroup([a, b])
>>> G.abelian_invariants()
[2]
>>> from sympy.combinatorics import CyclicGroup
>>> G = CyclicGroup(7)
>>> G.abelian_invariants()
[7]
property base
返回 Schreier-Sims 算法的基础。
解释
对于置换群 (G),一个基是一组点的序列 (B = (b_1, b_2, \dots, b_k)),使得除单位元素外,G 中没有元素能够固定所有 B 中的点。基和强生成集的概念及其应用在 [1],第 87-89 页和 [2],第 55-57 页中有详细讨论。
另一种思考 B 的方法是,它提供了包含非单位置换的稳定子余类的指标。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> G = PermutationGroup([Permutation(0, 1, 3)(2, 4)])
>>> G.base
[0, 2]
另请参阅
strong_gens, basic_transversals, basic_orbits, basic_stabilizers
baseswap(base, strong_gens, pos, randomized=False, transversals=None, basic_orbits=None, strong_gens_distr=None)
交换基和强生成集中的两个连续基点。
参数:
基础,强生成集
基础和强生成集。
pos
执行交换的位置。
随机化
随机化版本与确定性版本之间的切换。
横断面
如果已知基轨道的横断面。
基本轨道
如果已知的基本轨道。
强生成集分布
已知的强生成器由基本稳定子分布。
返回:
(base, strong_gens)
base是新基,strong_gens是相对于它的生成集。
解释
如果群 (G) 的一个基由 ((b_1, b_2, \dots, b_k)) 给出,则此函数返回一个基 ((b_1, b_2, \dots, b_{i+1}, b_i, \dots, b_k)),其中 (i) 由 pos 给出,并且相对于该基的一个强生成集。原始基和强生成集不会被修改。
随机化版本(默认)为拉斯维加斯类型。
示例
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.testutil import _verify_bsgs
>>> from sympy.combinatorics.perm_groups import PermutationGroup
>>> S = SymmetricGroup(4)
>>> S.schreier_sims()
>>> S.base
[0, 1, 2]
>>> base, gens = S.baseswap(S.base, S.strong_gens, 1, randomized=False)
>>> base, gens
([0, 2, 1],
[(0 1 2 3), (3)(0 1), (1 3 2),
(2 3), (1 3)])
检查该基和生成集是否为 BSGS。
>>> S1 = PermutationGroup(gens)
>>> _verify_bsgs(S1, base, gens)
True
注意事项
算法的确定性版本在 [1] 第 102-103 页讨论;随机化版本在 [1] 第 103 页和 [2] 第 98 页讨论。这是拉斯维加斯类型。注意在 [1] 的伪代码和 BASESWAP 的讨论中有一个错误:伪代码的第 3 行中,(|\beta_{i+1}^{\left\langle T\right\rangle}|) 应替换为 (|\beta_{i}^{\left\langle T\right\rangle}|),算法的讨论中也是如此。
参见
property basic_orbits
返回相对于基和强生成集的基本轨道。
解释
如果 ((b_1, b_2, \dots, b_k)) 是群 (G) 的一个基,并且 (G^{(i)} = G_{b_1, b_2, \dots, b_{i-1}}) 是第 i 个基本稳定子(使得 (G^{(1)} = G)),则相对于此基的第 i 个基本轨道是 (b_i) 在 (G^{(i)}) 下的轨道。详见 [1] 第 87-89 页了解更多信息。
示例
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> S = SymmetricGroup(4)
>>> S.basic_orbits
[[0, 1, 2, 3], [1, 2, 3], [2, 3]]
参见
base,strong_gens,basic_transversals,basic_stabilizers
property basic_stabilizers
返回基于基和强生成集的稳定子链。
解释
相对于基 ((b_1, b_2, \dots, b_k)),第 i 个基本稳定子 (G^{(i)}) 是 (G_{b_1, b_2, \dots, b_{i-1}})。更多信息见 [1],第 87-89 页。
示例
>>> from sympy.combinatorics.named_groups import AlternatingGroup
>>> A = AlternatingGroup(4)
>>> A.schreier_sims()
>>> A.base
[0, 1]
>>> for g in A.basic_stabilizers:
... print(g)
...
PermutationGroup([
(3)(0 1 2),
(1 2 3)])
PermutationGroup([
(1 2 3)])
另见
base,strong_gens,basic_orbits,basic_transversals
property basic_transversals
返回基于基和强生成集的基本横截面。
解释
基本横截面是基本轨道的横截面。它们被提供为字典列表,每个字典具有键 - 一个基本轨道的元素,和值 - 相应的横截面元素。更多信息见 [1],第 87-89 页。
示例
>>> from sympy.combinatorics.named_groups import AlternatingGroup
>>> A = AlternatingGroup(4)
>>> A.basic_transversals
[{0: (3), 1: (3)(0 1 2), 2: (3)(0 2 1), 3: (0 3 1)}, {1: (3), 2: (1 2 3), 3: (1 3 2)}]
另见
strong_gens,base,basic_orbits,basic_stabilizers
center()
返回置换群的中心。
解释
对于群 (G) 的中心定义为 (Z(G) = {z\in G | \forall g\in G, zg = gz }),即与 (G) 中所有元素都可交换的 (G) 的元素的集合。它等于 (G) 在 (G) 中的中心化子,并且自然地是 (G) 的一个子群([9])。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> D = DihedralGroup(4)
>>> G = D.center()
>>> G.order()
2
注意事项
这是一个简单的应用 .centralizer() 的简单实现。
另见
centralizer
centralizer(other)
返回群/集合/元素的中心化子。
参数:
其他
置换群/置换列表/单一置换
解释:
集合 S 在群 G 内的中心化子是与 S 中所有元素都可交换的 G 中的元素集:
`C_G(S) = \{ g \in G | gs = sg \forall s \in S\}` ([10])
通常,S 是 G 的子集,但如果 G 是全置换群的真子群,则允许 S 中有元素在 G 外。
它自然是 G 的子群;置换群的中心化子等于该群任何一组生成元的中心化子,因为与生成元可交换的元素也与生成元的任何乘积可交换。
示例
>>> from sympy.combinatorics.named_groups import (SymmetricGroup,
... CyclicGroup)
>>> S = SymmetricGroup(6)
>>> C = CyclicGroup(6)
>>> H = S.centralizer(C)
>>> H.is_subgroup(C)
True
注意:
实现是使用特定基础对群 G 进行 .subgroup_search() 应用的。
参见:
subgroup_search
commutator(G, H)
返回两个子群的对易子。
解释:
对于置换群 K 和子群 G, H,G 和 H 的对易子被定义为所有对易子 ([g, h] = hgh^{-1}g^{-1}) 生成的群。它自然是 K 的子群 ([1], p.27)。
示例:
>>> from sympy.combinatorics.named_groups import (SymmetricGroup,
... AlternatingGroup)
>>> S = SymmetricGroup(5)
>>> A = AlternatingGroup(5)
>>> G = S.commutator(S, A)
>>> G.is_subgroup(A)
True
注意:
两个子群 (H, G) 的对易子等于所有生成元的对易子的正规闭包,即对 (H) 的生成元 (h) 和 (G) 的生成元 (g),即 (hgh^{-1}g^{-1}) ([1], p.28)
参见:
derived_subgroup
composition_series()
以列表形式返回群的组成系列。
解释:
对于群 (G) 的组成系列被定义为一个次正规系列 (G = H_0 > H_1 > H_2 \ldots)。组成系列是一个最长长度的次正规系列,每个因子群 (H(i+1) / H(i)) 都是简单的。
算法工作如下:从派生系列开始,想法是填补 (G = der[i]) 和 (H = der[i+1]) 之间的空白,对于每个 (i) 独立地。由于阿贝尔群 (G/H) 的所有子群都是正规的,因此第一步是将生成元 (g) 加入到生成元 (H) 中。
形成的因子群一般不是简单的。每个群是从前一个群 (H) 添加一个生成元 (g) 而得到的,如果前一个群用 (H) 表示,则下一个群 (K) 是由 (g) 和 (H) 生成的。因子群 (K/H) 是循环的,其阶数为 (K.order()//G.order()),然后通过 (g) 和 (H) 的幂来扩展这个系列。然后将形成的系列前置到已存在的系列。
示例:
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.named_groups import CyclicGroup
>>> S = SymmetricGroup(12)
>>> G = S.sylow_subgroup(2)
>>> C = G.composition_series()
>>> [H.order() for H in C]
[1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1]
>>> G = S.sylow_subgroup(3)
>>> C = G.composition_series()
>>> [H.order() for H in C]
[243, 81, 27, 9, 3, 1]
>>> G = CyclicGroup(12)
>>> C = G.composition_series()
>>> [H.order() for H in C]
[12, 6, 3, 1]
conjugacy_class(x)
返回群中一个元素的共轭类。
解释
在群 G 中元素 g 的共轭类是与 g 共轭的元素 x 的集合,即对于这样的 x,(x = hgh^{-1})。
g = xax^{-1}
对于G中的某些a。
注意共轭是一种等价关系,因此共轭类是G的分区。要获得群的所有共轭类的列表,请使用 conjugacy_classes()方法。
在置换群中,每个共轭类对应于特定的cycle structure:例如,在S_3中,共轭类是:
- 单位类,
{()}- 所有换位对,
{(1 2), (1 3), (2 3)}- 所有 3-循环,
{(1 2 3), (1 3 2)}
例子
>>> from sympy.combinatorics import Permutation, SymmetricGroup
>>> S3 = SymmetricGroup(3)
>>> S3.conjugacy_class(Permutation(0, 1, 2))
{(0 1 2), (0 2 1)}
注意
该过程通过找到元素在G下共轭的轨道直接计算共轭类。这种算法仅适用于相对较小阶的置换群,但在这方面类似于 orbit()函数本身。
conjugacy_classes()
返回群的共轭类。
解释
如在.conjugacy_class()函数的文档中描述的那样,共轭是群G上的等价关系,它将元素集合划分为共轭类。此方法返回群G的所有这些共轭类的列表。
例子
>>> from sympy.combinatorics import SymmetricGroup
>>> SymmetricGroup(3).conjugacy_classes()
[{(2)}, {(0 1 2), (0 2 1)}, {(0 2), (1 2), (2)(0 1)}]
contains(g, strict=True)
测试排列g是否属于自身G。
解释
如果g是G的元素,则它可以写成从G的稳定子群的陪集中抽取因子的乘积。要查看g是否是定义群的实际生成元之一,请使用G.has(g)。
如果strict不为True,则如果需要,将调整g的大小以匹配self中的置换大小。
例子
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation(1, 2)
>>> b = Permutation(2, 3, 1)
>>> G = PermutationGroup(a, b, degree=5)
>>> G.contains(G[0]) # trivial check
True
>>> elem = Permutation([[2, 3]], size=5)
>>> G.contains(elem)
True
>>> G.contains(Permutation(4)(0, 1, 2, 3))
False
如果 strict 为 False,则将调整置换,如果需要:
>>> H = PermutationGroup(Permutation(5))
>>> H.contains(Permutation(3))
False
>>> H.contains(Permutation(3), strict=False)
True
测试给定置换是否存在于群中:
>>> elem in G.generators
False
>>> G.has(elem)
False
另见
coset_factor, sympy.core.basic.Basic.has, __contains__
coset_factor(g, factor_index=False)
返回G的(自身的)g的陪集因子分解。
解释
如果g是G的元素,则它可以写成从 Schreier-Sims 陪集分解中抽取的置换的乘积,
返回f中的排列是那些其乘积给出g的排列:g = f[n]*...f[1]*f[0],其中n = len(B)且B = G.base。f[i]是self._basic_orbits[i]中的置换之一。
如果factor_index==True,返回元组[b[0],..,b[n]],其中b[i]属于self._basic_orbits[i]
例子
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation(0, 1, 3, 7, 6, 4)(2, 5)
>>> b = Permutation(0, 1, 3, 2)(4, 5, 7, 6)
>>> G = PermutationGroup([a, b])
定义g:
>>> g = Permutation(7)(1, 2, 4)(3, 6, 5)
确认它是G的一个元素:
>>> G.contains(g)
True
因此,它可以写成从u中抽取的因子(最多 3 个)的乘积。请参见下面,使用了来自u1和u2以及单位置换的因子:
>>> f = G.coset_factor(g)
>>> f[2]*f[1]*f[0] == g
True
>>> f1 = G.coset_factor(g, True); f1
[0, 4, 4]
>>> tr = G.basic_transversals
>>> f[0] == tr[0][f1[0]]
True
如果g不是G的元素,则返回[]:
>>> c = Permutation(5, 6, 7)
>>> G.coset_factor(c)
[]
另见
sympy.combinatorics.util._strip
coset_rank(g)
使用 Schreier-Sims 表示排名。
解释
g的陪集秩是它在按字典顺序列出的陪集分解中出现的顺序号。
排序与G.generate(method=’coset’)中的相同。如果g不属于该组,则返回 None。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation(0, 1, 3, 7, 6, 4)(2, 5)
>>> b = Permutation(0, 1, 3, 2)(4, 5, 7, 6)
>>> G = PermutationGroup([a, b])
>>> c = Permutation(7)(2, 4)(3, 5)
>>> G.coset_rank(c)
16
>>> G.coset_unrank(16)
(7)(2 4)(3 5)
参见
coset_factor
coset_table(H)
以列表形式返回自身在 H 中的标准化(右)陪集表。
coset_transversal(H)
使用[1]中描述的第二种方法,返回群self在其子群H的右陪集的横截面。
coset_unrank(rank, af=False)
使用 Schreier-Sims 表示法进行unrank操作
如果 0 <= rank < order,则coset_unrank是coset_rank的反向操作;否则返回 None。
property degree
返回群中置换的大小。
解释
组合中的置换数量由len(group)给出;可以由该组生成的置换数量由group.order()给出。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([1, 0, 2])
>>> G = PermutationGroup([a])
>>> G.degree
3
>>> len(G)
1
>>> G.order()
2
>>> list(G.generate())
[(2), (2)(0 1)]
参见
order
derived_series()
返回群的衍生系列。
返回:
包含衍生成员的置换群列表
按照(G = G_0, G_1, G_2, \ldots)的顺序。
解释
对于群(G)的衍生系列定义为(G = G_0 > G_1 > G_2 > \ldots),其中(G_i = [G_{i-1}, G_{i-1}]),即(G_i)是(G_{i-1})的衍生子群,对于(i\in\mathbb{N})。当存在某个(k\in\mathbb{N}),使得(G_k = G_{k-1})时,系列终止。
示例
>>> from sympy.combinatorics.named_groups import (SymmetricGroup,
... AlternatingGroup, DihedralGroup)
>>> A = AlternatingGroup(5)
>>> len(A.derived_series())
1
>>> S = SymmetricGroup(4)
>>> len(S.derived_series())
4
>>> S.derived_series()[1].is_subgroup(AlternatingGroup(4))
True
>>> S.derived_series()[2].is_subgroup(DihedralGroup(2))
True
参见
derived_subgroup
derived_subgroup()
计算衍生子群。
解释
衍生子群或交换子群是由所有交换子([g, h] = hgh^{-1}g^{-1})生成的群;它等于生成器的交换子集的正规闭包([1],p.28,[11])。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([1, 0, 2, 4, 3])
>>> b = Permutation([0, 1, 3, 2, 4])
>>> G = PermutationGroup([a, b])
>>> C = G.derived_subgroup()
>>> list(C.generate(af=True))
[[0, 1, 2, 3, 4], [0, 1, 3, 4, 2], [0, 1, 4, 2, 3]]
参见
derived_series
property elements
以列表形式返回置换群的所有元素
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> p = PermutationGroup(Permutation(1, 3), Permutation(1, 2))
>>> p.elements
[(3), (3)(1 2), (1 3), (2 3), (1 2 3), (1 3 2)]
equals(other)
如果由群中元素生成的置换群相同,则返回True,即它们表示同一个置换群。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> p = Permutation(0, 1, 2, 3, 4, 5)
>>> G = PermutationGroup([p, p**2])
>>> H = PermutationGroup([p**2, p])
>>> G.generators == H.generators
False
>>> G.equals(H)
True
generate(method='coset', af=False)
返回迭代器以生成群的元素。
解释
使用这些方法之一进行迭代:
method='coset' using the Schreier-Sims coset representation
method='dimino' using the Dimino method
如果af = True,则产生置换的数组形式
示例
>>> from sympy.combinatorics import PermutationGroup
>>> from sympy.combinatorics.polyhedron import tetrahedron
在四面体对象中给出的置换群也是真实的群:
>>> G = tetrahedron.pgroup
>>> G.is_group
True
甚至四面体 pgroup 中生成的置换群(甚至前两个)也是一个适当的群:
>>> H = PermutationGroup(G[0], G[1])
>>> J = PermutationGroup(list(H.generate())); J
PermutationGroup([
(0 1)(2 3),
(1 2 3),
(1 3 2),
(0 3 1),
(0 2 3),
(0 3)(1 2),
(0 1 3),
(3)(0 2 1),
(0 3 2),
(3)(0 1 2),
(0 2)(1 3)])
>>> _.is_group
True
generate_dimino(af=False)
使用 Dimino 算法生成群元素。
如果af == True,则产生置换的数组形式。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1, 3])
>>> b = Permutation([0, 2, 3, 1])
>>> g = PermutationGroup([a, b])
>>> list(g.generate_dimino(af=True))
[[0, 1, 2, 3], [0, 2, 1, 3], [0, 2, 3, 1],
[0, 1, 3, 2], [0, 3, 2, 1], [0, 3, 1, 2]]
参考文献
[R75]
计算代数系统中排列群的各种算法的实现:AXIOM,N.J. Doye,M.Sc. Thesis
generate_schreier_sims(af=False)
使用 Schreier-Sims 表示法按照coset_rank顺序生成群元素
如果 af = True,则返回置换的数组形式。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1, 3])
>>> b = Permutation([0, 2, 3, 1])
>>> g = PermutationGroup([a, b])
>>> list(g.generate_schreier_sims(af=True))
[[0, 1, 2, 3], [0, 2, 1, 3], [0, 3, 2, 1],
[0, 1, 3, 2], [0, 2, 3, 1], [0, 3, 1, 2]]
generator_product(g, original=False)
返回强生成器列表 ([s1, \dots, sn]),使得 (g = sn \times \dots \times s1)。如果 original=True,则只包含原始群生成器的列表。
property generators
返回群的生成元。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1])
>>> b = Permutation([1, 0, 2])
>>> G = PermutationGroup([a, b])
>>> G.generators
[(1 2), (2)(0 1)]
property identity
返回置换群的单位元素。
index(H)
返回置换群的索引。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation(1,2,3)
>>> b =Permutation(3)
>>> G = PermutationGroup([a])
>>> H = PermutationGroup([b])
>>> G.index(H)
3
property is_abelian
测试群是否是阿贝尔的。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1])
>>> b = Permutation([1, 0, 2])
>>> G = PermutationGroup([a, b])
>>> G.is_abelian
False
>>> a = Permutation([0, 2, 1])
>>> G = PermutationGroup([a])
>>> G.is_abelian
True
is_alt_sym(eps=0.05, _random_prec=None)
对于度数大于等于 8 的对称/交替群进行蒙特卡罗测试。
解释
更具体地说,这是一个单侧蒙特卡罗测试,如果答案为 True(即,G 是对称/交替群),则保证是正确的,而答案为 False 则以 eps 的概率是错误的。
对于度数小于 8 的情况,检查群的顺序以确保测试是确定性的。
注意
算法本身使用了一些群论和数论中的非平凡结果:1)如果度数为 n 的传递群 G 包含一个长度为 n/2 < p < n-2 的循环元素,其中 p 是一个素数,则 G 是对称群或交替群([1],第 81-82 页)2)对称/交替群中具有 1)描述的属性的元素比例约为 (\log(2)/\log(n))([1],第 82 页;[2],第 226-227 页)。辅助函数 _check_cycles_alt_sym 用于检查排列中满足 1)的循环。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> D = DihedralGroup(10)
>>> D.is_alt_sym()
False
另请参阅
_check_cycles_alt_sym
property is_alternating
如果群是交替的,则返回True。
示例
>>> from sympy.combinatorics import AlternatingGroup
>>> g = AlternatingGroup(5)
>>> g.is_alternating
True
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> g = PermutationGroup(
... Permutation(0, 1, 2, 3, 4),
... Permutation(2, 3, 4))
>>> g.is_alternating
True
注意
这使用了一个简单的测试,涉及到计算完整的群序。如果需要更快速的大群分类,可以使用PermutationGroup.is_alt_sym()。然而,PermutationGroup.is_alt_sym() 可能不够准确,并且无法区分交替群和对称群。
另请参阅
is_alt_sym
property is_cyclic
如果群是循环的,则返回True。
示例
>>> from sympy.combinatorics.named_groups import AbelianGroup
>>> G = AbelianGroup(3, 4)
>>> G.is_cyclic
True
>>> G = AbelianGroup(4, 4)
>>> G.is_cyclic
False
注意
如果群的顺序 (n) 可以分解为不同的素数 (p_1, p_2, \dots , p_s),并且如果
[\forall i, j \in {1, 2, \dots, s }: p_i \not \equiv 1 \pmod {p_j}]
如果成立,那么顺序为 (n) 的群只有一个循环群 [R76]。这是群的顺序为 (15, 35, \dots) 的引理的一般化。
同时,这些额外的引理还可以用来测试群是否循环,如果已知群的顺序。
-
如果群是阿贝尔群并且群的顺序是无平方的,则群是循环的。
-
如果群的顺序小于 (6) 并且不是 (4),则该群是循环的。
-
如果群的阶是素数,则群是循环的。
参考文献
[R76] (1,2)
1978: John S. Rose: A Course on Group Theory, Introduction to Finite Group Theory: 1.4
property is_dihedral
如果群是二面角的,则返回 True。
示例
>>> from sympy.combinatorics.perm_groups import PermutationGroup
>>> from sympy.combinatorics.permutations import Permutation
>>> from sympy.combinatorics.named_groups import SymmetricGroup, CyclicGroup
>>> G = PermutationGroup(Permutation(1, 6)(2, 5)(3, 4), Permutation(0, 1, 2, 3, 4, 5, 6))
>>> G.is_dihedral
True
>>> G = SymmetricGroup(3)
>>> G.is_dihedral
True
>>> G = CyclicGroup(6)
>>> G.is_dihedral
False
参考文献
[Di1]
[Di2]
kconrad.math.uconn.edu/blurbs/grouptheory/dihedral.pdf
[Di3]
kconrad.math.uconn.edu/blurbs/grouptheory/dihedral2.pdf
[Di4]
en.wikipedia.org/wiki/Dihedral_group
is_elementary(p)
如果群是基本阿贝尔的,则返回 True。一个基本阿贝尔群是一个有限阿贝尔群,其中每个非平凡元素的阶为 (p),其中 (p) 是一个素数。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1])
>>> G = PermutationGroup([a])
>>> G.is_elementary(2)
True
>>> a = Permutation([0, 2, 1, 3])
>>> b = Permutation([3, 1, 2, 0])
>>> G = PermutationGroup([a, b])
>>> G.is_elementary(2)
True
>>> G.is_elementary(3)
False
property is_nilpotent
测试群是否幂零。
解释
如果一个群 (G) 具有有限长度的中心级数,则它是幂零的。或者,如果 (G) 的下中心级数以平凡群终止,则 (G) 是幂零的。每个幂零群也是可解的([1], p.29, [12])。
示例
>>> from sympy.combinatorics.named_groups import (SymmetricGroup,
... CyclicGroup)
>>> C = CyclicGroup(6)
>>> C.is_nilpotent
True
>>> S = SymmetricGroup(5)
>>> S.is_nilpotent
False
参见
lower_central_series, is_solvable
is_normal(gr, strict=True)
测试 G=self 是否是 gr 的正规子群。
解释
如果对于每个 g2 属于 G 和 g1 属于 gr,g = g1*g2*g1**-1 属于 G,则 G 在 gr 中是正规的。对于 gr.generators 中的每个 g1 和 G.generators 中的每个 g2 检查这一点就足够了。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([1, 2, 0])
>>> b = Permutation([1, 0, 2])
>>> G = PermutationGroup([a, b])
>>> G1 = PermutationGroup([a, Permutation([2, 0, 1])])
>>> G1.is_normal(G)
True
property is_perfect
如果群是完全的,则返回 True。如果一个群等于它的导出子群,则它是完全的。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation(1,2,3)(4,5)
>>> b = Permutation(1,2,3,4,5)
>>> G = PermutationGroup([a, b])
>>> G.is_perfect
False
property is_polycyclic
如果一个群是多项循环的,则返回 True。如果一个群具有循环因子的子正规级数,则该群是多项循环的。对于有限群,这与群是否可解是相同的。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1, 3])
>>> b = Permutation([2, 0, 1, 3])
>>> G = PermutationGroup([a, b])
>>> G.is_polycyclic
True
is_primitive(randomized=True)
测试一个群是否是原始的。
解释
如果一个置换群 G 作用在集合 S 上,且 S 不含 G 的非平凡块(块的基数大于 1),则称 G 为原始的。
注意
算法在 [1], p.83 中描述,并使用函数 minimal_block 来搜索形式为 ({0, k}) 的块,其中 k 是 (G_0) 的轨道代表的范围。该算法的复杂度为 (O(n²)),其中 n 是群的阶数,在 (G_0) 较小时性能较差。
提供两种实现:一种使用函数stabilizer确定性地找到 (G_0),另一种(默认)使用random_stab产生 (G_0) 的随机元素,希望它们生成的子群具有不多于 (G_0) 的轨道(这在[1], p.83 中建议)。行为由randomized标志改变。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> D = DihedralGroup(10)
>>> D.is_primitive()
False
另见
minimal_block, random_stab
property is_solvable
测试群是否可解。
如果其导出级数以平凡群结束,则G是可解的([1], p.29)。
示例
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> S = SymmetricGroup(3)
>>> S.is_solvable
True
另见
is_nilpotent, derived_series
is_subgroup(G, strict=True)
如果self的所有元素都属于G,则返回True。
如果strict为False,则如果self的次数小于G的次数,则将调整元素大小以使它们具有相同的次数。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> from sympy.combinatorics import SymmetricGroup, CyclicGroup
默认情况下测试是严格的:每个群的次数必须相同:
>>> p = Permutation(0, 1, 2, 3, 4, 5)
>>> G1 = PermutationGroup([Permutation(0, 1, 2), Permutation(0, 1)])
>>> G2 = PermutationGroup([Permutation(0, 2), Permutation(0, 1, 2)])
>>> G3 = PermutationGroup([p, p**2])
>>> assert G1.order() == G2.order() == G3.order() == 6
>>> G1.is_subgroup(G2)
True
>>> G1.is_subgroup(G3)
False
>>> G3.is_subgroup(PermutationGroup(G3[1]))
False
>>> G3.is_subgroup(PermutationGroup(G3[0]))
True
若要忽略大小,请将strict设置为False:
>>> S3 = SymmetricGroup(3)
>>> S5 = SymmetricGroup(5)
>>> S3.is_subgroup(S5, strict=False)
True
>>> C7 = CyclicGroup(7)
>>> G = S5*C7
>>> S5.is_subgroup(G, False)
True
>>> C7.is_subgroup(G, 0)
False
property is_symmetric
如果群是对称的,则返回True。
示例
>>> from sympy.combinatorics import SymmetricGroup
>>> g = SymmetricGroup(5)
>>> g.is_symmetric
True
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> g = PermutationGroup(
... Permutation(0, 1, 2, 3, 4),
... Permutation(2, 3))
>>> g.is_symmetric
True
注释
这使用一个涉及计算完整群序的朴素测试。如果您需要更快速地为大群分类,您可以使用PermutationGroup.is_alt_sym()。然而,PermutationGroup.is_alt_sym()可能不够精确,并且不能区分交替群和对称群。
另见
is_alt_sym
is_transitive(strict=True)
测试群是否是传递的。
解释
如果一个群只有一个轨道,则该群是传递的。
如果strict为False,则如果群只有一个长度不为 1 的轨道,则该群是传递的。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1, 3])
>>> b = Permutation([2, 0, 1, 3])
>>> G1 = PermutationGroup([a, b])
>>> G1.is_transitive()
False
>>> G1.is_transitive(strict=False)
True
>>> c = Permutation([2, 3, 0, 1])
>>> G2 = PermutationGroup([a, c])
>>> G2.is_transitive()
True
>>> d = Permutation([1, 0, 2, 3])
>>> e = Permutation([0, 1, 3, 2])
>>> G3 = PermutationGroup([d, e])
>>> G3.is_transitive() or G3.is_transitive(strict=False)
False
property is_trivial
测试群是否是平凡群。
如果群仅包含单位置换,则为真。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> G = PermutationGroup([Permutation([0, 1, 2])])
>>> G.is_trivial
True
lower_central_series()
返回群的下中心级数。
一个群 (G) 的下中心级数是级数 (G = G_0 > G_1 > G_2 > \ldots),其中 (G_k = [G, G_{k-1}]),即第一个术语之后的每个术语都等于(G)与(G1)中的上一个术语的交换([1], p.29)。
返回:
按顺序列出排列群的列表 (G = G_0, G_1, G_2, \ldots)
示例
>>> from sympy.combinatorics.named_groups import (AlternatingGroup,
... DihedralGroup)
>>> A = AlternatingGroup(4)
>>> len(A.lower_central_series())
2
>>> A.lower_central_series()[1].is_subgroup(DihedralGroup(2))
True
另见
commutator, derived_series
make_perm(n, seed=None)
将 pgroup 中随机选择的 n 个排列相乘,从单位排列开始。如果 n 是整数列表,则这些整数将用于选择排列,并且它们将按照从左到右的顺序应用:make_perm((A, B, C)) 将给出 CBA(I),其中 I 是单位排列。
seed 用于设置从 pgroup 中随机选择排列的种子。如果这是一个整数列表,则将按照给定的顺序选择 pgroup 中对应的排列。这主要用于测试目的。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a, b = [Permutation([1, 0, 3, 2]), Permutation([1, 3, 0, 2])]
>>> G = PermutationGroup([a, b])
>>> G.make_perm(1, [0])
(0 1)(2 3)
>>> G.make_perm(3, [0, 1, 0])
(0 2 3 1)
>>> G.make_perm([0, 1, 0])
(0 2 3 1)
另见
random
property max_div
排列群的最大真约数。
解释
显然,这是度数除以其最小真约数(大于 1,如果存在的话)。由于它保证是素数,所以使用 sympy.ntheory 中的 sieve。此函数也用作函数 minimal_block 和 _union_find_merge 的优化工具。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> G = PermutationGroup([Permutation([0, 2, 1, 3])])
>>> G.max_div
2
另见
minimal_block, _union_find_merge
minimal_block(points)
对于传递群,找到由 points 生成的块系统。
解释
如果群 G 作用于集合 S,则 S 的非空子集 B 在 G 的作用下称为一个块,如果对于所有 g 属于 G,我们有 gB = B(g 使 B 固定)或者 gB 和 B 没有共同的点(g 将 B 移动整个)。([1],第 23 页; [6])。
对于群 G 中的 g 的块 B 的不同平移 gB,将集合 S 划分,并且这组平移被称为一个块系统。此外,显然地,分区中的所有块具有相同的大小,因此块大小整除 |S|([1],第 23 页)。G-同余是集合 S 上的等价关系 ~,使得 a ~ b 意味着对于所有 g 属于 G,有 g(a) ~ g(b)。对于一个传递群,G-同余的等价类与块系统中的块是同一回事([1],第 23 页)。
下面的算法检查群是否传递,然后找到由对 (p_0, p_1), (p_0, p_2), ..., (p_0,p_{k-1}) 生成的 G-同余,这与找到具有最小块大小的最大块系统相同,使得 p_0, ..., p_{k-1} 在同一个块中([1],第 83 页)。
它是 Atkinson 算法的实现,如[1]建议的,使用并查集数据结构操作集合 S 上的等价关系。运行时间略高于 (O(|points||S|))。([1], pp. 83-87; [7])。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> D = DihedralGroup(10)
>>> D.minimal_block([0, 5])
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
>>> D.minimal_block([0, 1])
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
参见
_union_find_rep, _union_find_merge, is_transitive, is_primitive
minimal_blocks(randomized=True)
对于一个传递群,返回所有最小块系统的列表。如果一个群是不可传递的,则返回 (False)。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> DihedralGroup(6).minimal_blocks()
[[0, 1, 0, 1, 0, 1], [0, 1, 2, 0, 1, 2]]
>>> G = PermutationGroup(Permutation(1,2,5))
>>> G.minimal_blocks()
False
参见
minimal_block, is_transitive, is_primitive
normal_closure(other, k=10)
返回子群/排列集合的正规闭包。
参数:
other
排列的子群/列表/单个排列
k
一个特定于实现的参数,确定一次将多少共轭附加到
other上
解释
若 S 是群 G 的子集,则 A 在 G 中的正规闭包定义为包含 A 的所有 G 的正规子群的交集 ([1], p.14)。或者,它是由共轭元 x^{-1}yx 生成的群,其中 x 是 G 的生成元,y 是子群 \left\langle S\right\rangle(对于 \left\langle S\right\rangle 的某个选择的生成集)的生成元 ([1], p.73)。
示例
>>> from sympy.combinatorics.named_groups import (SymmetricGroup,
... CyclicGroup, AlternatingGroup)
>>> S = SymmetricGroup(5)
>>> C = CyclicGroup(5)
>>> G = S.normal_closure(C)
>>> G.order()
60
>>> G.is_subgroup(AlternatingGroup(5))
True
注意
该算法在[1]第 73-74 页中描述;它利用产品替换算法生成排列群的随机元素。
参见
commutator, derived_subgroup, random_pr
orbit(alpha, action='tuples')
计算 alpha 的轨道 ({g(\alpha) | g \in G}) 作为一个集合。
解释
此处使用的算法的时间复杂度为(O(|Orb|*r)),其中( |Orb| )是轨道的大小,r是群的生成器数目。有关更详细的分析,请参见[1],第 78 页,[2],第 19-21 页。这里的 alpha 可以是单个点,也可以是点列表。
如果 alpha 是单个点,则计算普通轨道。如果 alpha 是点列表,则有三个可用选项:
'union' - 计算列表中点的轨道的并集 'tuples' - 在群作用下计算列表的轨道(即,g((1,2,3)) = (g(1), g(2), g(3))) 'sets' - 计算列表的轨道,解释为集合
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([1, 2, 0, 4, 5, 6, 3])
>>> G = PermutationGroup([a])
>>> G.orbit(0)
{0, 1, 2}
>>> G.orbit([0, 4], 'union')
{0, 1, 2, 3, 4, 5, 6}
参见
orbit_transversal
orbit_rep(alpha, beta, schreier_vector=None)
返回一个将alpha发送到beta的群元素。
解释
如果beta不在alpha的轨道上,则函数返回False。此实现使用了 Schreier 向量。关于正确性的证明,请参见[1],第 80 页。
示例
>>> from sympy.combinatorics.named_groups import AlternatingGroup
>>> G = AlternatingGroup(5)
>>> G.orbit_rep(0, 4)
(0 4 1 2 3)
参见
schreier_vector
orbit_transversal(alpha, pairs=False)
计算alpha轨道的横断面。
解释
对于置换群( G ),轨道( Orb = {g(\alpha) | g \in G} )的一个横断面是集合( {g_\beta | g_\beta(\alpha) = \beta} ),其中( \beta \in Orb )。请注意可能存在多个可能的横断面。如果pairs设为True,则返回配对列表((\beta, g_\beta))。关于正确性的证明,请参见[1],第 79 页。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> G = DihedralGroup(6)
>>> G.orbit_transversal(0)
[(5), (0 1 2 3 4 5), (0 5)(1 4)(2 3), (0 2 4)(1 3 5), (5)(0 4)(1 3), (0 3)(1 4)(2 5)]
参见
orbit
orbits(rep=False)
返回self的轨道,根据每个轨道中的最小元素排序。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation(1, 5)(2, 3)(4, 0, 6)
>>> b = Permutation(1, 5)(3, 4)(2, 6, 0)
>>> G = PermutationGroup([a, b])
>>> G.orbits()
[{0, 2, 3, 4, 6}, {1, 5}]
order()
返回群的阶数:可以从群的元素生成的排列数。
群的排列数由len(group)给出;群中每个排列的长度由group.size给出。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([1, 0, 2])
>>> G = PermutationGroup([a])
>>> G.degree
3
>>> len(G)
1
>>> G.order()
2
>>> list(G.generate())
[(2), (2)(0 1)]
>>> a = Permutation([0, 2, 1])
>>> b = Permutation([1, 0, 2])
>>> G = PermutationGroup([a, b])
>>> G.order()
6
参见
degree
pointwise_stabilizer(points, incremental=True)
返回点集的点对稳定子。
解释
对于置换群( G )和点集({p_1, p_2,\ldots, p_k}),(p_1, p_2, \ldots, p_k)的点对稳定子定义为(G_{p_1,\ldots, p_k} = {g\in G | g(p_i) = p_i \forall i\in{1, 2,\ldots,k}})([1],第 20 页)。它是(G)的子群。
示例
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> S = SymmetricGroup(7)
>>> Stab = S.pointwise_stabilizer([2, 3, 5])
>>> Stab.is_subgroup(S.stabilizer(2).stabilizer(3).stabilizer(5))
True
注意
当incremental == True时,与使用连续调用.stabilizer()的明显实现不同,这里使用增量 Schreier-Sims 算法来获得具有起始段的基。
参见
stabilizer, schreier_sims_incremental
polycyclic_group()
返回具有以下参数的 PolycyclicGroup 实例:
解释
-
pc_sequence:多项式序列是通过在给定置换群的导出序列中的相邻群之间收集所有缺失的生成器而形成的。
-
pc_series:多项式系列是通过在
der[i]中添加der[i+1]中的所有缺失生成器而形成的,其中der表示导出系列。 -
相对阶:由 pc_series 中相邻群的比率计算的列表。
presentation(eliminate_gens=True)
返回群的(FpGroup)演示。
该算法在[1],第 6.1 章中描述。
random(af=False)
返回一个随机群元素
random_pr(gen_count=11, iterations=50, _random_prec=None)
使用乘积替换返回一个随机群元素。
解释
有关乘积替换算法的详细信息,请参见_random_pr_init在random_pr中执行实际的‘乘积替换’。请注意,如果属性_random_gens为空,则需要通过_random_pr_init进行初始化。
另请参阅
_random_pr_init
random_stab(alpha, schreier_vector=None, _random_prec=None)
alpha的稳定器的随机元素。
alpha的 Schreier 向量是用于加速重复调用的可选参数。该算法在[1],第 81 页中描述。
另请参阅
random_pr, orbit_rep
schreier_sims()
Schreier-Sims 算法。
解释
它计算稳定器链(G > G_{b_1} > .. > G_{b1,..,b_r} > 1)的生成器,其中(G_{b_1,..,b_i})稳定(b_1,..,b_i),以及相应的s余类。群的一个元素可以写成乘积(h_1*..*h_s)。
我们使用增量 Schreier-Sims 算法。
例子
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([0, 2, 1])
>>> b = Permutation([1, 0, 2])
>>> G = PermutationGroup([a, b])
>>> G.schreier_sims()
>>> G.basic_transversals
[{0: (2)(0 1), 1: (2), 2: (1 2)},
{0: (2), 2: (0 2)}]
schreier_sims_incremental(base=None, gens=None, slp_dict=False)
将一系列点和生成集扩展为基础和强生成集。
参数:
base
要扩展为基础的点序列。可选参数,默认值为
[]。
gens
要扩展的生成集相对于获得的基础的强生成集。可选参数,默认值为
self.generators。
slp_dict
如果为(True),则为每个强生成器(g)返回一个字典({g: gens}),其中(gens)是在(strong_gens)中的(g)之前出现的强生成器的列表,使得(gens)的元素的乘积等于(g)。
返回:
(base, strong_gens)
base是获得的基础,strong_gens是相对于它的强生成集。原始参数base,gens保持不变。
例子
>>> from sympy.combinatorics.named_groups import AlternatingGroup
>>> from sympy.combinatorics.testutil import _verify_bsgs
>>> A = AlternatingGroup(7)
>>> base = [2, 3]
>>> seq = [2, 3]
>>> base, strong_gens = A.schreier_sims_incremental(base=seq)
>>> _verify_bsgs(A, base, strong_gens)
True
>>> base[:2]
[2, 3]
注意
该版本的 Schreier-Sims 算法运行在多项式时间内。实施中存在某些假设 - 如果提供了平凡群,则立即返回base和gens,因为任何点序列都是平凡群的基础。如果生成器gens中存在恒等元素,则将其移除,因为它是冗余生成器。实现描述在[1],第 90-93 页。
参见
schreier_sims,schreier_sims_random
schreier_sims_random(base=None, gens=None, consec_succ=10, _random_prec=None)
随机化的 Schreier-Sims 算法。
参数:
base
要扩展为基础的序列。
gens
要扩展为强生成集的生成集。
consec_succ
定义错误答案概率的参数。
_random_prec
用于测试目的的内部参数。
返回:
(base, strong_gens)
base是基础,strong_gens是相对于它的强生成集。
解释
随机化的 Schreier-Sims 算法使用序列base和生成集gens,将base扩展到基础,并相对于该基础将gens扩展为强生成集,提供错误答案的概率最多为(2^{-consec_succ}),前提是随机生成器足够随机。
示例
>>> from sympy.combinatorics.testutil import _verify_bsgs
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> S = SymmetricGroup(5)
>>> base, strong_gens = S.schreier_sims_random(consec_succ=5)
>>> _verify_bsgs(S, base, strong_gens)
True
注释
该算法详细描述在[1],第 97-98 页。它将轨道orbs和置换群stabs扩展到最终生成的基本轨道和基本稳定器的基础和强生成集。扩展过程的思想是通过稳定器链“筛选”随机群元素,并在筛选不成功时在路上修正稳定器/轨道。助手函数_strip用于尝试根据当前稳定器链的状态分解随机群元素,并报告元素是否完全分解(成功筛选)或否(失败筛选)。在后一种情况下,报告筛选失败的级别,并相应地修正stabs,base,gens和orbs。停止条件是连续consec_succ次成功筛选。这确保当前的base和gens以至少(1 - 1/\text{consec_succ})的概率形成 BSGS。
参见
schreier_sims
schreier_vector(alpha)
计算alpha的 Schreier 向量。
解释
Schreier 向量高效存储关于 alpha 轨道的信息。稍后可用于快速获取将 alpha 发送到轨道中特定元素的群的元素。注意,Schreier 向量取决于群生成器列出的顺序。定义详见 [3]。由于列表索引从零开始,我们采用“None”作为标记,表示元素不属于轨道。有关算法及其正确性详见 [2],第 78-80 页。
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([2, 4, 6, 3, 1, 5, 0])
>>> b = Permutation([0, 1, 3, 5, 4, 6, 2])
>>> G = PermutationGroup([a, b])
>>> G.schreier_vector(0)
[-1, None, 0, 1, None, 1, 0]
参见
orbit
stabilizer(alpha)
返回 alpha 的稳定子群。
解释
(\alpha) 的稳定子群是群 (G_\alpha = {g \in G | g(\alpha) = \alpha})。正确性证明见 [1],第 79 页。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> G = DihedralGroup(6)
>>> G.stabilizer(5)
PermutationGroup([
(5)(0 4)(1 3)])
参见
orbit
property strong_gens
从 Schreier-Sims 算法返回一个强生成集。
解释
置换群 (G) 的生成集合 (S = {g_1, g_2, \dots, g_t}) 相对于点序列(称为“基”)((b_1, b_2, \dots, b_k)) 是强生成集,如果对于 (1 \leq i \leq k),点对稳定子 (G^{(i+1)} := G_{b_1, b_2, \dots, b_i}) 与 (S) 的交集生成点对稳定子 (G^{(i+1)})。关于基和强生成集的概念及其应用在 [1],第 87-89 页和 [2],第 55-57 页详细讨论。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> D = DihedralGroup(4)
>>> D.strong_gens
[(0 1 2 3), (0 3)(1 2), (1 3)]
>>> D.base
[0, 1]
参见
base,basic_transversals,basic_orbits,basic_stabilizers
strong_presentation()
返回群的强有限表示。返回群的生成器与强生成器的顺序相同。
该算法基于 Sims 的 Verify 算法,详见 [1],第六章。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> P = DihedralGroup(4)
>>> G = P.strong_presentation()
>>> P.order() == G.order()
True
参见
presentation,_verify
subgroup(gens)
返回由群元素列表 gens 生成的子群。
subgroup_search(prop, base=None, strong_gens=None, tests=None, init_subgroup=None)
查找所有满足属性 prop 的元素的子群。
参数:
prop
用于被使用的属性。必须在群元素上可调用,并始终返回
True或False。假设所有满足prop的群元素确实形成一个子群。
base
超群的一个基。
strong_gens
超群的一个强生成集。
tests
一个长度等于
base长度的可调用对象列表。这些用于通过部分基映像排除群元素,因此如果元素g已知不满足prop,则testsl返回 False。
init_subgroup
如果预先知道所寻找群的一个子群,则可以将其作为此参数传递给函数。
返回:
res
满足
prop的所有元素的子群。保证该群的生成集相对于基base是一个强生成集。
解释
这是一种深度优先搜索,考虑基映像,并使用多个测试来修剪搜索树。
示例
>>> from sympy.combinatorics.named_groups import (SymmetricGroup,
... AlternatingGroup)
>>> from sympy.combinatorics.testutil import _verify_bsgs
>>> S = SymmetricGroup(7)
>>> prop_even = lambda x: x.is_even
>>> base, strong_gens = S.schreier_sims_incremental()
>>> G = S.subgroup_search(prop_even, base=base, strong_gens=strong_gens)
>>> G.is_subgroup(AlternatingGroup(7))
True
>>> _verify_bsgs(G, base, G.generators)
True
注意事项
这个函数非常长且复杂,需要仔细注意。该实现在[1],第 114-117 页中描述,此处的代码注释遵循书中伪代码以确保清晰。
一般情况下,复杂度是指数级的,因为搜索过程本身访问超群的所有成员。然而,有许多测试用于修剪搜索树,用户可以通过tests参数定义自己的测试,因此在实践中,对于某些计算而言,情况并不糟糕。
程序中关键的一部分是执行频繁的基变换(这是伪代码中的第 11 行),以获得一个新的基本稳定器。书中提到可以通过使用.baseswap(...)来实现,但当前的实现使用更直接的方法来找到下一个基本稳定器 - 在前一个基本稳定器上调用函数.stabilizer(...)。
sylow_subgroup(p)
返回群的一个 p-Sylow 子群。
该算法在[1],第四章,第七部分中描述。
示例
>>> from sympy.combinatorics.named_groups import DihedralGroup
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.named_groups import AlternatingGroup
>>> D = DihedralGroup(6)
>>> S = D.sylow_subgroup(2)
>>> S.order()
4
>>> G = SymmetricGroup(6)
>>> S = G.sylow_subgroup(5)
>>> S.order()
5
>>> G1 = AlternatingGroup(3)
>>> G2 = AlternatingGroup(5)
>>> G3 = AlternatingGroup(9)
>>> S1 = G1.sylow_subgroup(3)
>>> S2 = G2.sylow_subgroup(3)
>>> S3 = G3.sylow_subgroup(3)
>>> len1 = len(S1.lower_central_series())
>>> len2 = len(S2.lower_central_series())
>>> len3 = len(S3.lower_central_series())
>>> len1 == len2
True
>>> len1 < len3
True
property transitivity_degree
计算群的传递度。
解释
作用于集合(\Omega = {0, 1, \dots, n-1})的置换群(G)是k-重传递的,如果对于任意(k)个点((a_1, a_2, \dots, a_k) \in \Omega)和任意(k)个点((b_1, b_2, \dots, b_k) \in \Omega),存在(g \in G)使得(g(a_1) = b_1, g(a_2) = b_2, \dots, g(a_k) = b_k)。群(G)的传递度是最大的k,使得(G)是k-重传递的。([8])
示例
>>> from sympy.combinatorics import Permutation, PermutationGroup
>>> a = Permutation([1, 2, 0])
>>> b = Permutation([1, 0, 2])
>>> G = PermutationGroup([a, b])
>>> G.transitivity_degree
3
另请参阅
is_transitive,orbit