Hash tabele w MATLAB

92

Czy MATLAB obsługuje tabele skrótów?


Jakieś tło

Pracuję nad problemem w Matlabie, który wymaga odwzorowania obrazu w skali. W tym celu należy utworzyć filtr 2-D Gaussa z wariancji sigma*s^kza kw pewnym przedziale., A potem wykorzystać każdą z nich z kolei do filtrowania obrazu. Teraz chcę jakieś mapowanie z kdo przefiltrowanego obrazu.

Gdyby kzawsze była liczbą całkowitą, po prostu utworzyłbym tablicę 3D, która:

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

Jednak kniekoniecznie jest liczbą całkowitą, więc nie mogę tego zrobić. Pomyślałem o utrzymaniu takiej tablicy k, która:

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

Na pierwszy rzut oka wydaje się to całkiem niezłe, z wyjątkiem tego, że przeprowadzę to wyszukiwanie potencjalnie kilka tysięcy razy z około 20 lub 30 wartościami ki obawiam się, że zaszkodzi to wydajności.

Zastanawiam się, czy nie byłoby lepiej, gdyby robił to z jakąś tablicą mieszającą, tak żebym miał czas wyszukiwania, który wynosi O (1) zamiast O (n).


Teraz wiem, że nie powinienem optymalizować przedwcześnie i może w ogóle nie mam tego problemu, ale pamiętaj, że to tylko tło i mogą być przypadki, w których to naprawdę najlepsze rozwiązanie, niezależnie od tego, czy jest to najlepsze rozwiązanie mojego problemu.

Nathan Fellman
źródło

Odpowiedzi:

14

Matlab nie obsługuje tabel skrótów. EDYCJA Do r2010a, czyli; zobacz odpowiedź @Amro .

Aby przyspieszyć wyszukiwanie, możesz odrzucić findi użyć INDEKSOWANIA LOGICZNEGO .

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

lub

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

Jednak w całym moim doświadczeniu z Matlabem nigdy nie zdarzyło mi się, aby wyszukiwanie było wąskim gardłem.


Aby przyspieszyć określony problem, sugeruję użycie filtrowania przyrostowego

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

zakładając, że array_of_ksjest sortowany w kolejności rosnącej, a GaussFilter oblicza rozmiar maski filtra na podstawie wariancji (i używa oczywiście 2 filtrów 1D) lub możesz filtrować w przestrzeni Fouriera, co jest szczególnie przydatne w przypadku dużych obrazów i jeśli wariancje są rozmieszczone równomiernie (czego najprawdopodobniej niestety nie są).

Jonas
źródło
120

Rozważ użycie klasy map MATLAB: Containers.Map . Oto krótki przegląd:

  • Kreacja:

    >> 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
    
  • Wyszukaj:

    x = rainfallMap('Jan');
    
  • Przydzielać:

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

    rainfallMap('Total') = 999;
    
  • Usunąć:

    rainfallMap.remove('Total')
    
  • Sprawdzać:

    values = rainfallMap.values;
    keys = rainfallMap.keys;
    sz = rainfallMap.size;
    
  • Klucz sprawdzić:

    if rainfallMap.isKey('Today')
        ...
    end
    
Amro
źródło
7
Wow, nie wiedziałem tego! +1. Czy wiesz, czy są one znacznie szybsze niż indeksowanie logiczne?
Jonas
3
Containers.Map został dodany w MATLAB 7.7 (R2008b) patrz mathworks.com/access/helpdesk/help/techdoc/rn/brqyzax-1.html . Nowością w R2010a jest konstruktor do określania typu klucza, a także typu wartości. M = Containers.Map ('KeyType', kType, 'ValueType', vType)
zellus
@Jonas: Nie używałem ich intensywnie, byłoby interesujące zobaczyć, jak porównują się z użyciem logicznego indeksowania do wyszukiwania ..
Amro
9
@ zellus, @ amro: Czy to nie denerwujące, że nie ma historii poleceń w Matlabie?
Jonas
4
Lookup: rainfallMap ('Jan'); Przypisz: rainfallMap ('Jan') = 'zero'; Sprawdź: rainfallMap.values; rainfallMap.keys; rainfallMap.size; Sprawdź klucz: rainfallMap.isKey ('Dzisiaj');
Evgeni Sergeev
26

Nowa klasa Containers.Map w Matlab R2008b (7.7) to pomniejszona wersja interfejsu java.util.Map w języku Matlab . Ma dodatkową zaletę w postaci bezproblemowej integracji ze wszystkimi typami Matlab ( na przykład mapy Java nie obsługują struktur Matlab ), a także możliwość określania typów danych od wersji Matlab 7.10 (R2010a) .

Poważne implementacje Matlab wymagające map / słowników klucz-wartość powinny nadal korzystać z klas Map Java ( java.util.EnumMap , HashMap , TreeMap , LinkedHashMap lub Hashtable ), aby uzyskać dostęp do ich większej funkcjonalności, jeśli nie wydajności. Wersje Matlaba wcześniejsze niż R2008b w żadnym wypadku nie mają alternatywy i muszą używać klas Java.

Potencjalnym ograniczeniem korzystania z kolekcji Java jest ich niezdolność do zawierania nieprymitywnych typów Matlab, takich jak struktury. Aby temu zaradzić, przekonwertuj typy w dół (np. Za pomocą struct2cell lub programowo) lub utwórz oddzielny obiekt Java, który będzie przechowywać Twoje informacje i przechowywać ten obiekt w Kolekcji Java.

Możesz również być zainteresowany zbadaniem zorientowanej obiektowo (opartej na klasach) implementacji Hashtable w czystym Matlabie, która jest dostępna w Wymiana plików .

Yair Altman
źródło
1
Kolejna implementacja oparta na klasie Matlab opublikowana dzisiaj: mathworks.com/matlabcentral/fileexchange/28586
Yair Altman
19

Możesz do tego użyć javy.

W Matlab:

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

Ale musiałbyś zrobić pewne profilowanie, aby zobaczyć, czy daje ci to wzrost prędkości, jak sądzę ...

tauran
źródło
12

Jest trochę niezgrabny, ale jestem zaskoczony, że nikt nie zasugerował używania struktur. Możesz uzyskać dostęp do dowolnego pola struct przez nazwę zmiennej jako struct.(var)gdzie varmoże być dowolna zmienna i będzie rozwiązać w odpowiedni sposób.

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

var = 'a';

display( dict.(var) ); % prints 1
Mark Elliot
źródło
1
Jeśli użyjesz numeru jako nazwy pola dict.('2'):: mathworks.com/access/helpdesk/help/techdoc/matlab_prog/ ...
Amro
Ponadto zmienne muszą być liczbami całkowitymi: dict.(['k',num2str(1)])działa, ale dict.(['k',num2str(1.1)])zawodzi, a jeśli wartości są liczbami całkowitymi, możesz ich użyć do bezpośredniego indeksowania. Inaczej to fajny pomysł.
Jonas
@Amro, @Jonas, uczciwe punkty, gdyby klucze były liczbami całkowitymi, nie musiałbyś używać tej sztuczki (tablica miałaby więcej sensu) ... jeśli klucze są dowolnymi liczbami zmiennoprzecinkowymi, jest to trochę trudniejsze, ale ja „d prefiks z listem i wymienić .ze związkiem _.
Mark Elliot
6
Powyższych problemów z używaniem struktur można uniknąć poprzez dict.(genvarname(['k',num2str(1.1)]))
wariabilizację