APL/J言語:M.(ラージエムドット、メモ)

APL/J言語:M.(ラージエムドット、メモ)
u M.というように使います。作用はuのみの場合と同じであるが、引数と結果をキープして後で使用できるようにします。。再帰(リカーシブ)に作用させる場合によく使われます。

以下の例では、メモ化(memoization)の効果による違いを示します。fib nはn番目のフィボナッチ数です。pnは整数のパーティションの数をオイラーによる再現関係式を用いて算出します。下記サイトの等式11を参照して下さい。
http://mathworld.wolfram.com/PartitionFunctionP.html .

fib=: 3 : 0 M.
if. 1>:y do. y 
else. (fib y-1)+fib y-2 
end.
)

fibx=: 3 : 0
if. 1>:y do. y 
else. (fibx y-1)+fibx y-2 
end.
)

   timer=: 6!:2

   timer 'fib 32'
0.000479377
   timer 'fibx 32'
43.696

   fib"0 i.18
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

pn =: -/@(+/)@:($:"0)@rec ` (x:@(0&=)) @. (0>:]) M.
pnx=: -/@(+/)@:($:"0)@rec ` (x:@(0&=)) @. (0>:])
rec=: - (-: (*"1) _1 1 +/ 3 * ]) @ (>:@i.@>.@%:@*1

   timer 'pn 28'
0.000675355
   timer 'pnx 28'
61.7146

   pn"0 i.18
1 1 2 3 5 7 11 15 22 30 42 56 77 101 135 176 231 297
   pn 1000
24061467864032622473692149727991

メモ化された動詞を一度使った引数に再度適用すると、高速化します。

   timer 'fib 32'
2.62393e_5
   timer 'pn 28'
4.01456e_5

M>(ラージエムドット、メモ化)は名称を持たない動詞に使えます。また結果がアトムでない動詞にも使えます。

   timer '+/@:($:"0)@:(-&1 2)`]@.(1>:]) M. 32'
0.000186387
   timer '+/@:($:"0)@:(-&1 2)`]@.(1>:])    32'
8.61349

comb=: 4 : 0 M.   NB. i.yの中のすべてのサイズxのコンビネーション
if. (x>:y)+.0=x 
do. i.(x

*1:2%3)&*