inv 再考
置換の表現には,リストタイプと巡回タイプとがあり,それぞれ積,逆元の実装に適していますが,今回のコードは根の置換という出自からリストタイプを利用しており,逆元の実装に工夫の余地がありました.現在公開中の inv は
inv(A):=map(second,sort(map("[",A,sort(A)),lambda([s,t],s[1]<t[1])))$
という sort ベースのもので
(%i3) L:random_permutation(makelist(i,i,1,10)); (%o3) [4,9,8,3,5,10,7,1,2,6] (%i5) for j:1 thru 10^5 do inv(L)$ Evaluation took 19.6490 seconds (19.6760 elapsed) using 2073.668 MB.
といった具合でした.これを積(左作用)
mul(A,B):=map(lambda([s],A[s]),B)$
と同じく成分をインデックスと見做し,第 i 成分が s である入力のリストに対して,第 s 成分が i であるリストを出力とするもの
inv(A):=block([B,i],B:A*(i:0),for s in A do B[s]:i:i+1,B)$
に変更すると
(%i7) for i:1 thru 10^5 do inv(L)$ Evaluation took 4.1150 seconds (4.1320 elapsed) using 482.180 MB.
という結果となりました.