0
0

More than 3 years have passed since last update.

# Python de 対称群 2

Last updated at Posted at 2020-12-17

# plusone() 関数の改良

どうもどこかで見たはずの，前回の tuple でやる方式は，スタンダードではないらしいので，list に変えて，更に拡張・改良する．

## 1 前回の関数

``````import numpy as np
from sympy.combinatorics import *
from sympy import *
init_printing(pretty_print=False)

n = 3

def plusone_tuple(x):
X = tuple([0])
for i in range(n):
a = tuple([tuple(x)[i] + 1])
X = X + a
return Permutation(tuple(X))

print(plusone_tuple(Permutation(0,1,2)))

#(1 2 3)
``````

とりあえず，内包表記を使って3次対称群の元を[0, 1, 2]に掛けたものを書いてみる．

``````A = PermutationGroup(SymmetricGroup(n)[0], SymmetricGroup(n)[1])._elements

print(A)
[list(A[i]) for i in range(len(A))]
'''
[Permutation(2), Permutation(0, 1, 2), Permutation(0, 2, 1), Permutation(1, 2), Permutation(2)(0, 1), Permutation(0, 2)]
[[0, 1, 2], [1, 2, 0], [2, 0, 1], [0, 2, 1], [1, 0, 2], [2, 1, 0]]
'''
``````

## 2 今回の関数

list にした関数と複数の置換のリストを扱えるよう改良した関数．

``````from sympy.combinatorics import *
from sympy import *
init_printing(pretty_print=False)

def plusone(x):
add_one = [(i > 0) * (list(x)[i - 1] + 1) for i in range(1 + len(list(x)))]
#(i > 0) is a step function.
return Permutation(add_one)

n = 3
def plusone_list(x):
return plusone(x)

def plusone_multi(list_of_permutations):
return [plusone(list_of_permutations[i]) for i in range(len(list_of_permutations))]

print(A)
AA = plusone_multi(A)
AA

'''
[Permutation(2), Permutation(0, 1, 2), Permutation(0, 2, 1), Permutation(1, 2), Permutation(2)(0, 1), Permutation(0, 2)]
[(3), (1 2 3), (1 3 2), (2 3), (3)(1 2), (1 3)]
'''
``````

ちなみに面倒くさいがこうしても同じである．

``````generate_Sym3_perm = PermutationGroup(plusone(SymmetricGroup(n)[0]), plusone(SymmetricGroup(n)[1]))._elements
generate_Sym3_perm
'''
[(3), (1 2 3), (1 3 2), (2 3), (3)(1 2), (1 3)]
'''
``````

``````def list_multi(list_of_permutations):
return [list(list_of_permutations[i]) for i in range(len(list_of_permutations))]
print(list_multi(A))
print(list_multi(AA))
'''
[[0, 1, 2], [1, 2, 0], [2, 0, 1], [0, 2, 1], [1, 0, 2], [2, 1, 0]]
[[0, 1, 2, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 1, 3, 2], [0, 2, 1, 3], [0, 3, 2, 1]]
'''
``````

## 3 3次対称群をシンプルに計算

3次対称群の要素を表示する．

``````Sym3_perm = SymmetricGroup(n)._elements
Sym3_perm
'''
[(2), (0 1 2), (0 2 1), (1 2), (2)(0 1), (0 2)]
'''
``````

1から始まる表示にして，リスト（[0,1,2,3]に置換を掛けた結果）に直してみる．

``````Sym3_list = list_multi(plusone_multi(Sym3_perm))
Sym3_list
'''
[[0, 1, 2, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 1, 3, 2], [0, 2, 1, 3], [0, 3, 2, 1]]
'''
``````

# 考察

np.array で出来ることに気づいたので計算時間を測定して比較してみる．

まずは上の．

``````%%timeit
Sym3_list = list_multi(plusone_multi(Sym3_perm))
Sym3_list
#129 µs ± 6.92 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
#132 µs ± 13.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
#132 µs ± 13.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
``````

numpy.

``````%%timeit
Sym3_list_np = np.array(plusone_multi(Sym3_perm)).tolist()
Sym3_list_np
#139 µs ± 10.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
#135 µs ± 5.21 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
#143 µs ± 8.14 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
``````

・1回目は list_multi → np.array

・2回目は np.array → list_multi

・3回目は並列に実行してみた．

ただ，np.array を使って少し重くなるのか，list_multi() を用いたほうがこころなしか速く，安定しているように思う．ここでは，numpy を import する必要もなさそうだ．

0
0
0

Register as a new user and use Qiita more conveniently

1. You get articles that match your needs
2. You can efficiently read back useful information
3. You can use dark theme
What you can do with signing up
0
0