概要
Mathematicaの標準関数Table
は例えば
In := Table[i^2,{i,1,5}]
Out = {1,4,9,16,25}
のように, ダミー変数i
を含んだ形で書かれる.
ダミー変数を使うことで変数が局所化され, i
の定義に関係なく式が評価されるようになる.
この記事では, このようなダミー変数を含む自作の関数の作り方について解説する.
実装
問題
次のような挙動をする関数を実装できれば十分だろう.
In := val[f[t],t,a]
Out = f[a]
ここでval
の各引数は
- 第1引数: ダミー変数を含む関数
- 第2引数: ダミー変数の指定
- 第3引数: ダミー変数の値の指定
を表している.
解答
この実装にはBlock
とSetAttributes
を用いて次のようにする.
In := SetAttributes[val, HoldAll]
val[f_,t_,a_]:=Block[{t=a},f]
1行目は関数val
に対してHoldAll
属性を与えている.
このHoldAll
属性はval
の全ての引数の評価を事前に行わない事を意味している.
http://reference.wolfram.com/language/ref/HoldAll.html
これでダミー変数が事前に定義されていたとしても問題なく動作するようになる.
2行目のBlock
は変数t
を局所的なものとして扱うためである.
http://reference.wolfram.com/language/ref/Block.html
要するにこれだけである.
以下ではもう少し補足的説明を与える.
誤答例
この実装までに幾つかの試行錯誤があった
Block
の代わりにReplaceAll
, Function
, Module
, With
を使えば次のように書ける.
In := SetAttributes[val1, HoldAll]
val1[f_,t_,a_]:=f/.t->a
SetAttributes[val2, HoldAll]
val2[f_,t_,a_]:=Function[t,f][a]
SetAttributes[val3, HoldAll]
val3[f_,t_,a_]:=Module[{t=a},f]
SetAttributes[val4, HoldAll]
val4[f_,t_,a_]:=With[{t=a},f]
ReplaceAll
以外の関数はt
が事前に定義されていたとしても問題なく評価される.
In := t=1;
{val[s^2,s,2], val[t^2,t,2]} (*Block*)
{val1[s^2,s,2], val1[t^2,t,2]} (*ReplaceAll*)
{val2[s^2,s,2], val2[t^2,t,2]} (*Function*)
{val3[s^2,s,2], val3[t^2,t,2]} (*Module*)
{val4[s^2,s,2], val4[t^2,t,2]} (*With*)
Out = {4,4}
{4,2}
{4,4}
{4,4}
{4,4}
ReplaceAll
での結果が{4,1}
とならずに{4,2}
となっているのは, 1
$(=1^2)$が2
に置換されたためである.
ではFunction
, Module
, With
を用いた実装がBlock
と同じかと言えば, そうではない.
次の例を見る.
In := u=v^2
val[u,v,2] (*Block*)
val1[u,v,2] (*ReplaceAll*)
val2[u,v,2] (*Function*)
val3[u,v,2] (*Module*)
val4[u,v,2] (*With*)
Out = 4
4
v^2
v^2
v^2
関数がダミー変数を含んだ遅延評価で定義される場合では, このような違いが生まれるのである.
標準関数Table
も次のようにBlock
の場合と同じ挙動を示す.
In := j=i^2;
Table[j,{i,1,5}]
Out = {1,4,9,16,25}
これらの挙動の違いはHULINKS blogの次の記事が分かりやすいかも知れない:
http://blog.hulinks.co.jp/2011/06/with-module-and-block-in-mathematica.html
よもやま話
標準関数でのダミー変数
Mathematicaでダミー変数を扱う標準関数はTable
の他にもPlot
がある.
しかし一見ダミー変数を扱っているように見えても, 実際には扱っていない関数も存在する.
次に幾つかの例を示そう.
ダミー変数を使うもの (変数が局所化される)
Table
Plot
NDIntegrate
ダミー変数を使わないもの (変数が局所化されない)
D
Integrate
Solve
D
においてダミー変数が使われていないのは, 次のような評価を想定しているためかも知れない.
In := D[2 Sin[x], Sin[x]]
Out = 2
(しかしこのような使い方は挙動が安心できないので避けるべきではある..)
(NIntegrate
とIntegrate
とで挙動が違うのは些か恐ろしく感じる)
ダミー変数の呼び方
便宜的に「ダミー変数」と書いたが, これはMathematicaでの正式な用語ではないようである.
http://reference.wolfram.com/language/ref/Table.html にはTable
の変数の扱いについて次のような記述があり, 「ダミー変数」とは書かれていない.
Tableは,Blockを使って実質的には値や変数を局所化する.
Mathematicaのシンタックスハイライタのオプションにはダミー変数について次のようにも書かれている.
日本語: 引数に使うことで特別な意味を持つ変数
英語: Valiables made special by use in arguments
シンタックスハイライタ
Mathematicaのnotebook上ではこれはlocal scope conflict(構文警告)としてシンタックスハイライトされるが, 問題なく評価される. (次画像の赤字)
前述のTable
, Plot
などの標準関数ではダミー変数のシンタックスハイライトが機能するが, ここで扱った自前関数のダミー変数はシンタックスハイライトされていない.
Mathematicaにはそのようなカスタマイズ機能は無いように見えたが, もしご存知の方が居ればコメントして頂けると幸いである.
ダウンロード
本記事の内容を含んだnbファイルは以下からダウンロード出来る.
https://www.dropbox.com/s/w6xotj3bli9kmeu/DummyVariables.nb?dl=0
他参考資料
標準評価手順 (Wolfram ドキュメントセンター):
https://reference.wolfram.com/language/tutorial/TheStandardEvaluationProcedure.html
数学のダミー変数 (Wolfram ドキュメントセンター):
http://reference.wolfram.com/language/tutorial/DummyVariablesInMathematics.html.ja