文章目錄
- 擴充矩陣大小
- 縮小矩陣
- 重塑矩陣形狀
- 預先指定記憶體空間
擴充矩陣大小
擴充任何已經存在的矩陣大小,使其依然為矩形。如4成3的矩陣與7乘3的矩陣,豎直串連,因為每一行都有三列。
擴充矩陣大小的兩種方法:
Ø 串連新的元素到當前矩陣
Ø 將資料存放區到當前矩陣範圍之外
注意:如果打算不斷的擴充矩陣大小以要求更多空間(通常是在迴圈裡出現),最好是在當初定義它的時候就預先定義好它的大小。
串連矩陣
串連是一個非常有用的操作,當希望通過添加元素或者與原始矩陣尺寸匹配的模組來擴充一個矩陣時。這意味著所有將要串連的矩陣在連接維上的大小是相等的。
例:使用一個使用者自訂函數compareResults操作矩陣裡的資料stats04 和 stats03。每次迴圈時,將函數的結果資料儲存在comp04的末尾。
col = 10;
comp04 = [];
for k = 1:50
t = compareResults(stats04(k,1:col), stats03(k,1:col));
comp04 = [comp04; t];
end
串連結構體或Cell陣
串連到結構體陣或者CELL的操作與操作普通矩陣類似。
例:產生一個3乘8的結構體矩陣S,每一項有域:X,Y,Z。接著串連第二個結構陣S2。
產生一個3乘8的結構矩陣S:
for k = 1:24
S(k) = struct('x', 10*k, 'y', 10*k+1, 'z', 10*k+2);
end
S = reshape(S, 3, 8);
產生第二個3乘2的矩陣使用相同的網域名稱:
for k = 25:30
S2(k-24) = struct('x', 10*k, 'y', 10*k+1, 'z', 10*k+2);
end
S2= reshape(S2, 3, 2);
將S2水平串連到S
S = [S S2]
S =
3x10 struct array with fields:
x
y
z
添加一個較小的塊到矩陣
當尺寸並不匹配時,為了添加一個或更多元素到一個矩陣裡,可以簡單的將元素儲存到矩陣邊界之外。Matlab會自動的將矩陣擴充矩陣使它保持矩形。
構造一個3乘5的矩陣,並使用串聯的方法添加一個新的元素。這時操作會失敗,因為不能將一個單列矩陣串聯入一個有5列元素的矩陣。
A = [ 10 20 30 40 50; ...
60 70 80 90 100; ...
110 120 130 140 150];
A = [A; 160]
??? Error using ==> vertcat
All rows in the bracketed expression must have the same
number of columns.
重試,將使用另一種方法使得MATLAB能自動匹配矩陣大小。將新元素儲存在第四行,這一行在當前的矩陣中並不存在。MATLAB將會擴充矩陣A,添加一個新行,並將第二列到第五列的元素置0。
A(4,1) = 160
A =
10 20 30 40 50
60 70 80 90 100
110 120 130 140 150
160 0 0 0 0
注意:如果試圖讀取矩陣中並不存在的位置,將會報錯。只能寫入。
同樣,也可以通過添加一個矩陣而不是單個元素來擴充矩陣。
A(4:6,1:3) = magic(3)+100
A =
10 20 30 40 50
60 70 80 90 100
110 120 130 140 150
108 101 106 0 0
103 105 107 0 0
104 109 102 0 0
並不需要連續的添加矩陣元素,Matlab會自動的填充0元素使得在任意地方添加新元素時,仍然保持矩陣為矩形。
A(4,8) = 300
A =
10 20 30 40 50 0 0 0
60 70 80 90 100 0 0 0
110 120 130 140 150 0 0 0
0 0 0 0 0 0 0 300
擴充一個結構或者CELL矩陣
與操作普通矩陣相同。MATLAB填充空cell([])來保持它為矩形。
C = {'Madison', 'G', [5 28 1967]; ...
46, '325 Maple Dr', 3015.28}
添加一個cell元素到C{3,1},MATLAB就擴自動擴充C矩陣:
C{3, 1} = ...
struct('Fund_A', .45, 'Fund_E', .35, 'Fund_G', 20);
C =
'Madison' 'G' [1x3 double]
[ 46] '325 Maple Dr' [3.0153e+003]
[1x1 struct] [] []
擴充一個字元矩陣
操作與普通矩陣相同,但並不推薦以這種方式來擴充矩陣。MATLAB以0填充未被初始化的位置,但是MATLAB和其他程式設計語言都將0視為字串的終止,所以有時候會感覺一些函數處理擴充後字串時,似乎它變短了。
例:將一個5字元的字串擴充到12個字元。最初的結果看起來是一個正常的字串。
greeting = 'Hello'; greeting(1,8:12) = 'World'
greeting =
Hello World
轉換字串後觀察到,在擴充點處是字元終止符。
uint8(greeting)
ans =
72 101 108 108 111 0 0 87 111 114 108 100
這會導致在使用一些函數,如strcmp,會得到一些期望之外的結果。
strcmp(greeting, 'Hello World')
ans =
0
縮小矩陣
通過將賦予空矩陣值[]來刪除矩陣的行和列。
例:A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
刪除它的第二列:
A(:, 2) = []
則A矩陣變為:
A =
16 3 13
5 10 8
9 6 12
4 15 1
如果刪除矩陣中的單個元素,則結果將不再是一個矩陣。
例:A(1,2) = []
返回錯誤。但是,可以使用線性索引來刪除單個元素或者是一序列元素。這是矩陣會變成一個行向量:
A(2:2:10) = []
A =
16 9 3 6 13 12 1
重塑矩陣形狀
reshape:修改矩陣形狀;
rot90: 將矩陣旋轉90;
fliplr:左右翻轉;
flipud:上下翻轉;
flipdim:沿著指定維翻轉;
transpose:沿著主對角線翻轉矩陣,將行向量變成列向量,反之亦然;
ctranspose:對角共軛翻轉矩陣;
例:
Ø 重塑矩陣:將3乘4矩陣變為2乘6
A = [1 4 7 10; 2 5 8 11; 3 6 9 12]
A =
1 4 7 10
2 5 8 11
3 6 9 12
B = reshape(A, 2, 6)
B =
1 3 5 7 9 11
2 4 6 8 10 12
Ø 轉置矩陣 (.' 相當於transpose;' 相當於ctranspose)
B = A.'
B =
1 2 3
4 5 6
7 8 9
10 11 12
A = [1+9i 2-8i 3+7i; 4-6i 5+5i 6-4i]
A =
1.0000 + 9.0000i 2.0000 -8.0000i 3.0000 + 7.0000i
4.0000 -6.0000i 5.0000 + 5.0000i 6.0000 -4.0000i
B = A'
B =
1.0000 -9.0000i 4.0000 + 6.0000i
2.0000 + 8.0000i 5.0000 -5.0000i
3.0000 -7.0000i 6.0000 + 4.0000i
Ø 旋轉矩陣
B = rot90(A)
B =
10 11 12
7 8 9
4 5 6
1 2 3
Ø 翻轉矩陣
B = fliplr(A)
B =
10 7 4 1
11 8 5 2
12 9 6 3
預先指定記憶體空間
重複擴充矩陣尺寸(比如說在迴圈中每次都往矩陣添加元素)會影響程式的運行效率。這是因為:
Ø MATLAB在每次增加矩陣大小時都需要耗時去分配記憶體。
Ø 這些新指定的記憶體在記憶體空間內都不是連續的,因此會減慢所有對此矩陣的操作。
所以,最好估計矩陣大小的最大值,並在矩陣產生時預先分配好記憶體空間。這樣,程式運行於一個連續的記憶體塊。
例:預定義一個25,000乘10,000的矩陣,並將每一個元素初始化為0:
A = zeros(25000, 10000);
構造一個預定義大小的矩陣
當為估計的矩陣最大尺寸預定義記憶體空間後,可以將資料按需要儲存在矩陣內。
例:預定義一個大矩陣,從檔案中讀取資料到這個矩陣中直到檔案結束:
blocksize = 5000;
maxrows = 2500000; cols = 20;
rp = 1; %行指標
% 預定義A,可能的最大尺寸
A = zeros(maxrows, cols);
%開啟檔案,儲存檔案指標
fid = fopen('statfile.dat', 'r');
while true
%將檔案讀入一個cell陣。以分行符號結束。
block = textscan(fid, '%n', blocksize*cols);%檔案、格式、格式使用次數
if isempty(block{1}) break, end;
%將cell陣轉為矩陣,重塑,賦予A
A(rp:rp+blocksize-1, 1:cols) = ...
reshape(cell2mat(
block), blocksize, cols);
% Process the data in A.
evaluate_stats(A); % 自訂函數,略過
% 更新行指標
rp = rp + blocksize;
end