开发者

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

开发者 https://www.devze.com 2023-04-13 00:49 出处:网络
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).

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.


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.


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.


It's simple. Just make a cell like: C = num2cell(1:length(S)); then: out=arrayfun(@(x,c) c*x,S,C)

0

精彩评论

暂无评论...
验证码 换一张
取 消