3

For any function, I am able to dictate the variables to be returned by explicitly defining how many outputs I am expecting [out1,out2,...,outn] = ...

Edit: Being able to maximize potential # of outputs would also be useful

Example problem

The following code does exactly what is expected (yes, it is redundant with myArray(IND) = 1;)

[I,J] = ind2sub(size(myArray),IND)
myArray(I,J) = 1;

When I try to pass the function arguments directly, I don't get the results I wannt

myArray(ind2sub(size(myArray),IND)) = 1;

I effectively get myArray(I) = 1; when I wanted myArray(I,J) = 1;

Question

How can I dictate how many output variables are returned without explicitly defining my output arguments?

I expect some function in the eval() family or some typecasting [],{},(:), etc. will do the trick but I have not seen any documentation or gotten any of them to work.

1 Answer 1

5

The immediate issue with using the output of ind2sub directly as an index into myArray without an intermediate variable is that only the first output of ind2sub is requested by subsindex when indexing into myArray. The first output is then used as a linear index to index into myArray and assign values which resulting in your unexpected behavior.

Instead, you can use a cell array to capture as many outputs as you want and then rely on {} indexing to yield a comma-separated list.

[outputs{1:ndims(myArray)}] = ind2sub(size(myArray), IND);

You can then use this cell array containing all outputs to then forward all values as inputs or subscripts elsewhere:

myArray(outputs{:}) = 1;

That being said, in the example that you've shown, you really don't need to do any of this as you can use the linear indices IND to index into myArray directly. In fact, using the output of ind2sub will likely give you the incorrect assignment as every permutation of the subscripts will be used when assigning values rather than the element-wise pairing of subscripts.

myArray(IND) = 1;

In general, you can use this technique along with nargout to request all output arguments if there is a non-variable number of outputs.

[outputs{1:nargout('func')}] = func(inputs);
Sign up to request clarification or add additional context in comments.

9 Comments

Ah thank you, you've highlighted why there is a need for explicit output definitions for builtin functions with variable outputs. I was hoping for an in-line solution that allows explicit output definitions without variable assignment (i.e. eval('foo(...),"nargout", 2') ) but I have not seen any evidence that one exists
@BrendanFrick I'm confused. There is. it's [outputs{1:2}] = thing
Can you call that inline? foo1([outputs{1:2}] = foo2(...))
@BrendanFrick No you need the temporary variable. I see what you are referring to now
@BrendanFrick Did you read my entire answer? The outputs that you're forwarding the way that you are aren't going to yield the correct result. See the linked post
|

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.