MATLAB中的哈希表


92

MATLAB是否支持哈希表?


一些背景

我正在研究Matlab中需要图像的比例空间表示的问题。要做到这一点,我创建一个2-d高斯滤波器具有方差sigma*s^kk在一定范围内。,然后我使用依次每一个来过滤所述图像。现在,我想要某种映射k到过滤后的图像。

如果k始终是整数,则只需创建一个3D数组即可:

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

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

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

乍一看似乎不错,不过我可能会使用20或30的值进行数千次查找k,而且我担心这样做会损害性能。

我想知道是否最好使用某种哈希表来执行此操作,以便查找时间为O(1)而不是O(n)。


现在,我知道我不应该过早地进行优化,并且我可能根本不会遇到这个问题,但是请记住,这仅仅是背景情况,并且在某些情况下,这实际上是最好的解决方案,无论它是否是最佳解决方案。解决我的问题的最佳方法。

Answers:


14

Matlab不支持哈希表。编辑直到r2010a,即;参见@Amro的答案。

为了加快查找速度,您可以删除find和使用LOGICAL INDEXING

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

要么

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

但是,根据我在Matlab上的所有经验,我从来没有遇到过查找瓶颈的情况。


为了加快您的特定问题,我建议您使用增量过滤

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

假设array_of_ks按升序排序,GaussFilter会基于方差(当然,使用2个1D滤镜)来计算滤镜蒙版大小,或者您可以在傅立叶空间中进行滤镜,这对于大图像以及方差为等距排列(很可能并非如此)。


120

考虑使用MATLAB的地图类:container.Map。这里是一个简短的概述:

  • 创建:

    >> 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
  • 抬头:

    x = rainfallMap('Jan');
  • 分配:

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

    rainfallMap('Total') = 999;
  • 去掉:

    rainfallMap.remove('Total')
  • 检查:

    values = rainfallMap.values;
    keys = rainfallMap.keys;
    sz = rainfallMap.size;
  • 确认码:

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

7
哇,我不知道!+1。您知道它们是否比逻辑索引快得多?
乔纳斯(Jonas)2010年

3
在MATLAB 7.7(R2008b)中添加了Containers.Map,请参见mathworks.com/access/helpdesk/help/techdoc/rn/brqyzax-1.html。R2010a中的新增功能是用于指定键类型和值类型的构造函数。M = container.Map('KeyType',kType,'ValueType',vType)
zellus 2010年

@Jonas:我没有广泛使用它们,很有趣的是看看它们与使用逻辑索引进行查找的比较
。.– Amro

9
@ zellus,@ amro:难道Matlab中没有命令的历史记录吗?
乔纳斯(Jonas)2010年

4
查找:rainingMap('Jan'); 分配:rainageMap('Jan')='零'; 检查:rainfallMap.values;rainfallMap.keys; rainfallMap.size; 检查键:rainageMap.isKey('Today');
Evgeni Sergeev 2012年

26

Matlab R2008b(7.7)的新container.Map类是java.util.Map接口的按比例缩小的Matlab版本。它具有与所有Matlab类型无缝集成(例如Java Maps无法处理Matlab结构)的附加优点,以及自Matlab 7.10(R2010a)起指定数据类型的能力

严重的需要键值映射/字典的Matlab实现仍应使用Java的Map类(java.util.EnumMapHashMapTreeMapLinkedHashMapHashtable)来访问其较大的功能(如果没有性能)。在任何情况下,R2008b之前的Matlab版本都没有真正的替代品,必须使用Java类。

使用Java集合的潜在限制是它们无法包含非原始Matlab类型(例如结构)。为了克服这个问题,可以向下转换类型(例如,使用struct2cell或以编程方式),或者创建一个单独的Java对象,该对象将保存您的信息并将该对象存储在Java Collection中。

您可能也有兴趣研究纯Matlab的面向对象(基于类)的Hashtable实现,该实现可在File Exchange上获得


1
今天发布的另一个基于Matlab基于类的实现:mathworks.com/matlabcentral/fileexchange/28586
Yair Altman,2010年

19

您可以使用Java。

在Matlab中:

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

但是您必须做一些分析,看看它是否可以给您带来速度上的提升……


12

这有点笨拙,但是令我惊讶的是没有人建议使用结构。您可以通过变量名称访问任何结构字段,因为struct.(var)在哪里var可以是任何变量,并且可以正确解析。

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

var = 'a';

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

1
如果你使用一个数字作为一个字段名这将打破:dict.('2')mathworks.com/access/helpdesk/help/techdoc/matlab_prog/...
荷银

另外,变量必须是整数:dict.(['k',num2str(1)])可以工作,但是会dict.(['k',num2str(1.1)])失败,并且如果值是整数,则可以使用它们直接进行索引。否则,这是一个好主意。
乔纳斯(Jonas)2010年

@ Amro,@ Jonas,公平点,如果键是整数,则不需要使用此技巧(数组会更有意义)...如果键是任意浮点数,则这更具挑战性,但是我“d前缀以字母和更换._
Mark Elliot 2010年

6
可以通过在添加为字段名称之前对字符串进行可变化来避免使用结构的上述问题:dict.(genvarname(['k',num2str(1.1)]))
foglerit 2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.