Search code examples
matlablogical-operatorsmatrix-indexing

Matlab index to logic indexing


I have given a list of indices, e.g. i = [3 5] and a vector v = 1:6. I need a function f which returns the logical map for the vector v given the indices i, e.g.:

f(i, length(v)) = [0 0 1 0 1 0]

Since I will call this function several million times, I would like to make it as fast as possible. Is there a builtin function which performs this task?


Solution

  • I know I'm late in the game, but I really wanted to find a faster solution which is just as elegant as ismember. And indeed there is one, that employs the undocumented ismembc function:

    ismembc(v, i)
    

    Benchmark

    N = 7;
    i = [3 5];
    
    %// slayton's solution
    tic
    for ii = 1:1e5
        clear idx;
        idx(N) = false;
        idx(i) = true;
    end
    toc
    
    %// H.Muster's solution
    tic
    for ii = 1:1e5
        v = 1:N;
        idx = ismember(v, i);
    end
    toc
    
    %// Jonas' solution
    tic
    for ii = 1:1e5
        idx = sparse(i, 1, true, N, 1);
    end
    toc
    
    %// ismembc solution
    tic
    for ii = 1:1e5
        v = 1:N;
        idx = ismembc(v, i);
    end
    toc
    

    Here's what I got:

    Elapsed time is 1.482971 seconds.
    Elapsed time is 6.369626 seconds.
    Elapsed time is 2.039481 seconds.
    Elapsed time is 0.776234 seconds.
    

    Amazingly, ismembc is indeed the fastest!

    Edit:
    For very large values of N (i.e. when v is a large array), the faster solution is actually slayton's (and HebeleHododo's, for that matter). You have quite a variety of strategies to choose from, pick carefully :)

    Edit by H.Muster:
    Here's are benchmark results including _ismemberoneoutput:

    Slayton's solution:
       Elapsed time is 1.075650 seconds.
    ismember:
       Elapsed time is 3.163412 seconds.
    ismembc:
       Elapsed time is 0.390953 seconds.
    _ismemberoneoutput:
       Elapsed time is 0.477098 seconds.
    

    Interestingly, Jonas' solution does not run for me, as I get an Index exceeds matrix dimensions. error...

    Edit by hoogamaphone:
    It's worth noting that ismembc requires both inputs to be numerical, sorted, non-sparse, non-NaN values, which is a detail that could be easily missed in the source documentation.