|
2.2.10 構造操作
Mathematicaは,式の構造を変更するための強力な基本機能を備えている.それらの機能を使うことで,結合則や分配則等の数学的性質を規定することができ,また,分かりやすくて効率的なプログラムの土台を作ることができる.
本節では式の構成そのものを操作する方法を説明する.2.6.3において,式の頭部に対して適切な属性を割り当てることで,そのいくつかの操作を特定の頭部を備えたすべての式に自動的に適用可能にする方法を説明する.
Mathematicaの関数 Sort[expr]を使うことで,リストだけでなく,任意の頭部を持った式に対してその構成要素の並べ替えを行うことができる.この関数を使えば,結合性や対称性の数学的性質を任意関数に与えることができるようになる.
Sortを使い引数リストを標準的順序に並べ替える.
In[1]:= Sort[ f[c, a, b] ]
Out[1]= 

並べ替え操作と順序の判定
このSort式に与えた第2引数は,ペア要素が正しく並んでいるかどうかを判断するための条件式である.実行すると,リストの要素が降順に並べ替えられる.
In[2]:= Sort[ {5, 1, 8, 2}, (#2 < #1)& ]
Out[2]= 
条件式を与え, xに依存しない項が先にくるよう並べ替える.
In[3]:= Sort[ {x^2, y, x+y, y-2}, FreeQ[#1, x]& ]
Out[3]= 

式の平坦化
Flattenは,ネストした関数を平坦化してくれる.
In[4]:= Flatten[ f[a, f[b, c], f[f[d]]] ]
Out[4]= 
Flattenを使えば,リストや式に連番要素を「つぎはぎ」的に取り込むことができる.
In[5]:= Flatten[ {a, f[b, c], f[a, b, d]}, 1, f ]
Out[5]= 
Flattenを使い,数学でいう結合則に従った式を作成することができる.また,関数 Distributeを使えば,分配性や線形性等の性質を持った式を構成することもできる.

分配則の適用
fを式 a + bの各項に分配する.
In[6]:= Distribute[ f[a + b] ]
Out[6]= 
より複雑な例を示す.
In[7]:= Distribute[ f[a + b, c + d] ]
Out[7]= 
fを Plus式に分配させると,通常, f[a + b]のような式は f[a] + f[b]の形に「展開」される.関数 Expandは,同様な操作を Times等の標準的な代数演算子に対して行う.これに対して, Distributeを使うと,分配操作を任意の演算子について行うことができるようになる.
Expandは, Timesの分配則を Plus項に適用することで代数式の展開を行う.
In[8]:= Expand[ (a + b) (c + d) ]
Out[8]= 
今度は加法式ではなく,リストに fを分配させる.結果は,引数の組合せからなるすべての可能なペアを含んでいる.
In[9]:= Distribute[ f[{a, b}, {c, d}], List ]
Out[9]= 
リストに分配させるが,今度は,式の頭部が fだけの場合に限り分配を行う.
In[10]:= Distribute[ f[{a, b}, {c, d}], List, f ]
Out[10]= 
式全体の頭部が fのものに限りリストに分配操作を実施する.得られた結果では, Listの代わりに gpが使われ, fの代りに fpが使われる.
In[11]:= Distribute[ f[{a, b}, {c, d}], List, f, gp, fp ]
Out[11]= 
Distributeに関連した関数に Threadがある. Threadは,リストや式の要素に対して並列的に関数を適用させることができる.

式への並列的な関数の適用
引数がリストである関数を入力する.
In[12]:= f[{a1, a2}, {b1, b2}]
Out[12]= 
Threadを使い関数 fをリストの各要素に並列に適用する.
In[13]:= Thread[%]
Out[13]= 
リスト形式でない引数は繰り返し使われることになる.
In[14]:= Thread[ f[{a1, a2}, {b1, b2}, c, d] ]
Out[14]= 
1.8.1と,さらに,2.6.3でより詳しく説明してあるが,Mathematicaの組込み関数の多くは,そのままでリストに対して並列的に作用することができる.このため,引数として現れるリストなら,その要素に対して並列的に作用することができる.
Logのような組込み済みの数学関数は,リスト要素に直接適用可能なので,自動的にリストの各要素に作用する.
In[15]:= Log[{a, b, c}]
Out[15]= 
しかし,方程式の項には自動的に適用されない.
In[16]:= Log[x == y]
Out[16]= 
それでも, Threadを使えば,方程式の両辺に関数を作用させることができる.
In[17]:= Thread[%, Equal]
Out[17]= 

一般化された内積と外積
Outer[f, , ]は,複数リスト と の要素を可能な限りの組合せで掛け合わせ,その結果を fと組み合せる. Outerは,3.7.11で説明するテンソルの直積集合を一般化したものととらえることができる.
Outerは,要素の可能な限りの組合せを作り,それらに fを適用する.
In[18]:= Outer[f, {a, b}, {1, 2, 3}]
Out[18]= 
この例では, Outerは,下方三角形の ブール値行列を生成する.
In[19]:= Outer[ Greater, {1, 2, 3}, {1, 2, 3} ]
Out[19]= 
頭部が同じ式からなる式の列であれば,どんな列にでも Outerを適用することができる.
In[20]:= Outer[ g, f[a, b], f[c, d] ]
Out[20]= 
Distributeと同様に あらゆる組合せによる項を生成する.これに対して, Threadに似ている Innerは,位置が同じ要素同士だけを組み合せた項を生成する.
これは, Innerで構築された構造体である.
In[21]:= Inner[f, {a, b}, {c, d}, g]
Out[21]= 
Innerは, Dotが一般化されたものである.
In[22]:= Inner[Times, {a, b}, {c, d}, Plus]
Out[22]= 
|