MATLABで関数を実装してみよう。

8回目のMATLAB記事です。

今回は「関数（function）」の実装方法を説明します。

関数ときくと、数学の関数 $y=f(x)$ を想像するかもしれません。**ある入力 $x$ が決まったら出力 $y$ の値が決まる数式**の事ですね。

プログラミングにおける関数は**機能**と考えた方が、何かと理解しやすいと思います（実際、functionの日本語訳の一つは「機能」となっています）。

どのような機能かというと**入力に手を加えて別の何かに変換する**機能です。数学の関数 $y=f(x)$ も、入力 $x$ を別の値 $y$ に変換する機能を持っていると、解釈できます。

関数を上手に使えば普段のプログラミングがかなり楽になることでしょう。


# 関数の定義

MATLABでは以下のようにして関数を定義します。

```matlab
function y = f(x)
 %%%%%%%%%
 %処理内容
 %%%%%%%%%
 y = 〇〇;
end
```

$y=f(x)$ という例を出したので、その通りに記述してみました。

function で書き始めると、それが関数だと宣言することになります。後は処理内容を書けば使用できます。使用方法は後述します。

さて、関数を実装する上で我々は以下のことを決めなければなりません。

1. 作る目的
2. 名前
3. 入力の個数
4. 出力の有無
5. 中身

これらを一つずつ見ていきましょう。

## 作る目的

そもそもプログラミングで関数を実装し、それを使う状況とは一体どんなものなのか。一言でいえば**目的がある**からです。それも便利な方向へ導くための。

例えば、以下のような状況を考えます。

```
ある30人のクラスで5教科のテスト（国数英理社）を行いました。
結果をまとめるために生徒ごとに合計点、平均点を求めたいとします。
ただし、手元にあるのは各生徒の5教科の点数だけとします。
```

ありきたりな状況です。やる事としては、5教科の合計点と平均点を30人分求めることです。

言葉にすると簡単そうですが、実際に行うのは非常に面倒な作業ですね。手計算なんて想像しただけで嫌になりそうです。電卓があれば、まあ高々30人分なので、根性論に持っていけそうですが、それでも...。

そこで、Excelにデータをうちこんで、SUM関数とAVERAGE関数を使おうとするでしょう。その方がミスがないし、なにより楽ですから。

プログラミングにおける関数も考え方もこれと一緒です。頻繁に行う作業を関数にしておく、つまり機能としてまとめておくことで、作業を円滑に進めることができます。

関数を実装する前に、まず**その目的を明確に**しましょう。


## 名前
次に名前です。先ほどの例だと「f」の部分です。

```matlab
function y = f ←この部分(x)
 %%%%%%%%%
 %処理内容
 %%%%%%%%%
 y = 〇〇;
end
```

今回は $y=f(x)$ という先の例もあって、この名前にしました。

しかし、関数の名前は**パッと見て**その機能が分かりやすいものにしましょう。そうでない名前は基本的に好まれません。

また、関数の中身が長くなりそうなら**コメントアウト**も利用して詳細を残しておきましょう。時間が経って見返すと、自分でもそのプログラムが何をしているのか、分からなくなることがよくあります！

なお、MATLABにおけるコメントアウトは以下のようにして行います。

```matlab
% 左端に「%」で1行のみコメントアウト

%{
     %{　と　%}　で囲むことで複数行のコメントアウト
%}
```


## 入力の個数

プログラミングにおいて、関数の入力のことを**引数**といいます。先ほどの例だと引数は「x」の部分です。

```matlab
function y = f(x ←この部分)
 %%%%%%%%%
 %処理内容
 %%%%%%%%%
 y = 〇〇;
end
```

例の引数は x のみですが、実際は目的に合わせて何個も設定可能です。


## 出力の有無

プログラミングにおいて、関数の出力のことを**戻り値**といいます。先ほどの例だと「y」の部分です。

```matlab
function y ←この部分 = f(x)
 %%%%%%%%%
 %処理内容
 %%%%%%%%%
 y = 〇〇;
end
```

実装の際、出力の有無を決めることができます。

”え、関数なのに出力が無いことってあるの？” と思うでしょう。実はプログラミングの関数ではそれがあります。

この場合、関数の定義は出力部分を消して以下のように書きます。

```matlab
function f(x)
 %%%%%%%%%
 %処理内容
 %%%%%%%%%
end
```

冒頭で、入力を何か別のものに変換する機能を持つのが関数だと説明しました。

ここでは変換するというより**使用する**と解釈してください。

例えば、入力の値をディスプレイに表示するという関数であれば、出力を必要としません。入力は何かに変換してませんが、それ自体はちゃんと使ってますね？ そういうことです。


## 中身

所望の結果を実現する処理内容（機能）を書きましょう。

なお、出力がある場合はその値を確定する文を書かないと関数として役割を果たせませんのでご注意ください。

```matlab
function y = f(x)
 %%%%%%%%%
 %処理内容   ←この部分
 %%%%%%%%%
 y = 〇〇;   ←この部分
end
```

# 関数の例

今回は練習ですので、本当にシンプルな関数を実装します。題材は以下の二次関数です。

```math
\begin{equation}
y=x^2 + 3x + 2
\end{equation}
```

この関数をMATLABでは以下のように実装します。ここで注意です。mファイル名と関数名は**必ず一緒に**してください。

```matlab:f.m
function y=f(x)
    y = x.^2 + 3*x + 2;
end
```

2乗の部分が「.^」になっているの理由は、行列が引数に渡されても正しく $y$ の値を計算してもらうためです。

というか、目的にもよりますが、引数に行列を想定しない関数を実装しても実用性はほぼ無いでしょう。

では実装した関数を使ってグラフを描いてみましょう。

```matlab:sample1.m
% f.mとsample1.mは同じフォルダに入れてください！

x = -3:0.1:0;
y = f(x);
plot(x,y, 'LineWidth', 2)
title('y = x^2 + 3x + 2')
xlabel('x')
ylabel('y')
xlim([x(1), x(end)])
grid
set(gca, 'FontSize', 13)
```

ここで、f.mとsample1.mは同じフォルダに入れてください。同じフォルダに入れるというは以下のような状態です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736302/80671e50-9c6a-c5b6-046a-325845f741dd.png" width=50%>


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736302/910d0a96-15be-4d6f-fd88-e2741a854daa.png" width=70%>


ちゃんと描画できましたね。

関数のmファイル（f.m）と、それを使用するmファイル（sample1.m）を別々にしましたが、以下のように一つにまとめることもできます（sample2.m）。

```matlab:sample2.m
x = -3:0.1:0;
y = f(x);
plot(x,y, 'LineWidth', 2)
title('y = x^2 + 3x + 2')
xlabel('x')
ylabel('y')
xlim([x(1), x(end)])
grid
set(gca, 'FontSize', 13)

function y=f(x)
y = x.^2 + 3*x + 2;
end
```
この場合も同じグラフが描画されます。お好きな方を選んでください。


# 関数は必ず下側に

もし、sample2.mにおいて**関数部分とそれ以外とを入れ替えた**上で実行したらどうなるでしょうか？

```matlab:sample2.m
function y=f(x)
y = x.^2 + 3*x + 2;
end

x = -3:0.1:0;
y = f(x);
plot(x,y, 'LineWidth', 2)
title('y = x^2 + 3x + 2')
xlabel('x')
ylabel('y')
xlim([x(1), x(end)])
grid
set(gca, 'FontSize', 13)
```

その答えはエラーが出ます。

```
エラー: ファイル: sample2.m、行: 5、列: 1
このステートメントはどの関数の内部にも含まれていません
 (関数 "f" の定義を閉じる END の後にあります)。
```

これはMATLABの作法が原因です。**関数は必ず下側に書かなければなりません**。

関数を上に持ってきたり、関数以外のプログラム文で挟んだりするとエラーが出ます。気を付けてくださいね。


# まとめ

今回は関数の実装方法を説明しました。

関数を自分で考え、自由に実装できるようになれば、MATLABに限らずプログラミングの技術がさらにパワーアップすると思います。

必要だと感じたらぜひ実装してみてください。


# 終わりに

数学の「関数」と「方程式」の違いを理解していますか？

関数は冒頭で説明した通り、ある入力が決まったら出力の値が決まる数式のことです。

一方で、方程式の主旨はある等式を満たす解を見つける事です。高校数学で習う二次方程式は、使用文字が $x$ であれば等式をみたす $x$ を見つければいいわけです。これについては、有名な解の公式がありますね。

両者はそれぞれの持つ意味が全然違います。この事実は知っておくべきでしょう。

なお、関数が方程式の解となることもあります。それ（その一つ）が**微分方程式**です。

微分方程式は世の中に存在する現象を理解、および記述するために人間が生み出した方法の一つです。

例えば自動車の運転、工場のタンクシステム等、微分方程式は我々の生活に関わる色んな場所で活躍しているのです。

よろしければ次回の記事も読んでくださると大変嬉しいです。

※本記事に対する改善点や修正点、またはこんな事が知りたいといったご意見がありましたらぜひご連絡ください。