使用 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操作者(-)和兩個矩陣 Bmean(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

另一種辦法是複製 vrepmat千萬不能做到這一點無論 ):

>> 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支援的函式之一,兩個陣列 AB 尊重以下兩個條件。

該名 bsxfun 有助於瞭解函式是如何工作的,它代表了B inary FUN 與 ction S ingletonê X 潘申。換句話說,如果:

  1. 除了一個,兩個陣列共享相同的維度
  2. 並且不一致的維度是兩個陣列中的任一個中的單例(即,具有 1 的大小)

那麼具有單例維度的陣列將被擴充套件以匹配另一個陣列的維度。擴充套件後,在兩個陣列上元素應用二元函式。

例如,讓 A 成為 M-by-N-byK 陣列,BM-by-N 陣列。首先,它們的前兩個尺寸具有相應的尺寸。其次,AK 層,而 B 只隱含 1,因此它是一個單例。滿足所有條件,將複製 B 以匹配 A 的第三維。

在其他語言中,這通常被稱為*廣播,*並在 Python(numpy) 和 Octave 中自動發生。

函式 @fun 必須是二進位制函式,這意味著它必須只有兩個輸入。

備註

在內部,bsxfun 不會複製陣列並執行有效的迴圈。