Bảng băm trong MATLAB


92

MATLAB có bất kỳ hỗ trợ nào cho bảng băm không?


Một số nền

Tôi đang giải quyết một vấn đề trong Matlab yêu cầu biểu diễn không gian theo tỷ lệ của một hình ảnh. Để làm điều này để tạo bộ lọc 2-D Gaussian với phương sai sigma*s^kcho ktrong một số phạm vi., Và sau đó tôi sử dụng mỗi một lần lượt để lọc hình ảnh. Bây giờ, tôi muốn một số loại ánh xạ từ khình ảnh được lọc.

Nếu kluôn là số nguyên, tôi chỉ cần tạo một mảng 3D sao cho:

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

Tuy nhiên, kkhông nhất thiết phải là một số nguyên, vì vậy tôi không thể làm điều này. Những gì tôi nghĩ đến việc làm là giữ một mảng knhư vậy:

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

Thoạt nghe, điều này có vẻ khá tốt, ngoại trừ việc tôi sẽ thực hiện tra cứu này vài nghìn lần với khoảng 20 hoặc 30 giá trị kvà tôi sợ rằng điều này sẽ ảnh hưởng đến hiệu suất.

Tôi tự hỏi nếu tôi sẽ không được phục vụ tốt hơn khi làm điều này với một bảng băm nào đó để tôi có thời gian tra cứu là O (1) thay vì O (n).


Bây giờ, tôi biết rằng tôi không nên tối ưu hóa quá sớm và tôi có thể không gặp sự cố này, nhưng hãy nhớ rằng, đây chỉ là nền và có thể có những trường hợp đây thực sự là giải pháp tốt nhất, bất kể nó có phải là giải pháp tốt nhất cho vấn đề của tôi .

Câu trả lời:


14

Matlab không hỗ trợ hashtables. CHỈNH SỬA Cho đến r2010a, tức là; xem câu trả lời của @Amro .

Để tăng tốc độ tìm kiếm, bạn có thể bỏ findvà sử dụng LOGICAL INDEXING .

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

hoặc là

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

Tuy nhiên, trong tất cả kinh nghiệm của tôi với Matlab, tôi chưa bao giờ thấy việc tra cứu là một nút cổ chai.


Để tăng tốc sự cố cụ thể của bạn, tôi khuyên bạn nên sử dụng tính năng lọc gia tăng

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

giả sử array_of_ksđược sắp xếp theo thứ tự tăng dần và GaussFilter tính toán kích thước mặt nạ bộ lọc dựa trên phương sai (và sử dụng, 2 bộ lọc 1D, tất nhiên) hoặc bạn có thể lọc trong Không gian Fourier, điều này đặc biệt hữu ích cho hình ảnh lớn và nếu phương sai là cách đều nhau (mà rất có thể là không may).


120

Xem xét sử dụng lớp bản đồ của MATLAB: container.Map . Đây là tổng quan ngắn gọn:

  • Sự sáng tạo:

    >> 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
    
  • Tra cứu:

    x = rainfallMap('Jan');
  • Chỉ định:

    rainfallMap('Jan') = 0;
  • Thêm vào:

    rainfallMap('Total') = 999;
  • Tẩy:

    rainfallMap.remove('Total')
  • Quan sát:

    values = rainfallMap.values;
    keys = rainfallMap.keys;
    sz = rainfallMap.size;
    
  • Kiểm tra chìa khóa:

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

7
Ồ, tôi không biết điều đó! +1. Bạn có biết liệu chúng có nhanh hơn nhiều so với lập chỉ mục logic không?
Jonas

3
Containers.Map đã được thêm vào MATLAB 7.7 (R2008b) xem mathworks.com/access/helpdesk/help/techdoc/rn/brqyzax-1.html . Điểm mới trong R2010a là một hàm tạo để chỉ định loại khóa cũng như loại giá trị. M = container.Map ('KeyType', kType, 'ValueType', vType)
zellus

@Jonas: Tôi chưa sử dụng chúng một cách rộng rãi, sẽ rất thú vị khi xem chúng so sánh như thế nào với việc sử dụng lập chỉ mục logic để tra cứu ..
Amro

9
@ zellus, @ amro: Thật khó chịu khi không có lịch sử các lệnh trong Matlab?
Jonas

4
Tra cứu: rainMap ('Jan'); Ấn định: rainMap ('Jan') = 'zero'; Kiểm tra: rainMap.values; rainMap.keys; lượng mưaMap.size; Phím kiểm tra: rainMap.isKey ('Hôm nay');
Evgeni Sergeev

26

Lớp container.Map mới của Matlab R2008b (7.7) là một phiên bản Matlab thu nhỏ của giao diện java.util.Map . Nó có thêm lợi ích là tích hợp liền mạch với tất cả các kiểu Matlab ( ví dụ như Java Maps không thể xử lý các cấu trúc Matlab ) cũng như khả năng kể từ Matlab 7.10 (R2010a) để chỉ định kiểu dữ liệu .

Các triển khai Matlab nghiêm trọng yêu cầu bản đồ / từ điển khóa-giá trị vẫn nên sử dụng các lớp Bản đồ của Java ( java.util.EnumMap , HashMap , TreeMap , LinkedHashMap hoặc Hashtable ) để có quyền truy cập vào chức năng lớn hơn của chúng nếu không phải là hiệu suất. Các phiên bản Matlab trước R2008b không có sự thay thế thực sự trong mọi trường hợp và phải sử dụng các lớp Java.

Một hạn chế tiềm ẩn khi sử dụng Java Collections là chúng không có khả năng chứa các kiểu Matlab không nguyên thủy như cấu trúc. Để khắc phục điều này, hãy chuyển đổi các kiểu (ví dụ: sử dụng struct2cell hoặc theo chương trình) hoặc tạo một đối tượng Java riêng biệt sẽ chứa thông tin của bạn và lưu trữ đối tượng này trong Bộ sưu tập Java.

Bạn cũng có thể muốn kiểm tra triển khai Hashtable hướng đối tượng Matlab thuần túy (dựa trên lớp), có sẵn trên File Exchange .


1
Một thực hiện Matlab lớp dựa trên đăng tải hôm nay: mathworks.com/matlabcentral/fileexchange/28586
Yair Altman

19

Bạn có thể sử dụng java cho nó.

Trong matlab:

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

Nhưng bạn sẽ phải thực hiện một số cấu hình để xem liệu nó có mang lại cho bạn tốc độ tăng hay không, tôi đoán ...


12

Nó hơi phức tạp, nhưng tôi ngạc nhiên là không ai đề xuất sử dụng cấu trúc. Bạn có thể truy cập bất kỳ trường cấu trúc nào bằng tên biến vì struct.(var)nơi varcó thể là bất kỳ biến nào và sẽ giải quyết một cách thích hợp.

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

var = 'a';

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

1
Nó sẽ bị hỏng nếu bạn sử dụng một số làm tên trường dict.('2'):: mathworks.com/access/helpdesk/help/techdoc/matlab_prog/…
Amro

Ngoài ra, các biến phải là số nguyên: dict.(['k',num2str(1)])hoạt động, nhưng dict.(['k',num2str(1.1)])không thành công và nếu các giá trị là số nguyên, bạn có thể sử dụng chúng để lập chỉ mục trực tiếp. Đó là một ý tưởng hay.
Jonas

@Amro, @Jonas, điểm hợp lý, nếu các khóa là số nguyên, bạn sẽ không cần sử dụng thủ thuật này (một mảng sẽ có ý nghĩa hơn) ... nếu các khóa được thả nổi tùy ý, điều này sẽ khó hơn một chút, nhưng tôi tiền tố 'd bằng một chữ cái và thay thế .bằng _.
Mark Elliot

6
Các vấn đề trên bằng cách sử dụng các cấu trúc có thể tránh được bằng cách variabilizing các dây trước khi thêm như tên trường:dict.(genvarname(['k',num2str(1.1)]))
foglerit

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.