I am attempting to use the following function in Matlab's eeglab toolkit to rename events, which meet certain criteria (i.e., their latency is between two numbers):
EEGfastrts = pop_selectevent( EEG, 'latency',’0 <= fastval’,'type',{'AnyResponse'},'renametype','FastRTs','deleteevents','off','deleteepochs','off','invertepochs','off');
However, when I input a variable (i.e., fastval), instead of an int value, this function does not work.
I was wondering if anyone might have suggestions/work-arounds for using this function for a value that is represented by a variable. My goal is to insert the function into a loop, which will alter the variable value with every iteration.
Thank you in advance for your thoughts and input.
From the docs it expects that the 'latency' input is a char, so you need to create that using your variable. One option is to use sprintf() e.g:
fastval = 100; % some value
strLatency = sprintf( '0 < %.2f', fastval ); % output e.g. '0 < 100.00'
Then use this in your function call...
EEGfastrts = pop_selectevent( EEG, 'latency', strLatency, ...
'type', {'AnyResponse'}, 'renametype', 'FastRTs', ...
'deleteevents', 'off', 'deleteepochs', 'off', 'invertepochs', 'off');
Related
Is it possible to get the 'nth' return value from a function without having to create dummy variables for all n-1 return values before it?
Let's say, I have the following function in MATLAB:
function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;
Now suppose, I'm only interested in the third return value. This can be accomplished by creating one dummy variable:
[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;
But I think this is kind of ugly. I would think that you might be able to do something like one of the following things, but you can't:
[_, _, variableThatIWillUse, _] = func;
[, , variableThatIWillUse, ] = func;
variableThatIWillUse = func(3);
variableThatIWillUse = func()(3);
Are there any elegant ways to do this that do work?
So far, the best solution is to simply use the variableThatIWillUse as a dummy variable. This saves me from having to create a real dummy variable that pollutes the work-space (or that I would need to clear). In short: the solution is to use the variableThatIWillUse for every return value up until the interesting one. Return values after can simply be ignored:
[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;
I still think this is very ugly code.
With MATLAB Version 7.9 (R2009b) you can use a ~, e.g.,
[~, ~, variableThatIWillUse] = myFunction();
Note that the , isn't optional. Just typing [~ ~ var] will not work, and will throw an error.
See the release notes for details.
This is somewhat of a hack, but it works:
First a quick example function:
Func3 = #() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3
Now the key here is that if you use a variable twice on the left-hand side of a multiple-expression assignment, an earlier assignment is clobbered by the later assignment:
[b,b,c]=Func3();
% yields b=2, c=3
[c,c,c]=Func3();
% yields c=3
(Just to check, I also verified that this technique works with [mu,mu,mu]=polyfit(x,y,n) if all you care about from polyfit is the third argument.)
There's a better approach; see ManWithSleeve's answer instead.
If you wish to use a style where a variable will be left to fall into the bit bucket, then a reasonable alternative is
[ans, ans, variableThatIWillUse] = myfun(inputs);
ans is of course the default junk variable for MATLAB, getting overwritten often in the course of a session.
While I do like the new trick that MATLAB now allows, using a ~ to designate an ignored return variable, this is a problem for backwards compatibility, in that users of older releases will be unable to use your code.
I generally avoid using new things like that until at least a few MATLAB releases have been issued to ensure there will be very few users left in the lurch. For example, even now I find people are still using an old enough MATLAB release that they cannot use anonymous functions.
Here's another option you can use. First make a cell array to capture all the outputs (you can use the NARGOUT function to determine how many outputs a given function returns):
a = cell(1,3); % For capturing 3 outputs
% OR...
a = cell(1,nargout(#func)); % For capturing all outputs from "func"
Then call the function as follows:
[a{:}] = func();
Then simply remove the element from a that you want, and overwrite a:
a = a{3}; % Get the third output
I wrote a kth out function:
function kth = kthout(k, ffnc, varargin)
% kthout: take the kth varargout from a func call %FOLDUP
%
% kth = kthout(k, ffnc, varargin)
%
% input:
% k which varargout to get
% ffnc function to call;
% varargin passed to ffnc;
% output:
% kth the kth argout;
[outargs{1:k}] = feval(ffnc, varargin{:});
kth = outargs{k};
end %function
You can then call
val_i_want = kthout(3, #myfunc, func_input_1, func_input_2);
You could also wrap up the function like:
func_i_want = #(varargin)(kthout(3, #myfunc,varargin{:})); % Assuming you want the third output.
After which you use
val_i_want = func_i_want(func_input_1, func_input_2);
Note that there is overhead associated with using anonymous functions like this, and this is not something I would do in code that would be called thousands of times.
In MATLAB 2010a, I found a neat way of doing what you are asking for.
It is simply to use the character "~" (without the quotes of course) as your dummy variable (as many as you want when returning multiple parameters). This also works for input parameters to functions if the functions are designed to handle missing data.
I don't know if this existed in previous versions, but I just came across it recently.
You can make a function (or anonymous function) that only returns selected outputs, e.g.
select = #(a,b) a(b);
Then you can call your function like this:
select(func,2);
select(func,1:3);
Or you can assign the output to a variable:
output(1,2:4) = select(func,1:3);
I don't see any reason not to use ans(n). Like this:
size(rand([5 10 20 40]));
b = ans(2);
It gives b = 10, and this way would be compatible with all MATLAB versions. Note that size() here is just used to represent any function that has multiple return variables.
Furthermore, this works to get the second output argument when you don't know how many arguments there will be! Whereas, if you do this:
[~, b] = size(a);
Then b = 8000! (You need to end with ~, to catch more arguments!)
I have a set of functions that takes a cell array of tables and plots data from each table as a subplot on a figure. I have been learning to use the inputParser class to handle varargin inputs, and have that here. The optional parameters are for choosing plot type (plot or bar) and for choosing the names of the variables to plot from the input tables.
In my scenario, the inputs need to be passed along about 3 functions deep, so I'm wondering about best practices for doing this. In my current setup, the outermost function (main) takes a varargin input and parses the inputs by assigning defaults and such. Then I'm wondering, when it comes time to pass these inputs to the next function, is it best to pass the parsedInputs data Results struct down the line, or is it better to have the next function also take a varargin argument and to repeat the parsing process again? I'm not sure what the best way to go about this is. My code is below. The main script for test purposes looks as follows:
% RUN TEST CASE
Tables{1} = table([1 2 3]' , [6 7 8]', 'VariableNames', {'diam', 'length'});
Tables{2} = table([1 2 6]' , [6 9 2]', 'VariableNames', {'diam', 'length'});
Tables{3} = table([3 9 11]', [7 4 1]', 'VariableNames', {'diam', 'length'});
main(Tables);
The main function takes a (required) cell array of tables (Tables) and variable argument parameters, such as 'xVariable', 'yVariable', 'plotType'.
function main(Tables, varargin)%PlotParams, DICTS)
% parse inputs
parsedInputs = parse_plot_inputs(Tables, varargin);
% create figure of subplots
figure;
make_subplots_from_tables(parsedInputs);
end
A parse_plot_inputs function takes care of the default value assignment, etc.:
function parsedInputs = parse_plot_inputs(Tables, vararginList)
% input parser function for this specific plotting case
p = inputParser;
addRequired(p, 'Tables', #iscell);
addParameter(p, 'xVariable', 'diam');
addParameter(p, 'yVariable', 'length');
addParameter(p, 'plotType', 'plot');
parse(p, Tables, vararginList{:});
parsedInputs = p;
end
make_subplots_from_tables then loops through the cell array of tables, and calls plot_special to plot each of them on its own subplot.
function make_subplots_from_tables(parsedInputs)
% unpack parsed inputs
Tables = parsedInputs.Results.Tables;
% plot each table as a subplot
numTables = length(Tables);
for i = 1:numTables
subplot(numTables, 1, i); hold on;
plot_special(Tables{i}, parsedInputs)
end
end
plot_special is the "base" function in this scenario that calls the MATLAB plot functions:
function plot_special(T, parsedInputs)
% unpack parsed inputs
xVariable = parsedInputs.Results.xVariable;
yVariable = parsedInputs.Results.yVariable;
plotType = parsedInputs.Results.plotType;
% plot single table on one plot
xVals = T.(xVariable);
yVals = T.(yVariable);
switch plotType
case 'plot'
plot(xVals, yVals, '-x');
case 'bar'
bar(xVals, yVals);
otherwise
error('invalid plot type');
end
end
I am unsure whether this is the best method for taking in arguments and for using them in subsequent functions. This method works, although I'm not sure that it's the best practice, nor the most flexible, for example, considering the scenario when I would like to use plot_special on its own, and would like to be able to pass it arguments for xVariable, yVariable, etc. if need be. Given that it is currently dependent on the parsedInputs list from the main function, that wouldn't be doable. However, I'm unsure what another way to define it would be. I considered having an if statement built in along with a varargin input argument that checks whether the varargin is an already-parsed struct, or if it's getting the variables directly and needs to call the parse_plot_inputs itself to get things working. Any advice would be great.
There is no single "best" method, it all depends on circumstances. What you are doing is fine if the functions that take an inputParser object are private sub-functions. If they are generic functions that should work independently, they should have their own argument parsing. One thing you could do, given that you want plot_special to be a stand-alone function, is as follows:
function main(Tables, varargin)
figure;
make_subplots_from_tables(Tables, varargin{:});
end
function make_subplots_from_tables(Tables, varargin)
% plot each table as a subplot
numTables = length(Tables);
for i = 1:numTables
subplot(numTables, 1, i); hold on;
plot_special(Tables{i}, varargin{:})
end
end
function plot_special(T, varargin)
% parse `varargin` to yield `xVariable`, `yVariable`, `plotType`
% plot single table on one plot
end
This way you do the parameter parsing only where necessary, although it is done once for each table plotted, rather than only once for the whole graph. This is probably a very minor issue though, since parameter parsing is not nearly as expensive as plotting.
Say I want to create an anonymous function from a m-file-function that returns two outputs. Is it possible to set up the anonymous function such that it only returns the second output from the m-file-function?
Example: ttest2 returns two outputs, t/f and a probability. If I want to use the t-test with cellfun, I might only be interested in collecting the probabilities, i.e. I'd like to write something like this
probabilities = cellfun(#(u,v)ttest2(u,v)%take only second output%,cellArray1,cellArray2)
There's no way I know of within the expression of the anonymous function to have it select which output to return from a function with multiple possible output arguments. However, you can return multiple outputs when you evaluate the anonymous function. Here's an example using the function MAX:
>> data = [1 3 2 5 4]; %# Sample data
>> fcn = #(x) max(x); %# An anonymous function with multiple possible outputs
>> [maxValue,maxIndex] = fcn(data) %# Get two outputs when evaluating fcn
maxValue =
5 %# The maximum value (output 1 from max)
maxIndex =
4 %# The index of the maximum value (output 2 from max)
Also, the best way to handle the specific example you give above is to actually just use the function handle #ttest2 as the input to CELLFUN, then get the multiple outputs from CELLFUN itself:
[junk,probabilities] = cellfun(#ttest2,cellArray1,cellArray2);
On newer versions of MATLAB, you can replace the variable junk with ~ to ignore the first output argument.
One way to do this is to define the function:
function varargout = getOutput(func,outputNo,varargin)
varargout = cell(max(outputNo),1);
[varargout{:}] = func(varargin{:});
varargout = varargout(outputNo);
end
and then getOutput(#ttest2,2,u,v) gives only the p-value.
To use it in a cellfun you would need to run:
probabilities = cellfun(#(u,v)getOutput(#ttest2,2,u,v)...
This eliminates the need to write a wrapper every time, but then you have to make sure this function is always in the path.
Say I want to create an anonymous function from a m-file-function that returns two outputs. Is it possible to set up the anonymous function such that it only returns the second output from the m-file-function?
Example: ttest2 returns two outputs, t/f and a probability. If I want to use the t-test with cellfun, I might only be interested in collecting the probabilities, i.e. I'd like to write something like this
probabilities = cellfun(#(u,v)ttest2(u,v)%take only second output%,cellArray1,cellArray2)
There's no way I know of within the expression of the anonymous function to have it select which output to return from a function with multiple possible output arguments. However, you can return multiple outputs when you evaluate the anonymous function. Here's an example using the function MAX:
>> data = [1 3 2 5 4]; %# Sample data
>> fcn = #(x) max(x); %# An anonymous function with multiple possible outputs
>> [maxValue,maxIndex] = fcn(data) %# Get two outputs when evaluating fcn
maxValue =
5 %# The maximum value (output 1 from max)
maxIndex =
4 %# The index of the maximum value (output 2 from max)
Also, the best way to handle the specific example you give above is to actually just use the function handle #ttest2 as the input to CELLFUN, then get the multiple outputs from CELLFUN itself:
[junk,probabilities] = cellfun(#ttest2,cellArray1,cellArray2);
On newer versions of MATLAB, you can replace the variable junk with ~ to ignore the first output argument.
One way to do this is to define the function:
function varargout = getOutput(func,outputNo,varargin)
varargout = cell(max(outputNo),1);
[varargout{:}] = func(varargin{:});
varargout = varargout(outputNo);
end
and then getOutput(#ttest2,2,u,v) gives only the p-value.
To use it in a cellfun you would need to run:
probabilities = cellfun(#(u,v)getOutput(#ttest2,2,u,v)...
This eliminates the need to write a wrapper every time, but then you have to make sure this function is always in the path.
Is it possible to get the 'nth' return value from a function without having to create dummy variables for all n-1 return values before it?
Let's say, I have the following function in MATLAB:
function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;
Now suppose, I'm only interested in the third return value. This can be accomplished by creating one dummy variable:
[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;
But I think this is kind of ugly. I would think that you might be able to do something like one of the following things, but you can't:
[_, _, variableThatIWillUse, _] = func;
[, , variableThatIWillUse, ] = func;
variableThatIWillUse = func(3);
variableThatIWillUse = func()(3);
Are there any elegant ways to do this that do work?
So far, the best solution is to simply use the variableThatIWillUse as a dummy variable. This saves me from having to create a real dummy variable that pollutes the work-space (or that I would need to clear). In short: the solution is to use the variableThatIWillUse for every return value up until the interesting one. Return values after can simply be ignored:
[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;
I still think this is very ugly code.
With MATLAB Version 7.9 (R2009b) you can use a ~, e.g.,
[~, ~, variableThatIWillUse] = myFunction();
Note that the , isn't optional. Just typing [~ ~ var] will not work, and will throw an error.
See the release notes for details.
This is somewhat of a hack, but it works:
First a quick example function:
Func3 = #() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3
Now the key here is that if you use a variable twice on the left-hand side of a multiple-expression assignment, an earlier assignment is clobbered by the later assignment:
[b,b,c]=Func3();
% yields b=2, c=3
[c,c,c]=Func3();
% yields c=3
(Just to check, I also verified that this technique works with [mu,mu,mu]=polyfit(x,y,n) if all you care about from polyfit is the third argument.)
There's a better approach; see ManWithSleeve's answer instead.
If you wish to use a style where a variable will be left to fall into the bit bucket, then a reasonable alternative is
[ans, ans, variableThatIWillUse] = myfun(inputs);
ans is of course the default junk variable for MATLAB, getting overwritten often in the course of a session.
While I do like the new trick that MATLAB now allows, using a ~ to designate an ignored return variable, this is a problem for backwards compatibility, in that users of older releases will be unable to use your code.
I generally avoid using new things like that until at least a few MATLAB releases have been issued to ensure there will be very few users left in the lurch. For example, even now I find people are still using an old enough MATLAB release that they cannot use anonymous functions.
Here's another option you can use. First make a cell array to capture all the outputs (you can use the NARGOUT function to determine how many outputs a given function returns):
a = cell(1,3); % For capturing 3 outputs
% OR...
a = cell(1,nargout(#func)); % For capturing all outputs from "func"
Then call the function as follows:
[a{:}] = func();
Then simply remove the element from a that you want, and overwrite a:
a = a{3}; % Get the third output
I wrote a kth out function:
function kth = kthout(k, ffnc, varargin)
% kthout: take the kth varargout from a func call %FOLDUP
%
% kth = kthout(k, ffnc, varargin)
%
% input:
% k which varargout to get
% ffnc function to call;
% varargin passed to ffnc;
% output:
% kth the kth argout;
[outargs{1:k}] = feval(ffnc, varargin{:});
kth = outargs{k};
end %function
You can then call
val_i_want = kthout(3, #myfunc, func_input_1, func_input_2);
You could also wrap up the function like:
func_i_want = #(varargin)(kthout(3, #myfunc,varargin{:})); % Assuming you want the third output.
After which you use
val_i_want = func_i_want(func_input_1, func_input_2);
Note that there is overhead associated with using anonymous functions like this, and this is not something I would do in code that would be called thousands of times.
In MATLAB 2010a, I found a neat way of doing what you are asking for.
It is simply to use the character "~" (without the quotes of course) as your dummy variable (as many as you want when returning multiple parameters). This also works for input parameters to functions if the functions are designed to handle missing data.
I don't know if this existed in previous versions, but I just came across it recently.
You can make a function (or anonymous function) that only returns selected outputs, e.g.
select = #(a,b) a(b);
Then you can call your function like this:
select(func,2);
select(func,1:3);
Or you can assign the output to a variable:
output(1,2:4) = select(func,1:3);
I don't see any reason not to use ans(n). Like this:
size(rand([5 10 20 40]));
b = ans(2);
It gives b = 10, and this way would be compatible with all MATLAB versions. Note that size() here is just used to represent any function that has multiple return variables.
Furthermore, this works to get the second output argument when you don't know how many arguments there will be! Whereas, if you do this:
[~, b] = size(a);
Then b = 8000! (You need to end with ~, to catch more arguments!)