MATLAB Answers

Too many output argument error while using nested functions?

10 views (last 30 days)
mathLAB
mathLAB on 18 May 2020
Commented: mathLAB on 19 May 2020
Hi, I know this is a very common question. I have searched about the issue in multiple places but couldn't find a proper solution to my problem specifically.
So, I have one FEM code that gives multiple outputs, such as:
function [KAPPA, STIFF, BASIS] = RunGMsFEM
........
Then, I have another function that simulates the FEM code (training number) m times,
function [] = TrainData(fun, m, indices)
predefine some variables
...........
for k = 1:m
rng(k); % Here I am simulating some of the variables inside fun
[KAPPA, STIFF, BASIS] = fun; % I will run RunGMsFEM function here
for loop
.....
end
end
..........
save data as csv
The problem is that when I run the code:
[KAPPA, STIFF, BASIS] = RunGMsFEM
in command window I am not getting any error. But whenever I run the nested function
TrainData(RunGMsFEM, 100, some_indices)
I am getting too many output argument error on the exact same line:
[KAPPA, STIFF, BASIS] = fun
I know MATLAB doesn't let you assign multiple variables at one using vectors (like tuples in Python (a, b) = (3, 5)), and I understand the error but somehow it works perfectly when I run this code in command window. I tried to change my code into one output vector/matrix and then pull out he Z = [KAPPA, STIFF, BASIS] variables from the one output but the problem here all of the outputs have different size. For example: KAPPA is a vector, STIFF and BASIS are matrices with different sizes.
I can run the code in the command window but then I have to predefine all of the variables by hand which is annoying. Is there anyway to use a multiple output function inside another function?
Thank you,

  0 Comments

Sign in to comment.

Accepted Answer

Matt J
Matt J on 18 May 2020
Edited: Matt J on 18 May 2020
The code you've posted does not make it clear what problem you are encountering. There doesn't appear to be anything wrong in the code, and you haven't posted any error messages for us to examine.
However, it might help to mention that the Matlab equivalent of Python's (a, b) = (3, 5) would be,
>> [a,b]=deal(3,5)
a =
3
b =
5
Or an even more basic way would be,
a=3;
b=5;

  7 Comments

Show 4 older comments
mathLAB
mathLAB on 18 May 2020
I have posted the generic function definition, sure when I run the function I switch fun = RunGMsFEM, that's why I run the line below:
TrainData(RunGMsFEM, 100, some_indices)
where fun = RunGMsFEM, m =10 and indices = some_indices (predefined variable).
Matt J
Matt J on 18 May 2020
But as I mentioned a few comments ago, you cannot write fun = RunGMsFEM. You have to write,
fun = @RunGMsFEM
The '@' symbol is important!. Also, you must use parentheses, even if you are passing no arguments to fun,
[KAPPA, STIFF, BASIS] = fun() %The parentheses () are important here!
mathLAB
mathLAB on 19 May 2020
Yes, this works! Thank you. But it doesn't store any of the local variables. I guess I will change the output as the variables I need to store.
Thank you very much!

Sign in to comment.

More Answers (2)

Walter Roberson
Walter Roberson on 18 May 2020
[KAPPA, STIFF, BASIS] = fun % I will run RunGMsFEM function here
That is valid syntax; it is not obvious what difficulty you are having?
I tried to change my code into one outpu vector/matrix and then pull out he Z = [KAPPA, STIFF, BASIS] variables from the one output
Have you function emit a cell array ?
Is there anyway to use a multiple output function inside another function?
If you mean along the lines of
fun2(fun1())
where fun1 emits 3 outputs and fun2 expects 3 inputs, then NO, there is no way.
I have not been able to figure out the rules for the number of output arguments, but in the above case fun1() would always be called being told that only one output argument was expected.

  4 Comments

Show 1 older comment
Walter Roberson
Walter Roberson on 18 May 2020
fun does not appear to be the same as runGMsFEM . Perhaps you did something like
fun = RunGMsFEM;
[KAPPA, STIFF, BASIS] = fun
If so, then NO, that is not going to work and there is no way to make it work without changing RunGMsFEM .
If you change RunGMsFEM to emit a cell array (even if only in the case where nargout == 1) then you would be able to do
fun = RunGMsFEM;
[KAPPA, STIFF, BASIS] = fun{:};
Walter Roberson
Walter Roberson on 18 May 2020
You edited your comment after I replied...
TrainData(RunGMsFEM, 100, some_indices)
If the first position of TrainData is being received as the variable fun, then NO, there is no way to capture multiple outputs from RunGMsFEM there. The closest you can get is to have RunGMsFEM notice nargout == 1 and emit a cell array, and have TrainData pull the parts out of the cell array.

Sign in to comment.


Steven Lord
Steven Lord on 18 May 2020
The error message is correct. When you run this code:
TrainData(RunGMsFEM, 100, some_indices)
You are calling RunGMsFEM with one output and passing that output into TrainData as the first input argument. Therefore [KAPPA, STIFF, BASIS] = fun is an attempt to assign what's in the array fun into those three variables, and that MATLAB does not allow.
If you want to pass something that will allow TrainData to run RunGMsFEM with the desired number of outputs (instead of calling RunGMsFEM and passing whatver you received from that one call into TrainData) you need to specify the first input as a function handle to RunGMsFEM.
TrainData(@RunGMsFEM, 100, some_indices)
Compare:
x = 1:10;
callFunction = eps
makeFunctionHandle = @eps
"Passing x into" callFunction will error because it will ask for elements 1, 2, ... 10 of callFunction but callFunction only has one element.
callFunction(x)
Passing x into makeFunctionHandle will work and will call the eps function with the vector 1:10 as input.
out1 = makeFunctionHandle(x)
out2 = eps(x)
isequal(out1, out2) % true, calling makeFunctionHandle is like calling eps directly

Translated by