Хеш-таблиці в MATLAB


92

Чи підтримує MATLAB якусь підтримку хеш-таблиць?


Деякий фон

Я працюю над проблемою в Matlab, яка вимагає масштабного представлення зображення. Для цього я створюю двовимірний фільтр Гауса з дисперсією sigma*s^kдля kпевного діапазону., А потім використовую кожен по черзі для фільтрації зображення. Тепер я хочу якесь відображення kвідфільтрованого зображення.

Якби kзавжди було цілим числом, я б просто створив тривимірний масив таким чином, щоб:

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).


Зараз я знаю, що мені не слід оптимізувати передчасно, і у мене може не виникати цієї проблеми взагалі, але пам’ятайте, це лише передумови, і бувають випадки, коли це справді найкраще рішення, незалежно від того, чи є воно найкраще рішення для моєї проблеми.

Відповіді:


14

Matlab не підтримує хештеги. EDIT До r2010a, тобто; див. відповідь @Amro .

Щоб пришвидшити пошук, ви можете скинути 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. Чи знаєте ви, чи вони набагато швидші за логічне індексування?
Йонас,

3
Containers.Map був доданий в MATLAB 7.7 (R2008b) см mathworks.com/access/helpdesk/help/techdoc/rn/brqyzax-1.html . Новим у R2010a є конструктор, який визначає тип ключа, а також тип значення. M = контейнери.Map ('KeyType', kType, 'ValueType', vType)
zellus

@Jonas: Я їх широко не використовував, було б цікаво подивитися, як вони порівнюються з використанням логічного індексування для пошуку ..
Амро

9
@ zellus, @ amro: Чи не дратує те, що в Matlab немає історії команд?
Jonas

4
Пошук: rainfallMap ('січень'); Призначити: rainfallMap ('Jan') = 'нуль'; Перевірити: rainfallMap.values; rainfallMap.key; rainfallMap.size; Клавіша перевірки: rainfallMap.isKey ('Сьогодні');
Євген Сергєєв

26

Нові контейнери Matlab R2008b (7.7). Клас Map - це зменшена версія Matlab java.util.Map інтерфейсу . Він має додаткову перевагу безшовної інтеграції з усіма типами Matlab ( Java Maps, наприклад, не може обробляти структури Matlab ), а також можливість, оскільки Matlab 7.10 (R2010a) визначає типи даних .

Серйозні реалізації Matlab, що вимагають карт / словників ключових значень, все одно повинні використовувати класи Map Java ( java.util.EnumMap , HashMap , TreeMap , LinkedHashMap або Hashtable ) для доступу посилення їх більшої функціональності , якщо не продуктивність. Версії Matlab раніше R2008b не мають реальної альтернативи в будь-якому випадку і повинні використовувати класи Java.

Потенційним обмеженням використання Java Collections є їх нездатність містити непримітивні типи Matlab, такі як структури. Щоб подолати це, перетворіть типи вниз (наприклад, використовуючи struct2cell або програмно), або створіть окремий об'єкт Java, який буде зберігати вашу інформацію та зберігати цей об'єкт у колекції Java.

Можливо, вам буде цікаво вивчити реалізацію Hashtable із чистою Matlab, яка доступна на File Exchange .


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)])не вдається, і якщо значення є цілими числами, ви можете використовувати їх для безпосереднього індексування. Інакше це гарна ідея.
Йонас,

@Amro, @Jonas, справедливі моменти, якщо ключі були цілими числами, вам не потрібно було б використовувати цей фокус (масив мав би більше сенсу) ... якщо ключі довільні з плаваючою операцією, це трохи складніше, але я «d префікс з буквою і замінити .з _.
Mark Elliot

6
Вищезазначених проблем із використанням структур можна уникнути, dict.(genvarname(['k',num2str(1.1)]))
варіалізуючи

1

Ви також можете скористатися новим типом "Стіл". Ви можете зберігати різні типи даних і отримувати статистику з них дуже просто. Для отримання додаткової інформації див. Http://www.mathworks.com/help/matlab/tables.html .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.