簡體   English   中英

快速檢查元素是否在MATLAB矩陣中

[英]Fast check if element is in MATLAB matrix

我想驗證一個元素是否存在於MATLAB矩陣中。

一開始,我實現如下:

if ~isempty(find(matrix(:) == element))

這顯然很慢。 因此,我改為:

if sum(matrix(:) == element) ~= 0

但這又是慢的:我多次調用包含該指令的函數,每次丟失14秒!

有沒有辦法進一步優化這條指令?

謝謝。

如果你只需要知道矩陣中是否存在一個值,那么使用find的第二個參數來指定你只想要一個值會稍快(25-50%),甚至比使用sum更快一點,至少在我的機器。 一個例子:

matrix = randi(100,1e4,1e4);
element = 50;
~isempty(find(matrix(:)==element,1))

但是,在Matlab的最新版本中(我使用的是R2014b), nnz最終會更快地進行此操作,因此:

matrix = randi(100,1e4,1e4);
element = 50;
nnz(matrix==element)~=0

在我的機器上,這比所提供的示例的任何其他方法(包括使用any奇怪的方法)快約2.8倍。 在我看來,這個解決方案還具有最易讀的優點。

在我看來,有幾件事可以嘗試提高性能:

  1. 下面你最初的想法,我會去的功能any測試是任何平等測試了成功:

    if any(matrix(:) == element)

我在1000 x 1000矩陣上測試了它,它比你測試的解決方案更快。

  1. 我不認為展開matrix(:)是有害的,因為它等同於重塑,Matlab以智能的方式執行此操作,它實際上不會分配和移動內存,因為您沒有修改臨時對象matrix(:)

  2. 如果您在函數調用之間沒有變化或很少更改,您可以簡單地使用包含矩陣的所有元素的另一個向量,但已排序。 這樣,您可以使用更有效的搜索算法O(log(N))測試元素的存在。

  3. 我個人喜歡這種問題的ismember函數。 它可能不是最快的,但對於代碼的非關鍵部分,它極大地提高了可讀性和代碼維護(我寧願花一個小時編寫一些需要一天運行的東西,而不是花一天時間編寫一小時運行的代碼(這當然取決於你使用這個程序的頻率,但這是你永遠不會忘記的事情)

  4. 如果您可以擁有矩陣元素的排序副本,則可以考慮使用未記錄的Matlab函數ismembc,但請記住,輸入必須按非稀疏非NaN值排序。

  5. 如果性能確實很重要,您可能想要編寫自己的mex文件,對於此任務,您甚至可以使用openmp包含一些簡單的並行化。

希望這可以幫助,

阿德里安。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM