使用 bsxfun
通常,程式碼在 for 迴圈中編寫的原因是計算附近程式碼中的值。功能 bsxfun 通常可用於以更簡潔的方式執行此操作。
例如,假設你希望對矩陣 B 執行逐列運算,從中減去每列的平均值:
B = round(randn(5)*10); % Generate random data
A = zeros(size(B)); % Preallocate array
for col = 1:size(B,2); % Loop over columns
A(:,col) = B(:,col) - mean(B(:,col)); % Subtract means
end
如果 B 很大,這種方法效率很低,通常是由於 MATLAB 必須在記憶體中移動變數的內容。通過使用 bsxfun,人們可以在一行中整齊,輕鬆地完成相同的工作:
A = bsxfun(@minus, B, mean(B));
這裡,@minus 是一個功能控制代碼到 minus操作者(-)和兩個矩陣 B 和 mean(B) 的元件之間的將被應用。其他功能控制代碼,甚至使用者定義的控制代碼也是可能的。
接下來,假設你要將行向量 v 新增到矩陣 A 中的每一行:
v = [1, 2, 3];
A = [8, 1, 6
3, 5, 7
4, 9, 2];
天真的方法是使用一個迴圈( 千萬不能這樣做 ):
B = zeros(3);
for row = 1:3
B(row,:) = A(row,:) + v;
end
另一種辦法是複製 v 與 repmat( 千萬不能做到這一點無論 ):
>> v = repmat(v,3,1)
v =
1 2 3
1 2 3
1 2 3
>> B = A + v;
而是使用 bsxfun 執行此任務:
>> B = bsxfun(@plus, A, v);
B =
9 3 9
4 7 10
5 11 5
句法
bsxfun(@fun, A, B)
其中 @fun 是支援的函式之一,兩個陣列 A 和 B 尊重以下兩個條件。
該名 bsxfun 有助於瞭解函式是如何工作的,它代表了B inary FUN 與 ction S ingletonê X 潘申。換句話說,如果:
- 除了一個,兩個陣列共享相同的維度
- 並且不一致的維度是兩個陣列中的任一個中的單例(即,具有
1的大小)
那麼具有單例維度的陣列將被擴充套件以匹配另一個陣列的維度。擴充套件後,在兩個陣列上元素應用二元函式。
例如,讓 A 成為 M-by-N-byK 陣列,B 是 M-by-N 陣列。首先,它們的前兩個尺寸具有相應的尺寸。其次,A 有 K 層,而 B 只隱含 1,因此它是一個單例。滿足所有條件,將複製 B 以匹配 A 的第三維。
在其他語言中,這通常被稱為*廣播,*並在 Python(numpy) 和 Octave 中自動發生。
函式 @fun 必須是二進位制函式,這意味著它必須只有兩個輸入。
備註
在內部,bsxfun 不會複製陣列並執行有效的迴圈。