Mathematicaのオプションの名前付き引数
-
06-07-2019 - |
質問
オプションの名前付き引数を使用して関数を定義するための最良/標準的な方法は何ですか?具体的には、名前付き引数 a
、 b
、および c
を指定して、デフォルトの関数 foo
を作成しましょう。それぞれ1、2、および3。比較のために、位置引数を指定した foo
のバージョンを次に示します。
foo[a_:1, b_:2, c_:3] := bar[a,b,c]
foo
の名前付き引数バージョンのサンプル入力および出力は次のとおりです。
foo[] --> bar[1,2,3]
foo[b->7] --> bar[1,7,3]
foo[a->6, b->7, c->8] --> bar[6,7,8]
もちろん、名前付き引数の前に位置引数を付けるのも簡単です。
解決
Mathematicaのドキュメントで標準的な方法を見つけました: http:// reference .wolfram.com / mathematica / tutorial / SettingUpFunctionsWithOptionalArguments.html
Options[foo] = {a->1, b->2, c->3}; (* defaults *)
foo[OptionsPattern[]] := bar[OptionValue@a, OptionValue@b, OptionValue@c]
" OptionValue"と入力毎回少し面倒です。何らかの理由で ov = OptionValue
のようなグローバルな省略形を作成することはできませんが、これを行うことができます:
foo[OptionsPattern[]] := Module[{ov},
ov[x___] := OptionValue[x];
bar[ov@a, ov@b, ov@c]]
またはこれ:
With[{ov = OptionValue},
foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
]
またはこれ:
$PreRead = ReplaceAll[#, "ov" -> "OptionValue"] &;
foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
他のヒント
はい、 OptionValue
は少し難しい場合があります。
OptionValue [name]
は、OptionValue [f、name]
と同等です。ここで、f
は、OptionValue [name]
が表示される変換ルール。
通常、明示的な Automatic
を投げることでうまくいくので、あなたの場合、解決策は次のようになります。
Options[foo] = {a -> 1, b -> 2, c -> 3};
foo[OptionsPattern[]] :=
bar @@ (OptionValue[Automatic, #] &) /@ First /@ Options[foo]
ところで、オプションは opts:___?OptionQ
に一致し、その後 {a、b、c} /。Flatten [{ opts}]
。パターンチェック OptionQ
は(ドキュメントに記載されていませんが)まだありますが、 OptionValue
アプローチには、存在しないオプション(たとえば foo [ d-> 3]
)。これは2番目の応答にも当てはまりますが、受け入れた応答には当てはまりません。
この解決策をミックスに追加します:
foo[opts___Rule] := Module[{f},
f@a = 1; (* defaults... *)
f@b = 2;
f@c = 3;
each[a_->v_, {opts}, f@a = v];
Return[bar[f@a, f@b, f@c]]
]
その簡潔さで気に入っていますが、標準的な方法だとは思いません。その方法で何か問題がありますか?
PS、次の便利なユーティリティ関数を使用します:
SetAttributes[each, HoldAll]; (* each[pattern, list, body] *)
each[pat_, lst_, bod_] := (* converts pattern to body for *)
Scan[Replace[#, pat:>bod]&, Evaluate@lst] (* each element of list. *)