ここでは young の基本的な使い方を解説します。 Python のインタープリターから使う場合、まず young モジュールをインポートします。
>>> import young >>> from young import * # 手を抜く
上のスタイルでモジュールをインポートした場合、関数を呼び出すときに 毎回モジュールの名前を明示的に指定する必要があります。
>>> young.partition(10) >>> young.factorial(5)
Python のことはあまり知らず、young モジュールしか使わないなら下の方が楽でいいと思います。
まずは、基本的な計算から
>>> factorial(5) # 5 の階乗 : 5 x 4 x 3 x 2 x 1 120 >>> factorial(3, 5) # 3 から 5 までを掛ける : 3 x 4 x 5 60 >>> permutation(1,2,3) # (1,2,3) の順列 [[3, 1, 2], [2, 1, 3], [1, 3, 2], [2, 3, 1], [1, 2, 3], [3, 2, 1]] >>> permutation('xyz') # 'x', 'y', 'z' の順列 [['z', 'x', 'y'], ['y', 'x', 'z'], ['x', 'z', 'y'], ['y', 'z', 'x'], ['x', 'y', 'z'], ['z', 'y', 'x']] >>> combination(4, 2) # 4個から2個を選ぶ組合せの数 6 >>> combination('python', 2) # 文字列 "python" から2文字選ぶ [['p', 'y'], ['p', 't'], ['p', 'h'], ['p', 'o'], ['p', 'n'], ['y', 't'], ['y', ' h'], ['y', 'o'], ['y', 'n'], ['t', 'h'], ['t', 'o'], ['t', 'n'], ['h', 'o'], ['h ', 'n'], ['o', 'n']]
combination の結果は第一引数が整数か sequence かによって、異なります。
カタラン数を少し。
>>> catalan(20) 6564120420L >>> for i in range(10): # 0 から 9 までのカタラン数を表示 ... print i, catalan(i) ... 0 1 1 1 2 2 3 5 4 14 5 42 6 132 7 429 8 1430 9 4862
次に自然数 N の分割を与えます。
>>> partition(5) (5) (4,1) (3,2) (3,1,1) (2,2,1) (2,1,1,1) (1,1,1,1,1) >>> p = partition(10) >>> p.size() # 10 の分割はどれだけあるのか 42 >>> for x in take(p, 5): # 10 の分割のうち、最初の 5 個を表示 ... print x ... (1,1,1,1,1,1,1,1,1,1) (2,1,1,1,1,1,1,1,1) (2,2,1,1,1,1,1,1) (2,2,2,1,1,1,1) (2,2,2,2,1,1) >>> for x in drop(p, 37): # 最後の 5 個を表示(42 - 37 = 5) ... print x ... (7,3) (8,1,1) (8,2) (9,1) (10) # Ramanujan's upper bound >>> for n in (10, 20, 30, 40, 50): ... print partition(n).size(), partition_upper_bound(n) ... 42 48 627 692 5604 6080 37338 40080 204226 217590
Partition の引数に分割を渡すことで、直接 Partition のオブジェクトを作ることもできます。 分割は list または tuple で渡してください。
>>> p = Partition((2,1,1)) >>> p (2,1,1) >>> p.plot() # (2,1,1) の形をした盤を表示 ** * * >>> p_conj = p.conjugate() # (2,1,1) の conjugate >>> print p_conj (3,1) >>> p_conj.plot() # (3,1) の形をした盤を表示 *** * >>> p_conj.conjugate() == p # 確認 True >>> p.up() # 分割 (2,1,1) の up operation (3,1,1) (2,2,1) (2,1,1,1) >>> p.down() # 分割 (2,1,1) の down operation (1,1,1) (2,1)
Partition の up/down の戻り値は Partition の list(SeqOfPartition クラスのインスタンス)です。
置換群の簡単な計算もできます。 [1,2,3] を [2,1,3] に移す置換の場合、(2,1,3) で表します。
>>> from young import * >>> p = permgroup(3,2,1) >>> p PermGroup([3 2 1]) >>> p.get_inv() # 転倒数 3 >>> p.get_sgn() # 符号(-1 or +1) -1 >>> p.isodd() # 奇置換ですか? True >>> p.iseven() # 偶置換ですか? False >>> p.get_inverse() # 逆元 PermGroup([3 2 1]) >>> p = permgroup(5,3,2,1,4) >>> p.to_cycle() # 巡回置換分解 Cycle([(1 4 5) (2 3)]) >>> p.get_inverse() # 逆元 PermGroup([4 3 2 5 1]) >>> p1 = permgroup(4,3,1,2) >>> p2 = permgroup(3,1,4,2) >>> p1 * p2 # 置換群の間の演算は * で行います。 PermGroup([2 4 3 1]) >>> p2 * p1 PermGroup([1 4 2 3]) >>> p3 = p1 * p2 >>> p3 PermGroup([2 4 3 1]) >>> p4 = p3.get_inverse() # 逆元 >>> p4 PermGroup([4 1 3 2]) >>> p3 * p4 # 単位元になるかチェック PermGroup([1 2 3 4]) >>> p4 * p3 # 単位元になるかチェック PermGroup([1 2 3 4]) >>> p3.to_cycle() # 巡回置換分解 Cycle([(1 2 4) (3)]) >>>
と書かれているものと同じ演算になっています。
と同じです。
このあたりは将来的に変わる可能性が高いです。
次がメインのヤング図形です。 Young 盤を作るには、大きく分けて 3 通りあります。
young(N) とすれば、N の分割を元にしたすべてのヤング盤が生成されます。
>>> y = young(3) >>> print y # 3 の分割からなっている Young 盤をすべて表示 (3) 1 2 3 (2,1) 1 2 3 1 3 2 (1,1,1) 1 2 3
young の引数に分割を直接与えることで、その分割を基にしたヤング盤が生成されます。
>>> y = young((2,1,1)) # 分割 (2,1,1) を与える >>> print y # 分割が (2,1,1) のヤング盤 (2,1,1) 1 2 3 4 1 3 2 4 1 4 2 3
Young 盤を直接指定することもできます。 指定する Young 盤は sequence of sequence(tuple of tuple や list of list など) である必要があります。 この場合、すべて小文字の young ではなく、大文字で始まる Young です。
>>> y = Young([[1,2],[2],[3]]) # list of list であらわされた Young 盤を引数に渡す >>> print y 1 2 2 3
実際にヤング図形を操作してみます。
>>> y = young(4) >>> y (4) 1 2 3 4 (3,1) 1 2 3 4 1 2 4 3 1 3 4 2 (2,2) 1 2 3 4 1 3 2 4 (2,1,1) 1 2 3 4 1 3 2 4 1 4 2 3 (1,1,1,1) 1 2 3 4 >>> y.report() # 各分割に対して、標準盤がどれだけあるのか partition number square ---------------------------------------- (4) 1 1 (3,1) 3 9 (2,2) 2 4 (2,1,1) 3 9 (1,1,1,1) 1 1 ---------------------------------------- total 10 24 >>> factorial(4) # チェック 24 >>> young((3,1,1)) # 分割が (3,1,1) の標準盤 (3, 1, 1) 1 2 3 4 5 1 2 4 3 5 1 2 5 3 4 1 3 4 2 5 1 3 5 2 4 1 4 5 2 3 >>> y = young(6) >>> y.size() # 6 の分割を元にした標準盤がどれだけあるか 76 >>> for x in take(y, 4): # 6 を元にした標準盤から4個を表示 print x 1 2 3 4 5 6 1 2 4 3 5 6 1 2 5 3 4 6 1 3 4 2 5 6
>>> y = young((2,1)) # 最初に分割を与える >>> y.get_partition() # Young 盤の元になっている分割をかえす (2, 1) >>> print y (2,1) 1 2 3 1 3 2 >>> y.up() # 分割 (2,1) に up operation をする >>> y.get_partition() (2,1,1) (2,2) (3,1) >>> print y (3,1) 1 2 3 4 1 2 4 3 1 3 4 2 (2,2) 1 2 3 4 1 3 2 4 (2,1,1) 1 2 3 4 1 3 2 4 1 4 2 3 >>> for i in range(3): # さらに3回 up operation を繰り返す ... y.up() ... y.get_partition() ... print ... (2,1,1,1) (2,2,1) (3,1,1) (3,2) (4,1) (2,1,1,1,1) (2,2,1,1) (2,2,2) (3,1,1,1) (3,2,1) (3,3) (4,1,1) (4,2) (5,1) ...(snip) >>> y = young((2,1,1)) # まず分割を与える >>> y.get_partition() # チェック (2, 1, 1) >>> for i in range(4): # 今度は down operation ... y.down() ... y.get_partition() ... print ... (1,1,1) (2,1) (1,1) (2) (1) ()
Young 盤の bumping も出来ます。
>>> y = Young([[1,2,3]]) >>> print y 1 2 3 >>> y.bump(2) # bump >>> print y 1 2 2 3 >>> y1 = Young([[1,1,2],[2,2,3],[4,5]]) >>> y2 = Young([[1,1],[2]]) >>> y1 1 1 2 2 2 3 4 5 >>> y2 1 1 2 >>> y1.bump(y2) # y1 * y2 とすることも可能 >>> print y1 1 1 1 1 2 2 2 2 3 5 4 >>> y1 = Young([[1,1,2],[2,2,3],[4,5]]) >>> print y1 1 1 2 2 2 3 4 5 >>> for box in (1,1,2): ... y1.bump(box) ... print "y1 <- %d"%box ... print y1 ... y1 <- 1 1 1 1 2 2 2 3 5 4 y1 <- 1 1 1 1 1 2 2 2 3 5 4 y1 <- 2 1 1 1 1 2 2 2 2 3 5 4
まだ実験段階ですが、部分的に Skew tableau も実装されています。
>>> y1 = Young([[1,1,2],[2,2,3],[4,5]]) >>> y2 = Young([[1,1],[2]]) >>> skew = y1 / y2 # skew tableau >>> skew * * 2 * 2 3 4 5
Date: | $Date: 2004/04/25 16:58:20 $ |
---|