---
title: 數學軟體實作 - Matlab-03
tags: 2020 Fall - 數學軟體實作
GA: G-77TT93X4N1
---
# `Matlab` 基礎 - Lecture 3
## M 檔案 - function
以下為一個程式範例, 雖然可以正確執行, 不過有個很大的問題是註解不足.
雖然它有註解, 所以對於**當初寫這程式的人**很容易看得懂並修改, 不過對**使用者**而言卻沒有將最重要的資訊顯示出來, 所以不確定要如何使用.
```matlab=
function assignment2(y) %function名稱
disp('頂標=') %顯示'頂標'
disp(y(ceil(70*0.88))) %取y的第88百分位的成績
end
```
> Question: 我應該丟什麼東西進去這函數?
### Rules
1. function_name 與`檔案名稱`需完全一樣
2. 需有詳盡的註解
* 需講清楚`input`與`output`的規格
* 最好有個簡單範例
> 以下這函數請將其存成 `average.m` 檔.
```matlab=
%% 求向量平均值的函數
function avg = average(x)
% input: x, a vector
% output: avg, the average value of x
%
% example
% > x = [1 2 3 4 5]
% > avg = average(x);
%
avg = sum(x)/length(x);
end
```
---
## 程式流程控制 - for loop
> ```
> For 變數 = 向量
> 運算式;
> end
> ```
```matlab=
%% for 迴圈
%
% 迴圈, 顯示1至5
for ii=1:5
ii
end
% 迴圈, 顯示 1, 3, 5, 7
for ii=1:2:7
ii
end
% 迴圈, 顯示 0.1, 7, -3, 5
for ii=[0.1, 7, -3, 5]
ii
end
```
### Example - 級數和
$$
\sum^N_{n=1} \frac{1}{n^2}
$$
```matlab=
%% 求級數前 N 項和
%
N = 100; % 100 項
sum_all=0; % 設定總和的初始值
for ii=1:N % 開始做加法
sum_all = sum_all + 1/ii^2;
end
disp(sum_all) % 印出結果
```
### Rules
1. 迴圈變數禁止使用`i`, `j`. (此為`Matlab`內建的虛數)
* 迴圈變數請用`ii`, `jj` 與 `kk`
#### 計時
在`Matlab`中計時可以用`tic-toc`
```matlab=
% 範例, 計算 1 加到 10^5 所需時間
tic
sum(1:10^5);
toc
```
## Exercise 3
1. 試寫一函數, 求 $\frac{1}{n}$ 的級數和:
$$
\sum^N_{n=1} \frac{1}{n}
$$
此函數`input`為 $N$.
試以你寫的函數求出 $N=10^7$, $10^8$ 以及 $10^9$ 的級數值, 並計算所花費的時間.
---
## 程式流程控制 - while loop
> ```
> while 條件式
> 運算式;
> end
> ```
```matlab=
%% while 迴圈
% 顯示 1, 3, 5, 7
ii=1
while ii<8
ii = ii+2
end
```
### Example - 暴力求根
假設想要在 $[0, 1]$ 找到 $\sin(x)=0.1$ 的解, 我們可以定義一個函數 $f(x) = \sin(x)-0.1$, 接著在 $[0, 1]$ 區間隨機取點, 如果在取到的點其函數值夠小我們就說找到解了!
通常我們會定義一個容許值(tolerance, $tol$), 如果 $|f(x)|<tol$ 就說找到解了!
```matlab=
% 求根: f(x) = sin(x)-0..1
%
tol = 10^(-5); % 設定誤差容許值
ff = 10; % 設一個初始值
while abs(ff) > tol % 如果函數值大於容許值則繼續找
x = rand(1); % [0, 1] 之間隨機取點
ff = sin(x)-0.1; % 計算函數值
end
disp('找到的根, x = ')
disp(x)
disp('其函數值:')
disp(ff)
```
---
## `matlab` 運算元
| 運算元 | |
|----|-------|
| == | 等於 |
| ~= | 不等於 |
| > | 大於 |
| >= | 大於等於 |
| < | 等於 |
| <= | 小於等於 |
| && | and |
| `||` | or |
| ~ | not |
---
## 程式流程控制 - if
> ```
> if 條件式
> 運算式;
> else
> 運算式;
> end
> ```
```matlab=
% 求根: f(x) = sin(x)-0..1
%
tol = 10^(-5); % 設定誤差容許值
ite_max = 1000; % 設定搜尋次數上限
ff = 10; % 設一個初始值
ii = 0; % 設定搜尋計數初始值
while abs(ff) > tol % 如果函數值大於容許值則繼續找
x = rand(1); % [0, 1] 之間隨機取點
ff = sin(x)-0.1; % 計算函數值
ii = ii+1; % 計算次數
if(ii>ite_max) % 如果大於搜尋次數上限則跳出
break
end
end
disp('找到的根, x = ')
disp(x)
disp('其函數值:')
disp(ff)
disp('搜尋次數:')
disp(ii)
```
### Rules - 好習慣
1. `while` 迴圈裡面一定要有一個 `if` 判斷計數上限, 不然很容易程式寫錯這個回圈就永無止盡地跑.
---
## Assignment 2
已知
$$
S_N = \sum^{N}_{n=1}\frac{1}{n}
$$
為發散級數, 趨近於無窮大.
試寫一函數, `input` 為 $x$, `output` 為 $N$ 並滿足
$$
S_N > x.
$$
## References
* [MATLAB程式設計:入門篇 - 張智星](http://mirlab.org/jang/books/matlabProgramming4beginner/)
* [2-4 程式流程控制](http://mirlab.org/jang/books/matlabProgramming4beginner/02-4_flowControl.asp?title=2-4%20%B5{%A6%A1%ACy%B5{%B1%B1%A8%EE)
* [14-2 關係運算元](http://mirlab.org/jang/books/matlabProgramming4beginner/14-2_relationalOperator.asp?title=14-2%20%C3%F6%ABY%B9B%BA%E2%A4%B8)
* [14-3 邏輯運算元](http://mirlab.org/jang/books/matlabProgramming4beginner/14-3_logicalOperator.asp?title=14-3%20%C5%DE%BF%E8%B9B%BA%E2%A4%B8)
* [16-1 迴圈指令](http://mirlab.org/jang/books/matlabProgramming4beginner/16-1_loop.asp?title=16-1%20%B0j%B0%E9%AB%FC%A5O)