MATLAB 中的哈希表

MATLAB 是否支持散列表?


一些背景资料

我正在研究 Matlab 的一个问题,这个问题需要一幅图像的比例空间表示。为了做到这一点,我创建了一个2-D 高斯滤波器与方差 sigma*s^kk在一定范围内,然后我使用每一个轮流过滤的图像。现在,我想要从 k到滤波图像的某种映射。

如果 k始终是一个整数,我只需创建一个3D 数组,如下所示:

arr[k] = <image filtered with k-th guassian>

但是,k不一定是一个整数,所以我不能这样做。我想做的是保持一个 k数组,这样:

arr[find(array_of_ks_ = k)] = <image filtered with k-th guassian>

乍一看,这似乎相当不错,但是我将使用大约20或30个 k值进行几千次这种查找,我担心这会影响性能。

我想知道,如果使用某种哈希表进行查找,那么查找时间是 O (1)而不是 O (n) ,是否会更好。


现在,我知道我不应该过早优化,我可能根本就没有这个问题,但是请记住,这只是背景,在某些情况下,这可能是真正的最佳解决方案,不管它是否是 天啊问题的最佳解决方案。

54489 次浏览

Matlab does not have support for hashtables. EDIT Until r2010a, that is; see @Amro's answer.

To speed up your look-ups, you can drop the find, and use LOGICAL INDEXING.

arr{array_of_ks==k} = <image filtered with k-th Gaussian>

or

arr(:,:,array_of_ks==k) = <image filtered with k-th Gaussian>

However, in all my experience with Matlab, I've never had a lookup be a bottleneck.


To speed up your specific problem, I suggest to either use incremental filtering

arr{i} = GaussFilter(arr{i-1},sigma*s^(array_of_ks(i)) - sigma*s^(array_of_ks(i-1)))

assuming array_of_ks is sorted in ascending order, and GaussFilter calculates the filter mask size based on the variance (and uses, 2 1D filters, of course), or you can filter in Fourier Space, which is especially useful for large images and if the variances are spaced evenly (which they most likely aren't unfortunately).

You could use java for it.

In matlab:

dict = java.util.Hashtable;
dict.put('a', 1);
dict.put('b', 2);
dict.put('c', 3);
dict.get('b')

But you would have to do some profiling to see if it gives you a speed gain I guess...

Consider using MATLAB's map class: containers.Map. Here is a brief overview:

  • Creation:

    >> keys = {'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', ...
    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Annual'};
    
    
    >> values = {327.2, 368.2, 197.6, 178.4, 100.0,  69.9, ...
    32.3,  37.3,  19.0,  37.0,  73.2, 110.9, 1551.0};
    
    
    >> rainfallMap = containers.Map(keys, values)
    
    
    rainfallMap =
    containers.Map handle
    Package: containers
    
    
    Properties:
    Count: 13
    KeyType: 'char'
    ValueType: 'double'
    Methods, Events, Superclasses
    
  • Lookup:

    x = rainfallMap('Jan');
    
  • Assign:

    rainfallMap('Jan') = 0;
    
  • Add:

    rainfallMap('Total') = 999;
    
  • Remove:

    rainfallMap.remove('Total')
    
  • Inspect:

    values = rainfallMap.values;
    keys = rainfallMap.keys;
    sz = rainfallMap.size;
    
  • Check key:

    if rainfallMap.isKey('Today')
    ...
    end
    

It's a little clugey, but I'm surprised nobody has suggested using structs. You can access any struct field by variable name as struct.(var) where var can be any variable and will resolve appropriately.

dict.a = 1;
dict.b = 2;


var = 'a';


display( dict.(var) ); % prints 1

Matlab R2008b (7.7)’s new containers.Map class is a scaled-down Matlab version of the java.util.Map interface. It has the added benefit of seamless integration with all Matlab types (Java Maps cannot handle Matlab structs for example) as well as the ability since Matlab 7.10 (R2010a) to specify data types.

Serious Matlab implementations requiring key-value maps/dictionaries should still use Java’s Map classes (java.util.EnumMap, HashMap, TreeMap, LinkedHashMap or Hashtable) to gain access to their larger functionality if not performance. Matlab versions earlier than R2008b have no real alternative in any case and must use the Java classes.

A potential limitation of using Java Collections is their inability to contain non-primitive Matlab types such as structs. To overcome this, either down-convert the types (e.g., using struct2cell or programmatically), or create a separate Java object that will hold your information and store this object in the Java Collection.

You may also be interested to examine a pure-Matlab object-oriented (class-based) Hashtable implementation, which is available on the File Exchange.

You can also take advantage of the new type "Table". You can store different types of data and get statistics out of it really easy. See http://www.mathworks.com/help/matlab/tables.html for more info.