0

I've searched and there are many answers to this kind of question, suggesting functions like arrayfun, bsxfun, and so on. I haven't been able to resolve the issue due to dimension mismatches (and probably a fundamental misunderstanding as to how MATLAB treats anonymous function handles).

I have a generic function handle of more than one variable:

f = @(x,y) (some function of x, y)

Heuristically, I would like to define a new function handle like

g = @(x) sum(f(x,1:3))

More precisely, the following does exactly what I need, but is tedious to write out for larger arrays (say, 1:10 instead of 1:3):

g = @(x) f(x,1)+f(x,2)+f(x,3)

I tried something like

g = @(x) sum(arrayfun(@(y) f(x,y), 1:3))

but this does not work as soon as the size of x exceeds 1x1.

Thanks in advance.

2
  • Is it not an option to vectorize f, so that it also accepts array input for y and not just x? Otherwise what are the allowed dimensions of x? Commented Jan 15, 2016 at 19:04
  • 1
    The answer I gave is based on the limited information provided. A better solution may be possible if you provide the implementation of f since it may be possible to vectorize the output in some manner. Commented Jan 15, 2016 at 20:10

1 Answer 1

2

Assuming you cannot change the definition of f to be more vector-friendly, you can use your last solution by specifying a non-uniform output and converting the output cell array to a matrix:

g = @(x) sum(cell2mat(arrayfun(@(y) f(x,y), 1:3,'UniformOutput',false)),2);

This should work well if f(x,y) outputs column vectors and you wish to sum them together. For rows vectors, you can use

g = @(x) sum(cell2mat(arrayfun(@(y) f(x,y), 1:3,'UniformOutput',false).'));

If the arrays are higher in dimension, I actually think a function accumulator would be quicker and easier. For example, consider the (extremely simple) function:

function acc = accumfun(f,y)
    acc = f(y(1));
    for k = 2:numel(y)
        acc = acc + f(y(k));
    end
end

Then, you can make the one-liner

g = @(x) accumfun(@(y) f(x,y),y);
Sign up to request clarification or add additional context in comments.

6 Comments

I was just about to write almost the same:) However: does this work for any size of input for x? I was thinking along the lines of C=arrayfun(@(y)f(x,y),1:3,'uniformoutput',false); sum(cat(length(size(x))+1,C{:}),length(size(x))+1) for a general array of x, this should preserve the shape. But putting that into an anon function is messy.
@AndrasDeak The shape of x shouldn't matter; only the shape of f(x,y). And since the OP says that f(x,1)+f(x,2)+f(x,3) works, I assume the output array is regular enough that a one-liner could work ... we'll see.
cell2mat will concatenate the cell in 2d, right? While f(x,1)+f(x,2) will work for matrix-valued output. I might be wrong though.
@AndrasDeak You're right. cell2mat smashes the arrays together which will not produce a proper sum for general arrays. Rethinking.
Ooh, nice one with the accumulator:)
|

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.