Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving element index in spfun, cellfun, arrayfun, etc. in MATLAB

Tags:

matlab

Is there any way to retrieve the index of the element on which a function called by cellfun, arrayfun or spfun acts? (i.e. retrieve the index of the element within the scope of the function).

For the sake of simplicity, imagine I have the following toy example:

S = spdiags([1:4]',0,4,4)
f = spfun(@(x) 2*x,S)

which builds a 4x4 sparse diagonal matrix and then multiplies each element by 2.

And say that now, instead of multiplying each element by the constant number 2, I would like to multiply it by the index the element has in the original matrix, i.e. assuming that linear_index holds the index for each element, it would be something like this:

S = spdiags([1:4]',0,4,4)
f = spfun(@(x) linear_index*x,S)

However, note the code above does not work (linear_index is undeclared).

This question is partially motivated by the fact that blocproc gives you access to block_struct.location, which one could argue references the location (~index) of the current element within the full object (an image in this case):

block_struct.location: A two-element vector, [row col], that specifies the position of the first pixel (minimum-row, minimum-column) of the block data in the input image.

like image 792
Amelio Vazquez-Reina Avatar asked Oct 12 '11 14:10

Amelio Vazquez-Reina


2 Answers

No, but you can supply the linear index as extra argument.

Both cellfun and arrayfun accept multiple input arrays. Thus, with e.g. arrayfun, you can write

a = [1 1 2 2];
lin_idx = 1:4;
out = arrayfun(@(x,y)x*y,a,lin_idx);

This doesn't work with spfun, unfortunately, since it only accepts a single input (the sparse array).

You can possibly use arrayfun instead, like so:

S = spdiags([1:4]',0,4,4);
lin_idx = find(S);

out = spones(S);
out(lin_idx) = arrayfun(@(x,y)x*y,full(S(lin_idx)),lin_idx);
%# or
out(lin_idx) = S(lin_idx) .* lin_idx;

Note that the call to full won't get you into memory trouble, since S(lin_idx) is 0% sparse.

like image 67
Jonas Avatar answered Nov 13 '22 08:11

Jonas


You can create a sparse matrix with linear_index filling instead of values.

Create A:

A(find(S))=find(S)

Then use A and S without spfun, e.g.: A.*S. This runs very fast.

like image 33
cyborg Avatar answered Nov 13 '22 08:11

cyborg