Tabel hash di MATLAB

92

Apakah MATLAB memiliki dukungan untuk tabel hash?


Beberapa latar belakang

Saya sedang mengerjakan masalah di Matlab yang membutuhkan representasi skala-ruang dari sebuah gambar. Untuk melakukan ini, saya membuat filter Gaussian 2-D dengan varians sigma*s^kuntuk kbeberapa rentang., Dan kemudian saya menggunakan masing-masing secara bergantian untuk memfilter gambar. Sekarang, saya ingin semacam pemetaan dari kke gambar yang difilter.

Jika kselalu berupa integer, saya cukup membuat array 3D seperti itu:

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

Namun, kbelum tentu merupakan bilangan bulat, jadi saya tidak bisa melakukan ini. Apa yang saya pikirkan untuk dilakukan adalah menyimpan array kseperti itu:

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

Yang tampaknya cukup bagus pada awalnya, kecuali saya akan melakukan pencarian ini secara potensial beberapa ribu kali dengan sekitar 20 atau 30 nilai k, dan saya khawatir ini akan merusak kinerja.

Saya ingin tahu apakah saya tidak akan lebih baik melakukan ini dengan tabel hash semacam itu sehingga saya akan memiliki waktu pencarian yaitu O (1) daripada O (n).


Sekarang, saya tahu bahwa saya seharusnya tidak mengoptimalkan sebelum waktunya, dan saya mungkin tidak memiliki masalah ini sama sekali, tetapi ingat, ini hanya latar belakang, dan mungkin ada kasus di mana ini benar-benar solusi terbaik, terlepas dari apakah itu solusi terbaik untuk masalah saya .

Nathan Fellman
sumber

Jawaban:

14

Matlab tidak memiliki dukungan untuk hashtable. EDIT Sampai r2010a, yaitu; lihat jawaban @Amro .

Untuk mempercepat pencarian Anda, Anda dapat melepaskan find, dan menggunakan LOGICAL INDEXING .

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

atau

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

Namun, dalam semua pengalaman saya dengan Matlab, saya tidak pernah memiliki pencarian yang menjadi hambatan.


Untuk mempercepat masalah khusus Anda, saya sarankan untuk menggunakan pemfilteran inkremental

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

asumsi array_of_ksdiurutkan dalam urutan menaik, dan GaussFilter menghitung ukuran topeng filter berdasarkan varians (dan menggunakan, 2 filter 1D, tentu saja), atau Anda dapat memfilter dalam Fourier Space, yang sangat berguna untuk gambar besar dan jika variansnya diberi jarak secara merata (yang kemungkinan besar tidak sayangnya).

Jonas
sumber
120

Pertimbangkan untuk menggunakan kelas peta MATLAB: containers.Map . Berikut gambaran singkatnya:

  • Penciptaan:

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

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

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

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

    rainfallMap.remove('Total')
  • Memeriksa:

    values = rainfallMap.values;
    keys = rainfallMap.keys;
    sz = rainfallMap.size;
  • Kunci pengecekan:

    if rainfallMap.isKey('Today')
        ...
    end
Amro
sumber
7
Wow, saya tidak tahu itu! +1. Tahukah Anda apakah mereka jauh lebih cepat daripada pengindeksan logis?
Jonas
3
Containers.Map telah ditambahkan di MATLAB 7.7 (R2008b) lihat mathworks.com/access/helpdesk/help/techdoc/rn/brqyzax-1.html . Baru di R2010a adalah konstruktor untuk menentukan jenis kunci serta jenis nilai. M = containers.Map ('KeyType', kType, 'ValueType', vType)
zellus
@ Jonas: Saya belum pernah menggunakannya secara ekstensif, akan menarik untuk melihat bagaimana mereka dibandingkan dengan menggunakan pengindeksan logis untuk pencarian ..
Amro
9
@ zellus, @ amro: Tidakkah menjengkelkan karena tidak ada riwayat perintah di Matlab?
Jonas
4
Pencarian: rainMap ('Jan'); Tetapkan: rainMap ('Jan') = 'zero'; Periksa: rainMap.values; rainMap.keys; rainMap.size; Periksa kunci: rainMap.isKey ('Today');
Evgeni Sergeev
26

Container.Map baru Matlab R2008b (7.7) class adalah versi Matlab yang diperkecil dari antarmuka java.util.Map . Ini memiliki manfaat tambahan dari integrasi tanpa batas dengan semua tipe Matlab ( Java Maps tidak dapat menangani struct Matlab misalnya) serta kemampuan sejak Matlab 7.10 (R2010a) untuk menentukan tipe data .

Implementasi Matlab serius yang membutuhkan peta / kamus nilai kunci tetap harus menggunakan kelas Peta Java ( java.util.EnumMap , HashMap , TreeMap , LinkedHashMap , atau Hashtable ) untuk mendapatkan akses ke fungsionalitas yang lebih besar jika bukan performa. Versi Matlab yang lebih lama dari R2008b tidak memiliki alternatif nyata dalam hal apa pun dan harus menggunakan kelas Java.

Batasan potensial dalam menggunakan Koleksi Java adalah ketidakmampuannya untuk memuat jenis Matlab non-primitif seperti struct. Untuk mengatasi hal ini, konversi tipe-tipe (mis., Menggunakan struct2cell atau secara terprogram), atau buat objek Java terpisah yang akan menyimpan informasi Anda dan menyimpan objek ini di Koleksi Java.

Anda mungkin juga tertarik untuk memeriksa implementasi Hashtable berorientasi objek (berbasis kelas) murni-Matlab, yang tersedia di File Exchange .

Yair Altman
sumber
1
Implementasi berbasis kelas Matlab lainnya diposting hari ini: mathworks.com/matlabcentral/fileexchange/28586
Yair Altman
19

Anda bisa menggunakan java untuk itu.

Di matlab:

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

Tetapi Anda harus melakukan beberapa profil untuk melihat apakah itu memberi Anda peningkatan kecepatan, saya kira ...

tauran
sumber
12

Ini sedikit clugey, tapi saya terkejut tidak ada yang menyarankan menggunakan struct. Anda dapat mengakses bidang struct apa pun dengan nama variabel karena di struct.(var)mana vardapat berupa variabel apa pun dan akan menyelesaikannya dengan tepat.

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

var = 'a';

display( dict.(var) ); % prints 1
Mark Elliot
sumber
1
Ini akan rusak jika Anda menggunakan angka sebagai nama bidang dict.('2'):: mathworks.com/access/helpdesk/help/techdoc/matlab_prog/…
Amro
Selain itu, variabel harus berupa bilangan bulat: dict.(['k',num2str(1)])berfungsi, tetapi dict.(['k',num2str(1.1)])gagal, dan jika nilainya adalah bilangan bulat, Anda dapat menggunakannya untuk mengindeks secara langsung. Sebaliknya itu ide yang bagus.
Jonas
@Amro, @Jonas, poin yang adil, jika kuncinya adalah bilangan bulat, Anda tidak perlu menggunakan trik ini (array akan lebih masuk akal) ... jika kuncinya mengambang sewenang-wenang, ini sedikit lebih menantang, tetapi saya awalan dengan huruf dan ganti .dengan _.
Mark Elliot
6
Masalah di atas terkait penggunaan struktur dapat dihindari dengan membuat variasi string sebelum menambahkan sebagai nama bidang:dict.(genvarname(['k',num2str(1.1)]))
foglerit
1

Anda juga dapat memanfaatkan tipe baru "Tabel". Anda dapat menyimpan berbagai jenis data dan mendapatkan statistik darinya dengan sangat mudah. Lihat http://www.mathworks.com/help/matlab/tables.html untuk info lebih lanjut.

Lei Zhang
sumber