簡単なプログラミング(2)

演習問題を行う前に 1-2. Mathematica を使うときの注意を良く読んでください.


内容

  1. ルールベースドプログラミング
  2. 演習問題

ルールベースドプログラミング

プログラミングといえば、手続き型言語の FORTRAN や C言語が頭に浮かぶかも知れませんが Mathematica ではそれと少し違ったようにプログラミングすることができます。
それはルールベースドプログラミングといって、簡単にいうと数式を書き換えるルールを定義することでプログラミングを行ないます。実際の計算は、それを適用することによって行なわれます。こういっただけでは良くわからないと思うので、実際例をあげてみましょう。

goukei を定義する

今、自然数 n が与えられた時に 1 から n までの合計を計算する関数 goukei を定義することを考えます。つまり、

[Graphics:98_4_web.txtgr1.gif][Graphics:98_4_web.txtgr2.gif]

です。ここで goukei は数学的には次のように定義できることに注意します。

[Graphics:98_4_web.txtgr3.gif][Graphics:98_4_web.txtgr2.gif]

そこで、Mathematica にこれをルールとして教えてあげます。

入力
出力
入力
出力

きちんと定義されているかチェックします。

入力
出力

これでプログラミングは終りです。実際に goukei[10], goukei[100] を
計算してみましょう。

入力
出力
入力
出力

これで、計算できるのは不思議な気がするかも知れないので計算課程を追ってみます。まず、goukei[10] が入力されたとします。すると、まず (1) のルールが適用できるかどうか調べられますが、10 は 0 でないのでこれは適用されません。次に (2) のルールが適用できるかどうか調べられます。これは n=10 とおけば適用できるので、

[Graphics:98_4_web.txtgr13.gif][Graphics:98_4_web.txtgr2.gif]

と置き換わります。
次に、goukei[9] に対して (1) のルールが適用できるかどうか調べられますが、これも適用されないので次に (2) のルールが適用できるかどうか調べられ n=9 とおかれて

[Graphics:98_4_web.txtgr14.gif][Graphics:98_4_web.txtgr2.gif]

と置き換わります。このようにして goukei[0] が出てくるまで計算が続き、最後に goukei[0] に (1) のルールが適用され、 0 に置き換わって計算が終了します。つまり、次のようにして計算が進みます

[Graphics:98_4_web.txtgr15.gif][Graphics:98_4_web.txtgr2.gif]

上の計算は、数学的帰納法に少し似ていると思ったかも知れません。しかし、ルールベースドプログラミングは数学的帰納法に限らず、もっと一般的な数学のルールに用いることができます。次に log を定義してみます。

log を定義する

良く知られている通り、log は次のような性質を持っています。

[Graphics:98_4_web.txtgr16.gif][Graphics:98_4_web.txtgr2.gif]

このルールを Mathematica に教えてあげます.

入力
出力
入力
出力

log[x^3 * y * z^4] を計算します。

入力
出力

これは、次のように計算されています。

[Graphics:98_4_web.txtgr22.gif][Graphics:98_4_web.txtgr2.gif]

最小値を計算する

前回、手続き型のプログラミングを用いて、リストが与えられたとき、その中の最小値を返す関数を作りました。同じ事をする関数をルールベースドプログラミングを用いてやってみましょう。

これを行うためには Drop[] という関数が必要です。Drop[] は与えられたリストから指定された要素を除いたリストを返す関数です。list をリスト、n を自然数とすると

Drop[list, {n}]

は、list からn 番目の要素を除いたリストを返します。例えばリスト {a,b,c,d} から 2番目の要素 b を除いたリストを得るには

入力
出力

とします。

さて、リスト list が与えられたとき、list を1番目の値 list[[1]] と残りの要素 Drop[list, {1}] の2つに分けると

list の最小値 = ( Drop[list, {1}] の最小値 )  と (  list[[1]]  )  の小さい方

であることは明らかです。よって小さい方を返す関数 small を次のように定義すると

入力
出力

最小値を返す関数 saisyoti は次のように定義できる。

入力
出力

ただし、list の要素が1つの時は、その要素が最小値なので

入力
出力

となる。これでプログラミングは終わりです。リスト {1,-3,10} の最小値を計算してみよう。

入力
出力

ちゃんと最小値が計算されました。この計算は次のように行われています。

そろそろルールベースドプログラミングの考え方に慣れてきたと思うので、不定積分を行なう関数 sekibun を定義してみましょう。

sekibun を定義する

まず、x^n, Cos[x], Sin[x] の変数 x に関する積分

を Mathematica にルールとして教えてあげます。

入力
出力
入力
出力
入力
出力
入力
出力

次に積分の線形性

を定義します.

入力
出力
入力 [Graphics:test.txtgr23.gif]
出力

今までの定義をチェックします。

入力
出力







簡単な計算をしてみます。

入力
出力
入力
出力

次にこれだけでは面白くないので、部分積分をルールとして
加えてみましょう。t^n * f[t] の部分積分は次のようになりますね。

[Graphics:98_4_web.txtgr2.gif]

これを Mathematica にルールとして教えてあげます。

入力 [Graphics:test.txtgr31.gif]
出力
入力 [Graphics:test.txtgr32.gif]
出力

定義したルールをチェックします。

入力
出力
















部分積分を用いる計算をしてみます。
(だたし、最後の D[%,t] は直前の出力を t で微分する命令です)

入力
出力
入力
出力
入力
出力
入力
出力
入力 [Graphics:test.txtgr41.gif]
出力
入力
出力
この計算は結構複雑ですが、計算課程は次のようになっています。 [Graphics:98_4_web.txtgr2.gif]

ここで定義した sekibun は限られた関数しか積分できませんが、Mathematica のIntegrate も基本的には同じように、ルールをたくさん定義し、それを適用することによって計算を進めています(正確にいうと、もう少し高等な技術を使っていますが)。興味のある人は、自分でいろいろルールを追加することによっていろいろな関数が積分できるようにしてみて下さい。


演習問題

(1)自然数 n が与えられたとき、n の階乗を計算する関数 kaijo[n]をルールベースドプログラミングを用いて定義し、 10! と 100! を計算せよ.

(2) 微分を行う関数 bibun[f[x],x] をルールベースドプログラミングを用いて定義し、次の関数の微分を行え.また計算結果が正しいことを Mathematica の内部関数 D[f[x],x] を用いて確かめよ。

(3)次の関数をルールベースドプログラミングを用いて、定義せよ.ただし、関数 Sum[]、Max[] を用いるのは禁ずる.

  1. 数値のリストを与えたとき、そのリストの要素の最大値を計算する関数 saidaiti

    実行例:
    入力
    出力

  2. 数値のリストを与えたとき、そのリストの要素の和を計算する関数 listsum

    実行例:
    入力
    出力