# Matlab 簡易教學
###### tags: `note`
# 關於Matlab
[toc]

MATLAB(Matrix Laboratory)是由美國The MathWorks公司出品的商業數學軟體。
MATLAB是一種用於演算法開發、資料視覺化、資料分析以及數值計算的進階技術計算語言和互動式環境。
MATLAB主要用於數值運算,但利用為數眾多的附加工具箱,它也適合不同領域的應用。
## 開始使用
### 介面介紹
打開Matlab,首先介紹映入眼簾的介面
中上方那一條顯示目前文件位置
左方視窗顯示目前目錄
右方顯示變數名稱及其值
中間視窗顯示命令視窗可直接執行任何Matlab指令

### 開啟腳本
點選左上角即可開啟新的腳本,執行多個Matlab指令。
腳本將會顯示於介面中間

如果需要建立其他類型的腳本也可點選左上角+New建立更多其他類型的腳本
ex:函式
### 執行腳本
先按中左上方的Save儲存後接著按中上方的Run即可執行

### 酷酷的指令
以下為幾個酷酷的指令,在開始前可以先測試看看
```
version %檢視當前版本
ver %檢視當前版本
bench %測試電腦速度
```
### 新增Toolbox
如果已安裝Matlab但需要新增Toolbox時,不須重新安裝。
點選最上方
接著點選
進入後搜尋需要的Toolbox時即可

# 基礎語法
## 實用小提示
1.Matlab會將運算結果直接放在預設變數ans內

2.若不想每次都顯示結果可以加上分號
```
x=0+1;
y=1+1
```

3.建議執行腳本前可以在最上排輸入
clc;clear;close all;
即可清空
命令視窗;變數及其值;各個其他視窗(ex:plot)
4.要於命令視窗換行可以按Shift+Enter
5.加入註解的方式可使用百分比符號(%)
6.數學運算式,可以用三個句點(...)延長至下一行
```
x=1+1+1+1+1+1+1+1+1+...
+1
```

## 基礎運算、變數及數學函數
### 基礎運算
簡易的基礎運算 + - * /
```
1+1
2-2
3*3
4/4
5^5
```

### 變數
Matlab當然也可以自定義變數
```
x=(5+4-3)*2/3
y=x+1
```
 變數及值會顯示於右邊視窗 
### 數學函數
Matlab身為數學軟體也能簡易使用數學函式
以下為幾個簡易示範
```
x=2;
a=abs(x) %取x的絕對值
b=sin(x) %取x的正弦值
c=exp(x) %自然指數 exp(x)
d=log(x) %自然對數 ln(x)
e=sqrt(x) %對x開平方
```

### 複數
Matlab中不管i或j皆能代表單位虛數
```
x=1+2i
y=1+2j
```

```
x=1+2j;
a=angle(x) %x的相位角
b=real(x) %x的實部
c=imag(x) %x的虛部
d=conj(x) %x的共軛複數
e=x' %x的共軛複數
```

## 向量與矩陣
### 向量
這邊如果不使用逗號需要注意向量的格式
```
x=[1,2,3,4,5]
y=[1 2 3 4 5]
```

可以列等差級數的向量
```
x=1:0.3:5 %1開始<=5等差為0.3
```

#### 向量基礎運算
```
a=[1 2 3 4 5];
a+2
a-2
a*2
a/2
x=a*2+1
y=a.^2+1 %對每一個元素
```

#### 向量互相運算
需要長度一樣
如果要內積需要維度一樣
```
x=[1 2 3 4 5];
y=[2 2 2 2 2];
z=[3;3;3;3;3];
a=x+y
b=x-y
c=x.*y %對每一個元素
d=x./y %對每一個元素
e=x*z %內積
```

#### 針對內部元素
```
x=[1 2 3 4 5];
y=[2 2 2 2 2];
x(1)=2 %將向量x的第一個元素改為2
x(6)=6 %新增第六個元素值為6
x(2)=[] %將第二個元素刪除,[]意思是空集合
x(1)*2+y(5) %將x向量中的第一個元素*2+y的第五個元素取出運算
x(2:4)+1 %將第二到第四個元素加一
```

#### 特殊函數的使用方式
```
x=[1 2 100 4 500];
a=min(x) %向量x的最小值
b=max(x) %向量x的最大值
c=mean(x) %向量x的平均值
d=sum(x) %向量x的總和
e=sort(x) %將向量x排序
f=median(x) %向量x的中位數
g=prod(x) %向量的乘積
```

### 矩陣
直行(column)橫列(row)
建立矩證的方式
需要注意空格
```
x=[1 2 3;4 5 6;7 8 9]
y=[1 2 3 4;5 6 7 8;9 10 11 12]
```

#### 矩陣基礎運算
如同向量
可以直接做運算
```
a=[1 2 3;4 5 6;7 8 9];
a+2
a-2
a*2
a/2
x=a*2+1
y=a.^2+1 %對每一個元素
y=a^2+1 %沒加點就是矩陣相乘
```


#### 矩陣相互運算
一樣也需要維度一樣
```
x=[1 2 3;4 5 6;7 8 9]
y=[2 2 2;2 2 2;2 2 2]
a=x+y
b=x-y
c=x.*y
d=x./y
e=x*y %內積
```


#### 針對內部元素
```
x=[1 2 3 4;5 6 7 8;9 10 11 12]
x(1:2)=1 %將矩陣x第一行第二列的元素改為1
y=x(2,1:3) %將矩陣x第二橫列、第一至第三行取出並儲存成矩陣y
x=[x y'] %將矩陣y轉置後、再以行向量併入矩陣x
x(:,2)=[] %刪除矩陣x第二行(:代表所有橫列)
x=[x;1 2 3 4 ] %加入第四行至矩陣x
x([2 3],:)=[] %刪除矩陣第二、第三列
```


```
x=[1 2 3 4;8 7 5 6; 9 12 11 10]
a=x(end,:) %end代表保留某一維度最大值
b=x(:,end)
c=[1./x] %表示矩陣x每個元素的倒數
d=diag(x) %取出矩陣x對角線元素
e=reshape(x,6,2) %將矩陣重新排列成6*2的新矩陣e
```

#### 特殊函數的使用方式
由此可知 矩陣的話使用後結果會是每一行的
```
x=[1 2 100 4 500;5 7 800 4 900;7 5 200 3 800]
a=min(x)
b=max(x)
c=mean(x)
d=sum(x)
e=sort(x)
f=median(x)
g=prod(x)
```


#### 產生特殊功能的矩陣
```
zeros(2,2) %全0
ones(3,3) %全1
eye(4) %對角線1其他0
pascal(5) %帕斯卡矩陣
hilb(5) %hilbert矩陣
rand(5,5) %[0,1]均勻分佈的亂數矩陣
randn(5,5) % μ=0,σ=1的正規分佈亂數矩陣(常態分佈)
magic(5) %直行橫列對角線和相等的矩陣
```


希爾伯特矩陣


## 運算元
### 關係運算元
| 運算元 | 意思 | 備註 |
| ---- | ---- | ----|
| == | 等於 | =是賦值 |
| ~= | 不等於 | |
| < | 小於 | |
| <= | 小於或等於 | |
| > | 大於 | |
| >= | 大於或等於 | |
可以用來互相比較
```
x=[1 2 3;4 5 6;7 8 9]
y=[5 5 5;5 5 5;5 5 5]
a=x>y %true=1,false=0
b=x(a) %取出(可用sort排序)
```

或著跟數值比較
```
x=[1 2 3;4 5 6;7 8 9]
a=x>2
b=x(a)
```

尋找特定元素
數字用行來看
```
x=[1 0 3;4 0 6;7 8 9]
a=find(x) %找尋非0
x(a)
b=find(~x) %利用not找0
x(b)
c=find(x>3,2) %找矩陣x中大於3的前兩個元素
x(c)
d=find(x==7) %找矩陣x中數值是7的元素
x(find(4<x & x<8)) %找矩陣x中數值介於4和8的元素
```



### 邏輯運算元
| 運算元 | 意思 |
| ---- | ---- |
| & | AND |
| \| | OR |
| ~ | NOT |
|XOR|互斥或|
#### AND (*)

|A|B|Z|
|-|-|-|
|0|0|0|
|0|1|0|
|1|0|0|
|1|1|1|
#### OR (+)

|A|B|Z|
|-|-|-|
|0|0|0|
|0|1|1|
|1|0|1|
|1|1|1|
#### NOT

|A|O|
|-|-|
|0|1|
|1|0|
#### XOR

|A|B|O|
|-|-|-|
|0|0|0|
|0|1|1|
|1|0|1|
|1|1|0|
ex
```
x=[1 1 0;2 2 2; 0 0 3]
y=[0 1 0;0 0 2; 3 0 3]
a=x & y
b=x | y
c=~ x
d=xor(x,y)
```


#### 相關指令(all,any)
all 所有向量元素皆為-真-(非零),是則true,否則false。
any 任一向量元素皆為-真-(非零),是則true,否則false。
```
x=[0 1 2 3];
a=all(x)
b=any(x)
c=any(a<0)
```

也可用於矩陣
```
x=[1 2 3;4 5 6;7 8 9]
a=all(x>1)
```

### 集合運算元
|運算元|意思|
|-|-|
|union|聯集|
|intersect|交集|
|setdiff|差集|
|setxor|集合的XOR|
|unique|傳回最小等效級數(每個元素只出現一次)|
|ismember|測試元素是否為某集合|
```
x=[1 2 3 4 5 6];
y=[1 1 5 5 9 9 9];
a=union(x,y)
b=intersect(x,y)
c=setdiff(x,y) %只有x有
e=setxor(x,y) %互相都沒有的
f=unique(y)
g=ismember(9,y)
```

## 分支結構
### for

matlab中的基本語法為
For 變數 = 向量
運算式;
end
ex
```
x=[1 2 3 4 5];
for i=1:5
x(i)=x(i)*i;
end
disp(x)
```

ex
```
for i = 0:4
for j=0:i
fprintf("*")
end
fprintf("\n")
end
```

類似於C++中如下所示的寫法
```
for(i=0;i<5;i++){
for(j=0;j<=i;j++){
cout<<"x";
}
cout<<endl;
}
```
### while

matlab中的基本語法為
while 條件式
運算式;
end
ex
```
x=[1 2 3 4 5];
i=1;
while i<=5
x(i)=x(i)*i;
i=i+1;
end
disp(x)
```

### for與while不同之處
for: 明確知道要執行迴圈多少次
while: 不確定要執行迴圈多少次
當for(初始值;條件;迴圈結束後的變動)中
i會變動時,就適合用while
### if-else

matlab中的基本語法為
if 條件式
運算式;
else
運算式;
end
ex
```
x=randi(100); %取1-100之間的整數
if mod(x,2)==0 %取餘數
disp(x);fprintf('能被2整除')
%matlab'與"沒差
else
disp(x);fprintf('不能被2整除')
end
```

## 基本繪圖
### plot(stem)
基本繪圖指令有兩種
plot跟stem
```
x=linspace(1,20); %傳回包含1和20之間的100個等間距點的行向量。
y=2*x;
subplot(211)
plot(x,y);
subplot(212)
stem(x,y);
```

#### 多條曲線
可以同時繪製多條曲線
```
x=linspace(0,2*pi); %x=0:0.01:2*pi
y=sin(x);
subplot(211);plot(x,y);
subplot(212);plot(x,sin(x),x,cos(x),x,sin(x)+cos(x));
```

#### peaks
產生一個49*49的矩陣

```
x=peaks;
plot(x);
```

#### 其他指令
```
x=linspace(0,20);
y=2*x;
plot(x,y);
figure(2)
subplot(221);loglog(x,y); %x軸和y軸皆為對數刻度
subplot(222);semilogx(x,y); %x軸為對數刻度,y軸為線性刻度
subplot(223);semilogy(x,y); %x軸為線性刻度,y軸為對數刻度
subplot(224);plotyy(x,y,x,4*x); %畫出兩個Y軸
```

### 客製化
#### 線的客製
##### 線的顏色
|字串|顏色|
|-|-|
|B|藍|
|C|青藍|
|G|綠|
|K|黑|
|M|紫紅|
|R|紅|
|W|白|
|Y|黃|
##### 線的格式
|字串|格式|
|-|-|
|\-|實(預設)|
|\-\-|虛|
|:|點|
|\-.|點虛|
##### 線的線標
|字串|線標|
|-|-|
|o|圓形|
|+|加號|
|x|叉號|
|*|星號|
|.|點|
|∧|上三角|
|∨|下三角|
|>|右三角|
|<|左三角|
|square|方形|
|diamond|菱形|
|pentagram|五角形|
|hexagram|六角形|
```
x=linspace(0,2*pi);
y=sin(x);
plot(x,sin(x),'G-^',x,cos(x),'M:x',x,sin(x)+cos(x),'K-.pentagram');
```

### 其他客製
#### axis
```
axis([xmin,xmax,ymin,ymax])
```
#### subplot
```
subplot(m,n,p)
```
ex
221 222
223 224
#### grid
```
grid on; %開啟格線
```
### 說明文字
|指令|意思|
|-|-|
|title|標題|
|xlabel|x軸的註記|
|ylabel|y軸的註記|
|legend|多條曲線的說明|
|text|在圖形中加文字|
### 客製範例
ex1
```
clc;clear;close all;
n=-20:20;
x=exp((0.05+j*pi/4)*n);
xr=real(x);
xi=imag(x);
xamp=abs(x);
xpha=angle(x);
subplot(221);
stem(n,xr,'.');axis([-23 23 -3 3]);
xlabel('n');ylabel('xr');title('e^(^0^.^5^+^j^\pi^4^)^n的實部');
subplot(222);
stem(n,xi,'.');axis([-23 23 -3 3]);
xlabel('n');ylabel('xi');title('e^(^0^.^5^+^j^\pi^4^)^n的虛部');
subplot(223);
stem(n,xamp,'.');axis([-23 23 -3 3]);
xlabel('n');ylabel('xamp');title('e^(^0^.^5^+^j^\pi^4^)^n的振幅');
subplot(224);
stem(n,xpha,'.');axis([-23 23 -3 3]);
xlabel('n');ylabel('xpha');title('e^(^0^.^5^+^j^\pi^4^)^n的相位');
```

ex2
```
clear all;close all;clc;
wd=0.2*pi;N=21;M=(N-1)/2;
nn=-M:M;n=nn+eps;hd=sin(wd*n)./(pi*n);
w1=boxcar(N)';h1=hd.*w1;
w2=hanning(N)';h2=hd.*w2;
w3=hamming(N)';h3=hd.*w3;
w4=blackman(N)';h4=hd.*w4;
H1=20*log10(abs(fft(h1,1024)));
H2=20*log10(abs(fft(h2,1024)));
H3=20*log10(abs(fft(h3,1024)));
H4=20*log10(abs(fft(h4,1024)));
HH1=[H1(513:1024) H1(1:512)];
HH2=[H2(513:1024) H2(1:512)];
HH3=[H3(513:1024) H3(1:512)];
HH4=[H4(513:1024) H4(1:512)];
w=(-512:511)/512;
plot(w,HH1,w,HH2,':',w,HH3,'-.',w,HH4,'--');axis([-1.2 1.2 -150 20]);
legend('矩形窗','漢寧窗','漢明窗','布萊克曼窗');xlabel('\omega/\pi');
```

# 參考資料
1.淡江大學電機系新生程式先修
https://www.facebook.com/TKUECEProgram/?ref=page_internal
2.MATLAB程式設計:入門篇 Roger Jang (張智星)
http://mirlab.org/jang/books/matlabprogramming4beginner/
3.MATLAB 幫助中心
https://ww2.mathworks.cn/help/index.html
4.TKUEE Chi-Yi Tsai Digital Signal Processing 上課講義
5.TKUEE MTL 基礎通信實驗講義
6.https://ithelp.ithome.com.tw/articles/10243994
7.特別感謝extra 謝謝你!資工人我的超人!
https://github.com/leon890820
https://hackmd.io/@leon890820
滑鼠點擊跳躍 失敗需重新整理網頁
<iframe src="https://editor.p5js.org/leon890820/embed/fZiSz60OO" width=620 height=400></iframe>