Is there a splat operator (or equivalent) in Matlab?
Asked Answered
L

1

14

If I have an array (of unknown length until runtime), is there a way to call a function with each element of the array as a separate parameter?

Like so:

foo = @(varargin) sum(cell2mat(varargin));
bar = [3,4,5];
foo(*bar) == foo(3,4,5)

Context: I have a list of indices to an n-d array, Q. What I want is something like Q(a,b,:), but I only have [a,b]. Since I don't know n, I can't just hard-code the indexing.

Limitation answered 11/1, 2012 at 19:39 Comment(0)
P
16

There is no operator in MATLAB that will do that. However, if your indices (i.e. bar in your example) were stored in a cell array, then you could do this:

bar = {3,4,5};   %# Cell array instead of standard array
foo(bar{:});     %# Pass the contents of each cell as a separate argument

The {:} creates a comma-separated list from a cell array. That's probably the closest thing you can get to the "operator" form you have in your example, aside from overriding one of the existing operators (illustrated here and here) so that it generates a comma-separated list from a standard array, or creating your own class to store your indices and defining how the existing operators operate for it (neither option for the faint of heart!).

For your specific example of indexing an arbitrary N-D array, you could also compute a linear index from your subscripted indices using the sub2ind function (as detailed here and here), but you might end up doing more work than you would for my comma-separated list solution above. Another alternative is to compute the linear index yourself, which would sidestep converting to a cell array and use only matrix/vector operations. Here's an example:

% Precompute these somewhere:
scale = cumprod(size(Q)).';  %'
scale = [1; scale(1:end-1)];
shift = [0 ones(1, ndims(Q)-1)];

% Then compute a linear index like this:
indices = [3 4 5];
linearIndex = (indices-shift)*scale;
Q(linearIndex)  % Equivalent to Q(3,4,5)
Panne answered 11/1, 2012 at 19:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.