Matlab中bsxfun和unique函數解析


一.問題來源

  來自於一份LSH代碼,記錄下來。

二.函數解析

2.1 bsxfun

  bsxfun是一個matlab自版本R2007a來就提供的一個函數,作用是”applies an element-by-element binary operation to arrays a and b, with singleton expansion enabled。

  函數用在兩個數組間元素逐個計算。比如當我們想對一個矩陣A的每一列或者每一行與同一個長度相等的向量a進行某些操作(比較大小,乘除等)時,我們只能用循環方法或者利用repmat函數將要操作的向量a復制成和A一樣尺寸的矩陣,進而進行操作。從MATLAB R2007a開始,再遇到類似的問題時,我們有了簡潔高效的方法,即利用bsxfun函數。

2.2 unique

  格式 b = unique (a) %取集合a的不重復元素構成的向量。
  b = unique (A,'rows') %返回A、B不同行元素組成的矩陣。

  我發現b中內容由小到大排序了。

  [b,i,j] = unique (…) %i體現b中元素在原向量(矩陣a)中的位置;j體現原向量(矩陣a)在b中的位置

  參考文獻:http://blog.sina.com.cn/s/blog_5efed5800100crs2.html

三.實例分析

3.1 bsxfun  

  舉個例子。假設我們有一列向量和一行向量。a = randn(3,1), b = randn(1,3),我們可以很簡單的使用matlab的外乘c=a*b來得到,但如果我們想用”外加”呢?也就是說把上式求解過程中的乘號換做加號?
這時我們可以用c=bsxfun(@plus,a,b)來實現。
  bsxfun的執行是這樣的,如果a和b的大小相同,那么c=a+b. 但如果有某維不同,且a或b必須有一個在這一維的維數為1, 那么bsxfun就將少的這個虛擬的復制一些來使與多的維數一樣。在我們這里,b的第一維只有1(只一行),所以bsxfun將b復制3次形成一個3×3的矩陣,同樣也將a復制成3×3的矩陣。這個等價於c=repmat(a,1,3)+repmat(b,3,1)。

  這里repmat是顯式的復制,當然帶來內存的消耗。而bsxfun是虛擬的復制,實際上通過for來實現,等效於for(i=1:3),for(j=1:3),c(i,j)=a(i)+b(j);end,end。但bsxfun不會有使用matlab的for所帶來額外時間。從計算時間上來說前兩種實現差不多,遠高於for的實現。但如果數據很大,第二種實現可能會有內存上的問題。所以bsxfun最好。

  這里@plus是加法的函數數柄,相應的有減法@minus, 乘法@times, 左右除等,具體可見 doc bsxfun.也可以是m文件。

  @plus@minus@times@rdivide@ldivide@power@max@min@rem@mod@atan2@hypot@eq@ne@lt@le@gt@ge@and@or@xor

  參考文獻http://blog.sina.com.cn/s/blog_9e67285801010ttn.html

3.2rempat

>> A=[1 1 2 2 4 4 6 4 6]
A =
1 1 2 2 4 4 6 4 6
>> [c,i,j]=unique(A)
c =
1 2 4 6
i =
2 4 8 9 %i體現b中元素在原向量(矩陣a)中的位置;
j =
1 1 2 2 3 3 4 3 4 %j體現原向量(矩陣a)在b中的位置

例1-40
>> A=[1 2 2 4;1 1 4 6;1 1 4 6]
A =
1 2 2 4
1 1 4 6
1 1 4 6
>> [c,i,j]=unique(A,'rows')
c =
1 1 4 6
1 2 2 4
i =
3
1
j =
2
1
1  

  如何將一個矩陣的每行或每列元素分別擴大不同的倍數?如[1 2 3;4 5 6 ;7 8 9],第一列元素乘以1,第二列元素以2,第三列元素乘以4。

  利用bsxfun函數,可以給出下列代碼:a = [1,2,3;4,5,6;7,8,9];acol = bsxfun(@times,a,[1 2 4])


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM