数式を実装するを考えるにあたっての基本的な考え方

f:id:lib-arts:20200121234017p:plain

『数式を実装するってどうやったらどうやったら良いでしょうか?』のような質問をたまにいただくのですが、改めて考え直すと意外とコツがいるなと思われたので、数式を実装に落としていくにあたっての基本的な考え方を簡単にまとめておこうと思います。
数式を実装に変換するにあたってはある程度パターン化できる話ですが、具体的に数式と実装を対照的に並べる構成が多く、意外と変換にあたっての考え方を言語化している解説は少ない印象のため、その辺を考慮しながらまとめていければと思います。
以下目次になります。
1. 数式をプログラミングするとはどういうことか
2. 数式のプログラミングのパターン(演算、関数、方程式)
3. まとめ

 

1. 数式をプログラミングするとはどういうことか
1節では数式をプログラミングするにあたって前提の整理を行えればと思います。

数学における数式(すうしき、mathematical expression, mathematical formula)は、数・演算記号・不定元などの数学的な文字・記号(および約物)が一定の規則にのっとって結合された、文字列である。

数式 - Wikipedia

まず数式ですが、上記がWikipediaの記載の冒頭です。数や演算記号や文字が一定の規則にのっとって結合された文字列と記述されています。ちょっと表現が難しいのと、プログラムに変換していくという文脈的にそれほど厳密な理解は必要ないため、この記事においては「方程式」や「関数」を数式だと考えるものとします。
さて、この数式をプログラムの形式に変換するわけですが、簡単にプログラムについても改めて言葉を抑えておきます。

コンピュータプログラム(英:computer program)とは、コンピュータに対する命令(処理)を記述したものである。

プログラム (コンピュータ) - Wikipedia

要するにコンピュータ上で実施する処理を記述したものをプログラムであるとされています。

上記を元に考えると、数式をプログラミングするというのは「方程式の計算や関数の計算などをコンピュータ上で実行すること」と考えて良さそうです。以下はこちらの考えに基づいて詳細の話を進めて行きます。

 

2. 数式のプログラミングのパターン(演算、関数、方程式)
2節では具体的に数式のプログラミングについて見ていきます。数式にも色々とありますが、今回は基本的な考え方について確認できればと思うので、演算、関数、方程式について見ていきます。実装については比較的簡単に用いることができるPythonを用いていきます。
まず演算についてですが、1+43×8などの通常の数の四則演算から、行列演算まで様々な演算があります。こちらについては下記のように簡単に実装できます。

print(1+4)
print(3*8)

f:id:lib-arts:20200121232550p:plain

上記は単なる四則演算ですが、Pythonの場合、ライブラリのNumPyを用いて行列関連の演算も簡単に行うことができます。

import numpy as np

a = np.array([[1,2],[3,4]])
b = np.array([[2,1],[1,1]])

print(a)
print(b)
print("====")
print(a+b)
print(a.dot(b))

f:id:lib-arts:20200121232611p:plain

上記では簡単な行列の和と積を計算しています。基本的な数字の演算については和や積をそのまま記述することで実装ができるようになっています。一方で行列の積などの少し難しい演算は言語のプリインのライブラリに入っていないケースの方が多く、PythonにおけるNumPyなどの別途実装されたライブラリを用いることが多いです。

次に関数の実装について見ていきます。関数の実装については関数の定義を行います。Pythonの場合はdefを用いて実装します。下記ではf(x)=x^2を実装してみます。

def f_x2(x):
    return x**2

print(f_x2(1))
print(f_x2(2))
print(f_x2(3))
print(f_x2(-2))

f:id:lib-arts:20200121233801p:plain

プログラミングにおける関数と数式における関数の対応としては数式におけるxが引数、f(x)が返り値とされていると抑えておけば良いです。また、Pythonの場合は下記のようにNumPyとmatplotlibを組み合わせることでグラフの描画も行うことができます。

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

def f_x2(x):
    return x**2

x = np.arange(-2,2.1,0.1)
f_x = f_x2(x)

plt.plot(x,f_x)
plt.show()

f:id:lib-arts:20200121233836p:plain
関数の実装などは大体の言語で似たような記法で記述することができますが、この辺のグラフの描画などは言語やライブラリによって色々と変わることが多いので、よく使う言語ではある程度覚えておく方が良いと思います。

次に方程式の実装について見ていきます。方程式の実装方法は2パターンあります。1つ目は方程式を数式的に解いた上で値を計算するという方法です。たとえばf(x)=x^2+2axの最小値問題を求めるにあたっては、f'(x)=2x+2a=0を解くわけですが、この際にx=-aとなるので、実装上はxに-aを代入するだけで値を求めることができます。
2つ目のアプローチとしては方程式を繰り返し演算を用いて解くアプローチです。f(x)=x^2の例における勾配法について考えますが、x_{0}=2\alpha=0.25x_{n+1}=x_{n}-\alpha f'(x_{n})を解くと考えると、x_{n+1}=0.5x_{n}となります。こちらを実装に変換すると下記のようになります。

x = 2
for i in range(10):
    print(str(i)+":"+str(x))
    x = 0.5*x

f:id:lib-arts:20200121235030p:plain

このように方程式を実装するにあたっては大きく分けて二つのアプローチがあります。


3. まとめ
演算や関数については比較的直感的に実装できますが、方程式の実装についてはある程度慣れが必要だと思うのでいくつか例を見ながら確認を行うと良いのではと思います。