4

別のスレッドThe best way to construct a function with memoryでは、関数をファイルに戻す方法が説明されていました。

$runningLogFile = "/some/directory/runningLog.txt";
flog[x_, y_] := flog[x, y] = f[x, y] /.
v_ :> (PutAppend[Unevaluated[flog[x, y] = v;], $runningLogFile]; v)

これがどのように機能するかを正確に理解していなくても、ここの成分のほとんどを理解しているように感じます. 誰かがこれがどのように評価されるかを正確に説明してくれる可能性はありますか?

4

1 に答える 1

2

flog[1, 2]の評価を順を追って説明しましょう...

フロッグ[1, 2]

この式が評価されると、Mathematica は質問のgivenの定義でand 1forを置き換えます。これにより、ツアーの次のステップが得られます。x2yflog

flog[1, 2] = f[1, 2] /. v_ :> (PutAppend[Unevaluated[flog[1, 2] = v;], $runningLogFile]; v)

ここでの割り当て は、それ自体flog[1, 2] = ...の定義の一部であることに注意してください。flog

/.ReplaceAll関数 の代替表現である中置演算子です。ReplaceAll最初の引数の値に置換規則を適用します。その考えを保持してください-私たちはそれに戻ります. 最初の引数はflog[1, 2] = f[1, 2]. この式は評価されf[1, 2]、結果が に割り当てられflog[1, 2]ます。f[1, 2]議論のために、 が を返すと仮定しましょう345。したがって、新しい定義がflog、つまりに追加されますflog[1, 2] = 345。代入後、次の定義を確認できますflog

フロッグ精細

where にflogは最初は 1 つの定義しかありませんでしたが、現在は 2 つあることに注意してください。新しく追加されたflog[1, 2]定義は、その呼び出しの結果をキャッシュします。これはよく「メモ化」と呼ばれます。

flog[1, 2] = 345の新しい定義を確立するという副作用があるかもしれませんが、flogMathematica のすべての式と同様に、値も生成されます。値は345、苦労の末、 の最初の引数になりReplaceAllます。

の 2 番目の引数は、 RuleDelayed関数の中置式である演算子ReplaceAllの呼び出しです。この投稿を扱いやすいサイズに保つために、このコンテキストではルールがそれ自体に評価されることに注意してください。:>

これで、評価を伴う式ができました/....

345 /。v_ :> (PutAppend[Unevaluated[flog[1, 2] = v;], $runningLogFile]; v

置換式は、最初の引数 ( 345) を置換規則のパターン コンポーネント( ) と一致させv_ます。 v_一致345(またはそれ以外のもの) に一致し、置換の目的で 345名前を付けます。次に、ルールの右側に出現するすべてのを置換します。結果は、評価される次の式です...vReplaceAll345v

(PutAppend[未評価[flog[1、2] = 345;]、$runningLogFile]; 345)

ここでは、セミコロンで区切られた 2 つの式があります。ちなみに、はCompoundExpression;に展開される中置演算子です。最初の式には、2 番目の引数の値として指定されたファイルに最初の引数の値を書き込むPutAppendが含まれます。ただし、最初の引数はUnevaluatedでラップされていることに注意してください。これにより、最初の引数の評価が抑制され、ファイルにそのまま書き込まれます: . 現在の Mathematica セッションが終了した場合、書かれた式を将来の Mathematica セッションに読み込んで、 のメモ化された結果を再構築できます。flog[1, 2] = 345;flog[1, 2]

CompoundExpression最後の引数を除くすべての引数の値を破棄します。ここで、最後の引数は345です。式の最後に到達したため、これが元の呼び出しの最終的な戻り値になります。つまり、flog[1, 2]戻り値です。345ただし、後で参照できるように、この結果をメモリとディスクに保存するという副作用がありました。

今後の呼び出しflog[1, 2]

flog[1, 2]が再度呼び出されると、 Mathematica は新しい定義 を見つけますflog[1, 2] = 345345上記で説明した複雑さはなく、直接返されます。特に、再度呼び出すことさえありませんf[1, 2]。もちろん、これがこの例の全体的な動機でした。計算に非常にコストがかかるという仮定はf、これらすべての体操を正当化して、計算の回数を最小限に抑えることを正当化するものでした。

于 2012-07-31T03:56:29.070 に答える