Wolfram言語

Wolfram言語とは?

Wolfram言語はMathematicaの文 法と同じであり,関数型をベースとしている.そのため,「Mathematica 基礎」と検索して見つかる資料が使える.Wolfram言語は計算論に出てくる帰納関数やλ計算の理解に非常に役立つ.非常に豊富なライブラリを備えているため,覚えておくと今後非常に役に立つはずである.

各セルにおいてShift + Returnをすることでプログラムを実行できる.たとえば

1 + 1

と打ってShift + Returnをすると

2

と表示される.関数のマニュアルは,関数名の前に ? を付けると調べることができる.例えば,Plot関数のマニュアルは

?Plot

と打ってShift + Returnすると表示される.C言語とは違い,変数は変数のまま計算可能である.例えば

f = 1 / (1 + x^3)

とした場合,これの微分は

D[f, x] => (-3*x^2)/(1 + x^3)^2

で求まり,積分は

Integrate[f, x] 
    => ArcTan[(-1 + 2*x)/Sqrt[3]]/Sqrt[3] + Log[1 + x]/3 - Log[1 - x + x^2]/6

によって計算することが可能である.

式をShift + Returnで評価すると結果が表示されるが,結果を表示させないこともできる.それにはセミコロンを用いる.

x = 10

とすると,評価と同時に10という数字も表示される.

x = 10;

とすると,評価の結果は表示されない.

基本

代入

x = 10

関数定義

F[x_]:=x+10;
F[2] => 12

二変数関数は

G[x_,y_]:=x^y;
G[2,4]
    => 16

と定義する.

特定の値だけ,異なる定義も可能である.例えば

MyDiv[x_,y_]:=x/y
MyDiv[x_,0]:=1

とすると,割る値が0の場合だけ1を返す関数にすることが出来る.

C言語と同様に条件分岐も当然使うことが出来る.例えば

F[x_]:=If[x>0,x,-x]

は絶対値の関数となる.

Wolfram言語は関数型言語なため,For文やWhile文によるプログラミングはあまり推奨されないが,当然使うことが出来る.

sum=0;
Do[sum = sum + i, {i ,1, 100}];
sum

と書けば,1から100までの和を計算する.

nまでの和を計算するプログラムは(下で説明しているModuleを使って)

F[n_]:=Module[{sum},
  sum=0;
  Do[sum = sum + i, {i ,1, n}];
  sum
]

と書くことが可能である.

データ構造

Wolfram言語の基本データ構造はリストである.

a = {1,4,9,16,25}

は長さが5のリストである.リストの各要素にアクセスするには

a[[3]] 
  => 9

のようにする.範囲でアクセスするには

a[[2;;4]] 
  => {4,9,16}

とする.リストの生成はTable関数が便利である.例えば

Table[i^2, {i,1,4}] 
  => {1,4,9,16}

のように,連続する値を出力することが出来る.

行列はリストのリストである.例えば

m={{1,2,3},{4,5,6},{7,8,9}}

は2行3列の行列を表す.要素へのアクセスは

m[[2,2]] 
  => 5

のようにする.

Matlabのように,行列のスライスが可能である.上の行列mの部分行列(1,2行2,3列の部分行列)にアクセスするには

m[[1;;2, 2;;3]]
    => {{2, 3}, {5, 6}}

のように書く.代入においても同様の記法を用いることが出来る.また,直接リストによって指定することもできる.上と同じことは以下のコードでも可能である.

m[[{1, 2}, {2, 3}]]
    => {{2, 3}, {5, 6}}

グラフのプロット

Mathematicaで最も使う関数の一つがPlot関数である.例えば,Sin[x]をx=0から4πまでプロットするには

Plot[Sin[x], {x, 0, 4 Pi}]

と入力する.以下のような図が出力される.

プロットする線の色を変えることもできる.例えば以下の入力では,線の色が赤になる.

Plot[Sin[x], {x, 0, 4 Pi}, PlotStyle -> Red]

二つの関数の同時プロットも可能である.Sin[x]とCos[x]を同時にプロットするには以下のようにする

Plot[{Sin[x], Cos[x]}, {x, 0, 4Pi}]

データのプロットも可能である.例えば以下のデータがあるとする.

data = {{1, 1}, {2, 4}, {3, 9}, {4, 16}}

ここで,二つの値の組はxとyの値を表す.このデータを散布図としてプロットするには以下のListPlot関数を用いる.

ListPlot[data]

このようなListPlotを使うシチュエーションでは,しばしば,解析解との比較を行う場合がある.上のListPlotの結果をx^2の解析的なグラフと重ね合わせるには以下のように入力する.

p1 = Plot[x^2, {x, 0, 4}, PlotStyle -> Red];
p2 = ListPlot[data];
Show[p1, p2]

ここでは,見やすいようにx^2のプロットの線を赤色に指定している.

ルール適用

Wolfram言語ではルールによる書き換えを多用する.例えば,x^2+y^2のxに2,yに3を代入する場合

x^2 + y^2 + 1/.{x->2, y->3}
  => 14

と書くことで,ルール適用による置換が可能である.これは導関数を関数定義する場合に使える.

例えば,x^2の微分したものをF[x]として定義する場合を考える.これを単純に

F[x_]:=D[x^2, x]

と定義すると,たとえばF[3]とした場合に上手く計算できない.なぜなら,関数を呼び出した時点でxに3が代入されてしまい,3^2を3で微分するという意味になってしまうからである.そこで,以下のように書き換える

F[x_]:=D[y^2, y]/.y->x

こうすることで,F[3]とすると正しく6という答えを得ることが可能である.

ラムダ式

Wolfram言語ではラムダ式を扱うことができる.λ式は,Function関数か,#記号を用いる.λx.f(x)はMathematicaでは

g = Function[{x},f[x]]

と表される.例えばM = λx.(x^2+x+1)に対してM(3)は

g = Function[{x,},x^2+x+1]
g[3] => 13

となる.直接

Function[{x},x^2+x+1][3] => 13

なども可能である.より省略した記法も可能である.

(#^2+#+1)&

Function[{x},x^2+x+1]

と同じ意味である.

C言語の関数ポインタと同じように使えるので,例えばソートにも使える.

Sort[{"ABCD", "XY", "12345"}]

を実行すると,そのままでは辞書式に並べ替えるので

{"12345", "ABCD", "XY"}

という答えとなる.仮に,文字数をキーとして並べ替えたいならば,以下のようにラムダ式を用いる.

Sort[{"ABCD", "XY", "12345"}, StringLength[#1] < StringLength[#2] &]

この式で#1,#2は第一引数,第二引数を表し,StringLengthは文字の長さを返す.実行すると

{"XY", "ABCD", "12345"}

となり,所望の結果が得られる.

関数型プログラミング

Mathematicaは関数型のプログラミング言語である.そのため,C言語のようにfor文で要素にアクセスするのではなく,listに対して関数を適用することで計算する.特に,Map,Apply,Nestなどの関数を良く用いる.

Map関数は,リストに対して一度に関数を適用する.

Map[Sin, {1, 2, 3, 4, 5}]
  => {Sin[1], Sin[2], Sin[3], Sin[4], Sin[5]}

上の式は,以下の表現と全く同じである.

Sin/@{1, 2, 3, 4, 5}
  => {Sin[1], Sin[2], Sin[3], Sin[4], Sin[5]}

当然,適用する関数にはλ式を使うことができる.

Map[Function[{x}, x^2], {1,2,3,4}]
    =>{1, 4, 9, 16}

手続き型プログラミング

Wolfram言語は関数型の言語であるが,C言語などのような手続き型のようにもプログラムすることが可能である.そのためにはModuleと呼ばれる関数を用いる.

Module[{ローカル変数},
  手続き
]

ローカル変数は,Moduleの外からは参照することが出来ない.例えば,以下のような関数を定義してみる.

MyFunc[x_,y_]:=Module[{a,b,c},
  a=x^2;
  b=y^2;
  c=Sqrt[a+b];
  c
]

この関数は,三平方の定理を逐次的に計算している.

SetとSetDelayedの違い