Mathematicaで式の計算結果を関数の定義に使う場合にはコロンが不要であることについて
自分用の覚書。手元のMathematicaはMathematica8。バージョン依存性があるかどうかは知らない。
複雑な式を展開や因数分解をして整理した結果(例えば、ヘロンの公式の導出 Sqrt[ a^2 b^2 - ( a^2 + b^2 - c^2 )^2/4 ]/2 を展開して因数分解して)を、関数 f[a_,b_,c_] として定義して、再利用しようとして引っかかったのでメモ。
mathematica 関数 定義 コロン でググると「関数の定義にコロンを使う」という説明が(Wolfram社以外のサイトで)目立つが、関数の定義にコロンは必要ない。コロンの有無の違いは即時的な定義と遅延的な定義にある。
Wolfram言語で割当てを行うには,2つの違った方法があることに読者はすでに気が付いているかもしれない.つまり, lhs=rhs と lhs:=rhs である.これらの形の間にある基本的な違いは,いつ式 rhs が評価されるかにある. lhs=rhs は即時型の割当てを表し,右辺 rhs は定義した時点で評価される.これに対して, lhs:=rhs は遅延型の割当てを表し,rhs は,割当てが行われるときには評価されず,lhs の値が要求されるときに毎回評価される.そして関数の定義に関して次の記載がある;
http://reference.wolfram.com/language/tutorial/ImmediateAndDelayedDefinitions.ja.html (2015.7.28アクセス)
Although := is probably used more often than = in defining functions, there is one important case in which you must use = to define a function. If you do a calculation, and get an answer in terms of a symbolic parameter x, you often want to go on and find results for various specific values of x. One way to do this is to use the /. operator to apply appropriate rules for x in each case. It is usually more convenient, however, to use = to define a function whose argument is x.(おそらく)Mathematicaの計算結果は式や値の評価を済ませた結果であり、遅延評価が適用可能な「評価前の入力コマンド的なもの」になり得ないので、コロンを用いた関数の定義をすると、引数に代入した式や値の評価が行われない。
関数の定義では「コロン+等号」は「等号」よりもおそらく頻繁に用いられるけれども、関数の定義に「等号」を必ず用いねばならない重要な場合がある。それは計算を実行し、シンボリックな変数 x を用いた式が得られたときに、引き続きこの式の x にさまざまな値を代入したい場合である。x に何か適当なルール(式や値)を代入するには「スラッシュ+フルストップ」を用いてその都度計算する方法もあるが、「等号」を使って x を変数とする関数を定義する方が大抵の場合、便利である。(…てゆーか、計算結果を関数として再利用したいときに「コロン+等号」ではできない。)
http://reference.wolfram.com/language/tutorial/ImmediateAndDelayedDefinitions.en.html (2015.7.28アクセス)
したがって、例えば、ヘロンの公式の関数の作成は
Sqrt[a^2 b^2 - (a^2 + b^2 - c^2)^2/4]/2となる。左辺の「変数」にはアンダースコア*1を必ず付ける。アンダースコアは「任意の式を表す」記号である。
Expand[%^2]
Factor[%]
Sqrt[%]
f[a_, b_, c_] = % (*等号の前にコロンは書かない*)
f[p, q, r]Out[1]= 1/2 Sqrt[a^2 b^2 - 1/4 (a^2 + b^2 - c^2)^2]
Out[2]= -(a^4/16) + (a^2 b^2)/8 - b^4/16 + (a^2 c^2)/8 + (b^2 c^2)/8 - c^4/16
Out[3]= -(1/16) (a - b - c) (a + b - c) (a - b + c) (a + b + c)
Out[4]= 1/4 Sqrt[-(a - b - c) (a + b - c) (a - b + c) (a + b + c)]
Out[5]= 1/4 Sqrt[-(a - b - c) (a + b - c) (a - b + c) (a + b + c)]Out[6]= 1/4 Sqrt[-(p - q - r) (p + q - r) (p - q + r) (p + q + r)]
*1:なぜかMathematicaサイトでは「ブランク」"blank"と呼ばれている