MATLAB의 해시 테이블


92

MATLAB이 해시 테이블을 지원합니까?


일부 배경

이미지의 스케일 공간 표현이 필요한 Matlab의 문제를 해결 중입니다. 이를 sigma*s^k위해 k특정 범위에 대한 분산 이 있는 2D 가우스 필터를 만든 다음 각각을 차례로 사용하여 이미지를 필터링합니다. 이제 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 (n) 대신 O (1) 조회 시간을 가질 수 있도록 일종의 해시 테이블로 이것을 수행하는 것이 더 좋지 않을지 궁금합니다.


자, 저는 제가 조기에 최적화해서는 안된다는 것을 알고 있으며,이 문제가 전혀 발생하지 않을 수도 있습니다. 그러나 이것은 단지 배경 일 뿐이며 이것이 실제로 최선의 해결책 인 경우가있을 수 있습니다. 문제에 대한 최고의 솔루션 .

답변:


14

Matlab은 해시 테이블을 지원하지 않습니다. r2010a까지 편집 , 즉; @Amro 의 대답을 참조하십시오 .

조회 속도를 높이려면을 삭제하고 LOGICAL INDEXING을find 사용할 수 있습니다 .

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

3
Containers.Map 볼 MATLAB 7.7 (R2008b)에서 추가되었다 mathworks.com/access/helpdesk/help/techdoc/rn/brqyzax-1.html . R2010a의 새로운 기능은 키 유형과 값 유형을 지정하는 생성자입니다. M = container.Map ( 'KeyType', kType, 'ValueType', vType)
zellus

@Jonas : 나는 그것들을 광범위하게 사용하지 않았습니다. 그들이 조회를 위해 논리적 인덱싱을 사용하는 것과 비교하는 방법을 보는 것은 흥미로울 것입니다.
Amro

9
@ zellus, @ amro : Matlab에 명령 기록이 없다는 것이 얼마나 성가신가요?
Jonas

4
조회 : rainfallMap ( 'Jan'); 할당 : rainfallMap ( 'Jan') = 'zero'; 검사 : rainfallMap.values; rainfallMap.keys; rainfallMap.size; 키 확인 : rainfallMap.isKey ( 'Today');
Evgeni Sergeev

26

Matlab R2008b (7.7)의 새로운 container.Map 클래스는 java.util.Map 인터페이스 의 축소 된 Matlab 버전입니다 . Matlab 7.10 (R2010a) 이후 데이터 유형지정 하는 기능뿐만 아니라 모든 Matlab 유형 (예 : Java Maps에서 Matlab 구조체처리 할 수 ​​없음) 과의 원활한 통합이라는 추가 이점이 있습니다 .

키-값 맵 / 사전이 필요한 심각한 Matlab 구현은 여전히 ​​Java의 Map 클래스 ( java.util.EnumMap , HashMap , TreeMap , LinkedHashMap 또는 Hashtable )를 사용하여 성능이 아닌 경우 더 큰 기능에 액세스해야합니다. R2008b 이전의 Matlab 버전은 어떠한 경우에도 실제 대안이 없으며 Java 클래스를 사용해야합니다.

Java 컬렉션 사용의 잠재적 인 제한 사항은 구조체와 같은 비 원시 Matlab 유형을 포함 할 수 없다는 것입니다. 이를 극복하려면 유형을 다운 변환 (예 : struct2cell 또는 프로그래밍 방식으로 사용)하거나 정보를 보유하고이 객체를 Java 컬렉션에 저장할 별도의 Java 객체를 만듭니다.

File Exchange에서 사용할 수 있는 순수 Matlab 객체 지향 (클래스 기반) Hashtable 구현을 살펴 보는 것도 좋습니다.


1
오늘 게시 된 또 다른 Matlab 클래스 기반 구현 : mathworks.com/matlabcentral/fileexchange/28586
Yair Altman

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/…
Amro

또한 변수는 정수 여야합니다. dict.(['k',num2str(1)])작동하지만 dict.(['k',num2str(1.1)])실패하며 값이 정수인 경우이를 사용하여 직접 인덱싱 할 수 있습니다. 그렇지 않으면 좋은 생각입니다.
Jonas

@Amro, @Jonas, 공정한 포인트, 키가 정수이면이 트릭을 사용할 필요가 없습니다 (배열이 더 의미가 있음) ... 키가 임의의 부동 소수점 인 경우 조금 더 어렵지만 난 'd 접두사를 문자 .로하고를 _.
Mark Elliot

6
구조 사용과 관련된 위의 문제는 필드 이름으로 추가하기 전에 문자열을 가변 화하여 피할 수 있습니다.dict.(genvarname(['k',num2str(1.1)]))
foglerit

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.