一、基本操作
本課程有編程作業,編程作業需要使用Matlab或Octave,本文章使用Octave。下載地址:http://www.gnu.org/software/octave/#install。安裝完成后,打開GNU Octave (GUI)開始寫代碼。
1、基本運算
值得注意的是Octave使用“^”符號表示次冪,而不是向其他語言一樣表示異或,而異或運算使用xor()函數。並且不等於使用“~=”而不是“!=”。
% 基本運算 5 + 6 3 - 2 5 * 8 1 / 2 % 0.5 2 ^ 6 % 2的6次方 1 == 2 % false,返回0 1 ~= 2 % 1不等於2,true,返回1 1 && 0 % AND 1 || 0 % OR xor(1, 0) % 異或 PS1('>> ') % 修改提示符
2、變量、打印
注意:當Octave變量聲明語句后面不帶分號(“;”)時,Octave會打印該變量,故不需要打印的務必加分號。
disp方法也可以用於打印,該方法支持較復雜打印,可以組合字符串和數字。如 disp(sprintf('2 decimals: %0.2f', a));。
% 變量 a = 3; % 數字變量,double。加分號不打印出來 b = 'hi'; % 字符串變量 c = (3 >= 1); % 返回1 a = pi; % 打印 disp(a); disp(sprintf('2 decimals: %0.2f', a));% C風格 disp(sprintf('6 decimals: %0.6f', a)); % 顯示長變量 format long % 打印小數點后15位 a % 顯示短變量 format short % 打印小數點后四位 a
format long打印小數點后15位數字(注意是總共打印15位,而不是最后15位的意思),format short打印小數點后4位數字。
3、矩陣、向量
一般用大寫字母表示矩陣,例如A、B、X等;用小寫字母表示向量,例如v、w。
% 矩陣和向量 A = [1 2; 3 4; 5 6] % 3×2矩陣 v = [1 2 3] % 1×3向量 v = [1; 2; 3] % 3×1向量 v = 1: 0.1: 2 % 1到2,步長為0.1 v = 1: 6 ones(2, 3) % 生成一個2×3且全部元素為1的矩陣 C = 2 * ones(2, 3) % 矩陣和數 數乘運算 w = zeros(1, 3) % 1×3向量且全部元素為0 w = rand(1, 3) % 1×3的隨機矩陣,數據大小在0-1之間 rand(3, 3) % 3×3隨機矩陣 w = randn(1, 3) % 高斯隨機變量? w = -6 + sqrt(10) * (randn(1, 10000)); % 繪制直方圖 %hist(w); hist(w, 50) eye(5) % 生成5×5的單位矩陣(對角線元素為1,其余全為0)
注意到聲明矩陣的每一行時,用空格分隔每個元素,其實使用逗號也是可以的。語句v = 1:0.1:2表明按照步長0.1生成一個行向量,元素為[1 1.1 1.2 ....... 2]。語句v = 1:6的步長為1,不指定步長默認為1,生成[1 2 3 4 5 6]向量。
二、移動數據
1、獲取大小、長度
A = [1 2; 3 4; 5 6] sz = size(A) % 返回[3 2],分別表示行數和列數 size(A, 1) % 返回行數 size(A, 2) % 返回列數 % 返回長度4,length函數返回最大維度的大小 % 若矩陣為10×1,則長度為10。通常對向量使用length函數 v = [1 2 3 4] length(v)
使用size函數可求得矩陣的行數與列數,使用size(A,1)取得行數,使用size(A, 2)取得列數。
length函數會返回長度最長的長度,如length(A)返回3,通常對向量使用length函數。
2、一些常用命令
pwd % 查看當前所在目錄 % cd 'path' % 改變當前目錄 ls % 列出當前所有文件 clc % 清空控制台輸出 who % 查看工作空間所有變量 whos % 查看工作空間所有變量的細節 % clear data % 清空(刪除)data變量 % clear % 清空所有變量 load hello.txt % 加載數據並賦值,注意:這樣加載不能賦值到變量中 data = load('hello.txt') % 也可以這樣加載 save hello.mat v % 將變量v存入hello.mat文件中
一些命令的運行結果如下:
3、訪問、修改矩陣和向量
A(3, 2) % 取第3行第2列的數據 A(3, 2) = 10 % 將第3行第2列賦值為10 A(2, :) % 取出第2行數據, :表示某一行或某一列的所有數據 A(:, 2) % 取出第2列數據 A([1 3], :) % 取出第1行和第3行所有數據 A([1;3], :) % 一樣,取出第1行和第3行所有數據 A(:, 2) = [10; 11; 12] % 修改第2列 A = [A, [100; 101; 102]] % 附加1列作為最后一列 A(:) % 將A所有元素按列形成一個列向量 A = [1 2; 3 4; 5 6] B = [11 12; 13 14; 15 16] C = [A B] % A和B按列連接形成C(3×4)矩陣 C = [A; B] % A和B按行連接形成C(6×2)矩陣
使用冒號可以很方便的取出某一行或某一列的數據。訪問和修改數據只需要使用下標即可。值得注意的是,在修改矩陣某一列或添加一列的時候賦值的向量一定要和矩陣的行數相同,否則報錯。同理,修改一行時需要和列數相同。
三、矩陣、向量運算
1、基本運算
A = [1, 2; 3, 4; 5, 6] % 3x2矩陣 B = [11, 12; 13, 14; 15, 16] % 3x2矩陣 C = [1, 1; 2, 2] % 2x2矩陣 A * C % 矩陣乘法 A .* B % 矩陣對應元素相乘 A .^ 2 % 矩陣每個元素都做平方運算
A' % A的轉置
v = [1; 2; 3] 1 ./ v % 向量每個元素取倒數 log(v) % 每個元素取對數 exp(v) % 每個元素進行指數運算 abs(v) % 每個元素取絕對值
矩陣乘法需要左矩陣的列數與右矩陣的行數相同,例如A矩陣為3x2,C矩陣為2x2,他們相乘后得到3x2矩陣。
點乘運算為“.*”,兩個矩陣點乘需要為同型矩陣,同型矩陣就是行數和列數都一樣的矩陣。同理還有“.+”、“.-”、“./”等運算,當兩邊都是矩陣時需要同型。
若點乘的時數字,如A .^ 2,這個運算就是矩陣中的每個元素都做平方運算。同理A.-2就是每個元素減2。
log函數、exp函數、abs函數對每個元素分別就行求對數、求指數、求絕對值。
2、查找、求和
使用max函數查找最大值,使用find函數查找滿足條件的元素下標。
a = [1, 15, 2, 0.5] [val, ind] = max(a) % 返回最大值以及最大值的下標 a < 3 % 返回所有值的比較結果,小於則返回1, 大於則返回0 find(a < 3) % 僅返回那些小於3的值的下標 A = magic(3) % 返回魔術矩陣,該矩陣每行、每列、對角線、副對角線之和均相等 [rows, cols] = find(A >= 7) % 返回行下標和列下標 sum(a) % 求和 prod(a) % 所有元素相乘 floor(a) % 向下取整 ceil(a) % 向上取整 round(a) % 四舍五入 max(rand(3), rand(3)) % 對應元素對比,較大者存入新矩陣 max(A, [], 1) % 找到每一列的最大值組成向量 max(A, [], 2) % 找到每一行的最大值組成向量 max(A) % 等價於max(A, [], 1) max(max(A)) % 找到矩陣最大值,等價於max(A(:)) A = magic(9) sum(A, 1) % 求出每一列之和 sum(A, 2) % 求出每一行之和 sum(A) % 等價於sum(A, 1) A .* eye(9) % 取對角線元素 sum(sum(A .* eye(9))) % 求對角線元素之和 flipud(eye(9)) %翻轉形成副對角 sum(sum(A .* flipud(eye(9)))) % 副對角元素求和 A = magic(3) pinv(A) % 求逆矩陣
a<3將a向量中每個元素與3比較,小於的返回1,大於的返回0,這樣每個元素的真假值組成一個向量。而find函數則是返回符合條件的所有元素的下標。
四、繪制圖像
繪制圖像使用plot函數,plot函數繪制的是曲線圖。繪制函數主要是使用向量(行向量或列向量均可)給出x軸和y軸的一系列點,每個點(x,y)繪制在二維坐標系上,再將這些點連線。
t = [0: 0.01: 0.98];% x軸 y1 = sin(2 * pi * 4 * t); % sin函數,函數值,y軸 plot(t, y1); y2 = cos(2 * pi * 4 * t); % cos函數 plot(t, y2); % 繪制后sin函數會被cos替代
上圖的函數一起繪制的話sin函數會被cos函數覆蓋。
要使得兩個函數繪制在同一個窗口中,需要使用hold on命令。此外使用xlabel、ylabel、legend、title分別制動x軸標簽、y軸標簽、圖例和標題。
plot(t, y1); hold on; % 在同一個坐標系上繪制 plot(t, y2, 'r'); % 繪制為紅色 xlabel('time') % x軸標簽 ylabel('value') % y軸標簽 legend('sin', 'cos') % 圖例 title('my plot') print -dpng 'myPlot.png' % 保存為圖片文件 close; % 關閉圖像
還可以使用figure命令打開多個窗口,用數字對窗口編號。
% 打開兩個窗口 figure(1); plot(t, y1); figure(2); plot(t, y2);
還可以使用subplot函數將窗口分為多個格子,指定在某一格子繪圖。用axis指定x軸的范圍和y軸的范圍。
subplot(1, 2, 1) % 將畫板分為1×2的格子,並使用第1個格子繪制 plot(t, y1); subplot(1, 2, 2) % 使用第2個格子 plot(t, y2, 'r') axis([0.5 1 -1 1]) % 前兩個是x的范圍,后兩個是y的范圍 clf; % 清除所有繪制圖像
還可以對矩陣繪制,每一格表示一個數值,元素數值越大越接近黃色。對於繪制灰色圖像,數值越大越接近白色。這可以幫助我們直觀了解矩陣內元素的大小關系。
A = magic(5); imagesc(A), colorbar; % 可視化矩陣,繪制為彩色 imagesc(A), colorbar, colormap gray; % 繪制為灰白色
五、控制語句
和其他語言基本一樣,不一樣的是沒有花括號包住語句,取而代之的是縮進和end。
v = zeros(10, 1); % for for i = 1 : 10, v(i) = 2 ^ i; end v % 打印,下面的同理 indices = 1:10; for i = indices, disp(i); end % while i = 1; while i <= 5, v(i) = 100; i = i + 1; end v % if break i = 1; while true, v(i) = 999; i = i + 1; if i == 6, break; end end v % if、elseif、else v(1) = 2; if v(1) == 1, disp('The value is one'); elseif v(1) == 2, disp('The value is two'); else disp('The value is not one or two'); end;
函數的編寫與其他語言差別較大,Octave函數可以返回多個返回值。多返回值用逗號隔開。y1和y2是返回值,Octave不使用return語句返回,而是在函數體內直接對返回變量賦值。
function [y1, y2] = squareThisNumber(x), y1 = x ^ 2; y2 = x ^ 3; end
調用函數
[val1, val2] = squareThisNumber(10) % 調用函數
打印輸出
六、向量化
若我們要求解θ0x0 + θ1x1 + θ2x2 + θ3x3 + θ4x4 +θ5x5。為向量化的實現可能是使用for循環實現。
但如果使用向量化將令θ = [θ0; θ1; θ2; θ3; θ4; θ5](l列向量),令 x = [x0; x1; x2; x3; x4; x5](列向量)。
這樣只需要用θTx就可求解θ0x0 + θ1x1 + θ2x2 + θ3x3 + θ4x4 +θ5x5。極大方便了我們的運算。稱之為向量化。