APL/J言語:C.(ラージシードット、サイクル)
pがi.nの要素からなる順列ならば,pはn次の順列ベクトルと呼ばれる。
n=#b(bの要素数がn)ならば、p{bはbの要素の順列である。
C.pはボックス化されたi.#pの要素からなる表を返す。この表はpの順列の標準サイクル表現と呼ばれるものである。p=:4 5 2 1 0 3とするならば、C.pは(,2);4 0;5 3 1である。この意味は2の位置にあるものは2のまま、0が4,4が0に移動する。また3が5、1が3、5が1に移動するという意味である。単項動詞としてのC.(ラージシードット、サイクル)は自己逆関数である。標準サイクルに作用させると対応する通常のボックス化されない順列表現(順列ベクトル)を返す。
C.(ラージシードット、サイクル)は拡張されていて、qが負でない場合、1+>./; qの次元の順列を返すようになっている。(つまり、数列を与えた場合最大値に1を加えた数のサイクル表現を返す。)
単項動詞C.!.2(ラージシードットエクスクラメーションドットに)は順列pのパリティを計算する。返される値は順列番号のi.#pによってpを得るためになされる交換のペアの数が偶数か奇数かにより1か_1が返される。pが順列でない場合は0になる。
] x=: 2 , (i.4) ,: 1 0 2 3 2 2 2 2 0 1 2 3 1 0 2 3 C.!.2 x 0 1 _1
解説:2 2 2 2は順列でないので0、0 1 2 3は交換数が偶数(0)なので1、1 0 2 3は0と1を交換しただけなので交換数が奇数なので_1。
pとcがアイテム数#bの順列の通常の表現と、サイクル表現とすると、
p C. b
c C. b
はどちらもbの順列を生成する。引数のpとcは定義のしかたにおいて非標準で有り得る。特に、-#bまでの負の整数は#bで割ったときの余りとして処理される。
qがボックスでなく、(#b)|qの要素が重なっていなければ、q C. bはn=:#bについてp=:((i.n)-.n|q),n|qとしたときのp{bと同じである。別の言葉で言えば、qで表現された位置のものが順列の後ろに移動する。
解説:|(パイプ、絶対値、余り)は二項動詞としては右側引数を左側引数で割った余りを返す。-.(マイナスドット、ノット)は左側引数から右側引数の要素でないものだけを返す。(0 1 2 3)-.(1 2)=>(0 3)
qがボックスならば、(#b)|>j{q(ボックスj=0,1,2..の中身をリストにしてnで割った余りのリスト)の要素は重なってはならない。ボックスは右からボックスごとに順番に適用される。
(2 1;3 0 1) C. i.5 1 2 3 0 4 (<2 1) C. (<3 0 1) C. i.5 1 2 3 0 4 q=: C. p=: 1 2 3 0 4 [ a=: 'abcde' q ; (q C. a) ; (p C. a) ; (p { a) +-----------+-----+-----+-----+ |+-------+-+|bcdae|bcdae|bcdae| ||3 0 1 2|4|| | | | |+-------+-+| | | | +-----------+-----+-----+-----+ a ; (<0 _1) C. a +-----+-----+ |abcde|ebcda| +-----+-----+
追加例:
] p=: 22 ?. 22 NB.要素数22のランダムな順列 16 18 21 8 6 15 10 14 7 11 0 2 5 3 9 12 20 17 4 19 13 1 C. p NB.そのサイクル表現 +-------+--+--+-----------------------------------------+ |15 12 5|17|19|21 1 18 4 6 10 0 16 20 13 3 8 7 14 9 11 2| +-------+--+--+-----------------------------------------+ *./ #&> C. p NB.各サイクルの長さの最小公倍数 51 # ~. p&{^:(i.200) i.#p NB.pに生成されたサブグループのサイズ 51
解説:?.(はてなドット、クエスチョンマークドット)はシードが固定のランダムで毎回同じ順序の結果を出す。こういったサンプル作成には便利である。*./は最小公倍数のフレーズ。ボックスに#&>を作用すると3 1 1 17のような数列を返す。最後の例はi.#pに、p {を200回作用した結果から同じものをはぶくといくつあるか、という計算。~.(チルダドット、ナブ)はuniqのような意味。
下記の動詞CTはn次の疎配列(スパースアレイ)の完全なテンソルを計算する。(
CT=: 3 : '(C.!.2 p) (<"1 p=. (i.!y) A. i.y)}1$.$~y' CT 3 0 1 2 | 1 0 2 1 | _1 1 0 2 | _1 1 2 0 | 1 2 0 1 | 1 2 1 0 | _1 ($.^:_1 CT 3) ; ,"2 ' ' ,"1 '012'{~ >{ i.&.> $~3 +--------+------------+ | 0 0 0| 000 001 002| | 0 0 1| 010 011 012| | 0 _1 0| 020 021 022| | | | | 0 0 _1| 100 101 102| | 0 0 0| 110 111 112| | 1 0 0| 120 121 122| | | | | 0 1 0| 200 201 202| |_1 0 0| 210 211 212| | 0 0 0| 220 221 222| +--------+------------+ (CT 3) -: C.!.2&> { i.&.> $~ 3 1 ] m=: ?. 3 3$10 6 5 9 2 4 9 0 7 0 +/ , (CT #m) * *// m _252 -/ .* m NB.行列式 _252