1
  1. Lets say that I have an array x with some data values.
  2. I performed a clustering algorithm that has produced a label map with the label names - labelMap. Each point in the data now has a unique cluster label associated to it.
  3. I then perform the function foo(subset, secondArg) over each subset. The function foo returns a new array with the result which has the same size as its given the argument (its a map() function which also recieves a second argument).

What follows is the current implementation:

    x = rand(1,1000);
    numClusters = 3; % specified in advance by the user, for example using a clustering algorithm such as K-Means, this is a given.
    fooSecondArg = [1,2,3]; % second argument for foo().

    labelMap = kmeans(x,numClusters);
    res = zeros(size(x));

    %% make me run without a for loop :)
    for ind = 1:numClusters
        res(labelMap == ind) = foo(x(labelMap == ind), fooSecondArg(ind));
    end

My question is as follows:

As there is no overlap between the indices in x foo() acts upon, is there a way to perform foo over x without using a for or a parfor loop? (I don't want to use a parfor loop as It takes quite a while to start the additional matlab processes and I cannot later on deploy it as a stand alone application).

Many thanks!

Edit: I was asked for an example of foo() because I was told the solution may depend on it. A good viable example you may use in your answer:

    function out = foo(x,secondArg)
    out = x.^2/secondArg;
12
  • 1
    I don't think there's an automatic way (you could try accumarray with an anonymous function returning a cell array, but that has to be slower). It all depends on what foo internally does Commented Sep 6, 2015 at 20:27
  • An example of a fitting foo(x,secondArg) may be: return out = x.^2/secondArg Commented Sep 6, 2015 at 20:36
  • How does that secondArg depend on the cluster label? Do you have some kind of map from cluster label to secondArg? Commented Sep 6, 2015 at 20:41
  • It does not have to depend. It can be given by the user or may be calculated. for example, It can be the average over the cluster values. If there was no second argument, and foo() would calculate this value internally for each cluster, will your anwer vary? Commented Sep 6, 2015 at 20:43
  • 1
    I see. I misunderstood. Anyway, see my comment above. I think res = x.^2 ./ fooSecondArg(labelMap); would do Commented Sep 6, 2015 at 20:48

1 Answer 1

1

Whether the loop can be removed or not depends on the function you have. In your case the function is

function out = foo(x,secondArg)
out = x.^2/secondArg;

where secondArg depends on the cluster.

For this function (and for similar ones) you can indeed eliminate the loop as follows:

res = x.^2 ./ fooSecondArg(labelMap);

Here

  • labelMap is the same size of x (indicates the cluster label for each entry of x);
  • fooSecondArg is a vector of length equal to the number of clusters (indicates the second argument for each cluster).

Thus fooSecondArg(labelMap) is an array the same size of x, which for each point gives the second argument corresponding to that point's cluster. The operator ./ performs element-wise division to produce the desired result.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.