How do I pass a variable number of outputs through two functions?

10 views (last 30 days)
MaxT
MaxT on 15 Oct 2020
Commented: Walter Roberson on 15 Oct 2020
I am trying to return a variable number of outputs, but sometimes these outputs have to be passed through an intermediary function, and sometimes not.
I am using the MATLAB built-in Sensor Data Collection functions and constantly logging accelerometer data and GPS data on a phone (there are actually 7 sensor types, but I simplified it to 2 types for this question). This data is retrieved with unique functions. Accelerometer data (3 output arrays) is output from the "accellog" built-in function, and GPS data (7 output arrays) is output from the "poslog" built-in function, where n is the number of measurements.
I have two functions that I use to pull data from these datasets:
Function 1: "GetData" pulls all the data from a specified dataset. A string "sensorDataString" specifies the type of data that is being requested (this is needed so that functions can be generalized for different sensors).
function varargout = GetData(mobileObj, sensorDataString)
switch sensorDataString
case 'Acceleration'
[varargout{1:2}] = accellog(mobileObj);
case 'GPS'
[varargout{1:7}] = poslog(mobileObj);
end
end
Function 2: "GetSecondsOfData" returns a portion of the data set based on waiting a specified amount of time between , but relies on the "GetData" function to grab data in the first place.
% Return a set of mobile sensor measurements that span the specified number of seconds
function varargout = GetSecondsOfData(mobileObj, sensorDataString, numSeconds)
[tempdata, ~] = GetData(mobileObj, sensorDataString);
startIndx = size(tempdata,1) + 1; % Determine the starting index of measurements
pause(numSeconds) % Collect data for the specified number of seconds
varargout = GetData(mobileObj, sensorDataString);
for i = 1:size(varargout)
varargout{i} = varargout{i}(startIndx:end,:); % Pull out desired section of data
end
end
The errors occur when attempting to assign varargout from "GetData" and "GetSecondsOfData".
Is there a generalized way to pass a variable number of outputs from one function then pass these outputs through the calling function? (Or is there a better approach to this problem?)
I can use a switch-case structure to determine the number of outputs in the "GetSecondsofData" function, but this looks messy with 7 sensors. I could also output data in a different form (cell arrays) then deal them, but outputting multiple variables with varargout is the easiest to handle especially since I will sometimes use "GetData" and sometimes use "GetSecondsOfData", so I would have to assign outputs from cell arrays.
If you know the number of outputs you can use code like:
[varargout{1:7}] = poslog(mobileObj);
I'm looking for something that looks more like this, where the number of cells does not have to be specified:
varargout = GetData(mobileObj, sensorDataString);

Accepted Answer

J. Alex Lee
J. Alex Lee on 15 Oct 2020
Edited: J. Alex Lee on 15 Oct 2020
Currently your GetData function literally has no purpose other than to alias the function you want with other names...the mechanism below can achieve this for variable number of outputs, but in my view is more useless now that you have to specify the function name exactly anyway:
function varargout = GetData(mobileObj, sensorDataFun)
nargs = nargout(sensorDataFun);
[varargout{1:nargs}] = sensorDataFun(mobileObj);
end
As Stephen suggested, maybe GetData's purpose is to wrangle variable outputs into cell outputs:
function DataCell = GetData(mobileObj, sensorDataFun)
nargs = nargout(sensorDataFun);
[DataCell{1:nargs}] = sensorDataFun(mobileObj);
end
Then in the caller function
function DataCell = GetSecondsOfData(mobileObj, sensorDataFun, numSeconds)
tempdata = GetData(mobileObj, sensorDataString);
startIndx = size(tempdata{1},1) + 1; % Determine the starting index of measurements
pause(numSeconds) % Collect data for the specified number of seconds
DataCell = GetData(mobileObj, sensorDataFun);
for i = 1:numel(DataCell) % size isn't a good function to use here
DataCell{i} = DataCell{i}(startIndx:end,:); % Pull out desired section of data
end
end
If you really want to keep the variable number of outputs for GetSecondsOfData, but don't actually care about having GetData as a separate functionality, then
function varargout = GetSecondsOfData(mobileObj, sensorDataFun, numSeconds)
nargs = nargout(sensorDataFun);
[tempdata{1:nargs}] = sensorDataFun(mobileObj);
startIndx = size(tempdata{1},1) + 1; % Determine the starting index of measurements
pause(numSeconds) % Collect data for the specified number of seconds
[DataCell{1:nargs}] = sensorDataFun(mobileObj);
for i = 1:numel(DataCell) % size isn't a good function to use here
DataCell{i} = DataCell{i}(startIndx:end,:); % Pull out desired section of data
end
varargout = DataCell;
end
  13 Comments
Walter Roberson
Walter Roberson on 15 Oct 2020
nargout('ClassName>ClassName.MethodName')
Hmmm....
>> nargout('string>string.gt')
Error using nargout
Not a valid MATLAB file.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!