2
votes

I have two MATLAB vectors, one of them a simple ascending order vector, such as the following one:

ind = [1 2 3 4];

and another one of the same size as ind, but whose numbers can vary:

vec=[46 91 9 10];

Those two vectors are in some correspondence with one another, so I would like to be able to create a mapping M such that M(46) = 1, M(91) = 2, and so on. Of course, a solution using a full matrix M would, in general, be very wasteful since it would assume a matrix whose size is equal to the biggest possible value of vec. How might I be able to compress this mapping?

Essentially I'm looking for the MATLAB equivalent of what would otherwise be solved with a Python dict or a C++ std::map<int, int>.

3

3 Answers

3
votes

You want a map:

M = containers.Map(vec, ind);
2
votes

If vec is fixed and what you want it for is not very "heavy" you could define M like this:

M = @(x)find(vec == x);
1
votes

Matlab's nearest builtin equivalent to this is the sparse matrix. Limitations are that you would have to pre-specify the maximum possible index (though this may be very large, at no cost to you) and that the default value (for unassigned entries) must always be 0. But it will work:

M = sparse( 20000000, 1 );
M( vec ) = ind

For more flexibility, you could create your own class, overshadow the subsref and subsasgn methods, (rough equivalents of Python's __getitem__ and __setitem__, respectively) and store the keys and values in your own custom way. Unfortunately, in my experience, this kind of (object-oriented) solution tends to be very slow in Matlab.

Update: Luis Mendo's solution M = containers.Map( vec, ind ) is much more elegant, and more similar to the equivalent C++ and Python solutions. I hadn't heard of the containers.Map class. I suspect it will be a lot slower though, if timing performance is critical for your application. My preliminary test using these values suggests that retrieval from a sparse matrix is about 10x faster than retrieval from a containers.Map.