Giving default values to only some function variables in Matlab - matlab

I made a Matlab function
function foo(argone, argtwo)
The begining of the function allow to have default choices for those variables if the function is called only with one or even zero arguments
function foo(argone, argtwo)
if(~exist('argone','var'))
argone = defaultargone;
end
if(~exist('argtwo', 'var'))
argtwo = defaultargtwo;
end
... % Rest of the code
We can call the function as
foo() % Default values are assigned to argone and argtwo
foo(myargone) % Default value given to argtwo
foo(myargone, myargtwo) % No default values are used
But how to be able to give default value to argone only?
If function is called with
foo(~, myargtwo)
no default values are used; argone get the null value (that is not the default value)
Thank you for your help

An alternate way would be to include the option for handling an empty input:
function foo(argone, argtwo)
if ~exist('argone','var')||isempty(argone)
argone = defaultargone;
end
if ~exist('argtwo','var')||isempty(argtwo)
argtwo = defaultargtwo;
end
Then any of these should work:
foo()
foo([],[])
foo(argone)
foo([], argtwo)

The language itself does not support such inputs. A common workaround uses parameter value pairs.
Usange would be
foo('myargone',1, 'myargtwo',2)
foo('myargtwo',3)
foo('myargone',4)
In your function, you have to use varargin and the input parser

Related

User-Defined Option Argument for Custom Function in Matlab

Thanks in advance,
I want to write a new Matlab function code with different options for sub-algorithms for two distinct steps dealing the input argument/s. An example of one solution can be illustrated by use of switch-case statement such as:
function Return = Calculator(input,option1,option2)
switch option1
case 'Algorithm1_Opt1'
sub=f_Algorithm1_Opt1(input)
case 'Algorithm2_Opt1'
sub=f_Algorithm2_Opt1(input)
end
switch option2
case 'Algorithm1_Opt2'
Return=f_Algorithm1_Opt2(sub)
case 'Algorithm2_Opt2'
Return=f_Algorithm2_Opt2(sub)
end
My question: is there a way to specify custom options structure for an user-defined function as in optimset like;
options = optimset('param1',value1,'param2',value2,...)
such as;
options = optimset('Display','iter','TolX',1e-8)
So at last, I want to call my function as;
Return_exp=Calculator(input_exp,'option1','Algorithm1_Opt1','option2','Algorithm2_Opt2')
Regards.
As others have pointed out you can use the inputParser class or varargin. The inputParser implementation is sometimes too simplistic for coding complex problems. I usually prefer using varargin in these circumstances. Below are some templates I used.
For parameter parsing in functions:
function output=myfunc(requiredArg1,requiredArg2,varargin)
%% Parse Param-Value Inputs
PARAM_NAMES={'name1','name2'};
PARAM_VALUES={value1_default,value2_default};
n=1;
N=numel(varargin);
while n<N
% Read parameter name.
if ischar(varargin{n}) && isrow(varargin{n})
tf=strcmpi(varargin{n},PARAM_NAMES);
if any(tf)
% Set parameter value.
PARAM_VALUES{tf}=varargin{n+1};
else
error('Unrecognized parameter name.');
end
else
error('Unrecognized input. Parameter name must be a string.');
end
n=n+2;
end
if n<=N
warning('An extra input argument was provided, but is ignored.');
end
%% Program
end
For parameter parsing in constructors for handle classes:
methods
function obj=ObjectName(requiredArg1,requiredArg2,varargin)
%% Set Object Properties Using Param-Value Inputs
n=1;
N=numel(varargin);
while n<N
% Read property name.
if ischar(varargin{n}) && isrow(varargin{n})
mp=findprop(obj,varargin{n});
if isempty(mp)
error('''%s'' is not a property of the %s class.',varargin{n},class(obj));
elseif strcmpi(mp.SetAccess,'public')
obj.(varargin{n})=varargin{n+1};
else
error('Denied access to set the ''%s'' property.',varargin{n});
end
n=n+2;
end
end
if n<=N
warning('An extra input argument was provided, but is ignored.');
end
%% Program
end
end
The first template can be also be used for parameter parsing in constructors for value classes by setting PARAM_NAMES=properties(obj).

Is it possible to write a MATLAB script that can give command line input to a function?

I am writing MATLAB code that will fit together with other MATLAB functions that I cannot modify. Some of these existing functions take input from the command line. Is there a way I can write a test script in MATLAB that can call these functions, and then provide the input as the user would?
ie. if I have a function:
function y = f(x)
z = input('Enter number: ');
y = x + z;
end
Is there a way to have a script call f and provide z?
If you are looking for a non elegant solution.
If you are looking for a potentially dangerous solution.
Then you might try this: write a function named "input" as follows:
function a=input(str)
% THIS IS THE DUMMY VERSION OF THE
% MATLAB BUILT-IN FUNCTION "input"
global dummy_input
disp('WARNING!!!')
disp('MATLAB "input" built-in function overridded')
disp(['Setting dummy_inpt'])
a=dummy_input;
end
Declare a global variable either in the script you use to test the function and in your "dummy" input function.
Assign the desired value to the global variable as follows:
global dummy_input
x=3;
dummy_input=123;
y=my_func(x)
dummy_input=42.13;
y=my_func(x)
If my_func is the function you post in the question, you will obtain:
WARNING!!!
MATLAB "input" built-in function overridded
Setting dummy_inpt
y =
126
WARNING!!!
MATLAB "input" built-in function overridded
Setting dummy_inpt
y =
45.1300
I've added the printing of the warnings in the "dummy" input function yust as a remainder ...
You do not need to modify the function you want to test, when it will call input to get a number from the user, it will call your "dummy" input.
Version 2 of the "dummy" input function
This version of the "dummy" input function allows autonatically handling multiple request of input values.
It requires the user knows in advance how many times the "original" input function is called.
No additional global counter is required.
It is sufficient the change the definition of the global parameter in the script, declaring it as an array containing the set of input the user want to assign:
global input_list
input_list=[27 30 5 31 21]
In the "dummy" input function, the first element of the array is assigned to the output variable, then the it is deleted:
a=input_list(1);
input_list(1)=[];
the code of the updated version of the function is the following:
function a=input(str)
% THIS IS THE DUMMY VERSION OF THE
% MATLAB BUILT-IN FUNCTION "input"
global input_list
disp('WARNING!!!')
disp('MATLAB "input" built-in function overridded')
disp(' ')
disp(' ')
disp(' ')
if(isempty(input_list))
error('Error in DUMMY input: no more input data')
else
disp(['Setting dummy_input ' num2str(input_list(1))])
a=input_list(1);
disp(' ')
disp(' ')
disp(' ')
input_list(1)=[];
end
end
An error is generated in case the input array becomes empty (by deleting its element at each call) before the end of the script.
I've also added some calls to disp to make more "clear" the output on the Command Window.
Also the "dummy" input function print a message on the Command Window telling which input values has been assigned.
Make sure to remove your dummy "input" function at the end
Hope this helps.

Correct use of tilde operator for input arguments

Function:
My MATLAB function has one output and several input arguments, most of which are optional, i.e.:
output=MyFunction(arg1,arg2,opt1,opt2,...,optN)
What I want to do:
I'd like to give only arg1, arg2 and the last optional input argument optN to the function. I used the tilde operator as follows:
output=MyFunction(str1,str2,~,~,...,true)
Undesired result:
That gives the following error message:
Error: Expression or statement is incorrect--possibly unbalanced (, {, or [.
The error points to the comma after the first tilde, but I don't know what to make of it to be honest.
Problem identification:
I use MATLAB 2013b, which supports the tilde operator.
According to MATLAB's documentation the above function call should work:
You can ignore any number of function inputs, in any position in the argument list. Separate consecutive tildes with a comma...
I guess there are a few workarounds, such as using '' or [] as inputs, but I'd really like to understand how to correctly use '~' because actually leaving inputs out allows me to use exist() when checking the input arguments of a function.
If you need any further info from me, please let me know.
Thank you very much!
The tilde is only for function declaration. Matlab's mlint recommends to replace unused arguments by ~. The result is a function declared like this function output = MyFunction(a, b, ~, c). This is a very bad practice.
Since you have a function where the parameters are optional, you must call the function with empty arguments output=MyFunction(str1,str2,[],[],...,true).
A better way to do it is to declare the function with the varargin argument and prepare your function for the different inputs:
function output = MyFunction(varargin)
if nargin == 1
% Do something for 1 input
elseif nargin == 2
% Do something for 3 inputs
elseif nargin == 3
% Do something for 3 inputs
else
error('incorrect number of input arguments')
end
It is even possible to declare your function as follows:
function output = MyFunction(arg1, arg2, varargin)
The declaration above will tell Matlab that you are expecting at least two parameters.
See the documentation of nargin here.
... and the documentation of varargin here
To have variable number of inputs, use varargin. Use it together with nargin.
Example:
function varlist2(X,Y,varargin)
fprintf('Total number of inputs = %d\n',nargin);
nVarargs = length(varargin);
fprintf('Inputs in varargin(%d):\n',nVarargs)
for k = 1:nVarargs
fprintf(' %d\n', varargin{k})
end

What is the neatest way of passing flags to a Matlab function?

I'm designing a function that takes as argument one structure and any number of flags. The function will contain a couple of ifs checking whether a specific flag is set.
What is the neatest way to achieve this? I was thinking about passing the flags as separate string arguments. Is there a neater solution?
I would do it like using varargin and ismember:
function foo(arg1,arg2,varargin)
flag1=ismember('flag1',varargin);
flag2=ismember('flag2',varargin);
flag3=ismember('flag3',varargin);
And you can call the function like that:
foo(a1,a2,'flag3','flag1')
This will activate flag1 and flag3.
Pass in a struct of flags:
options = struct(...
'Flag1', true, ...
'Flag2', true, ...
'MySpecifFlag', false ...
);
Foo(st, options);
To get a list of all the flags that were explicitly set by the user, use fieldnames:
passedOptions = fieldnames(options);
This returns a cell array whose elements are strings - these strings are the flags set by the user; the ith element of the array is the ith flag set by the user.
Access the value of each flag that was set:
options.(passedOptions{i}) %# gets the value of the flag corresponding to passedOptions{i}
Probably you can pass varargin -
The even will be names of the flags and the odd their values (except the first)
function Foo(st, varargin)
end
Then pass values like this:
Foo(st, 'Flag1', true, 'Flag2', false)
Foo(st, 'Flag3', true, 'MyFlag2', false,'MySpecialFlag',false)
Foo(st)
To access the variable arguments use
varargin{2}, varargin{3},
etc..
To check whether a specific flag was passed, do
flagNames = varargin{2:end};
ismember('MyFlag',flagNames )
You can pass the flags as a string with 0s and 1s. The order can be fixed or you can also pass a cell array of flag names.
flagstr = '101'; %# string passed as argument
flaglog = flagstr=='1'; %# logical vector, can be accessed as flaglog(i)
fname = {'flag1','flag2','flag3'}; %# flag names, can be passed as argument or defined in the function
fvalue = num2cell(flaglog); %# create cell array
flags = cell2struct(fvalue, fname, 2); %# create a structure, so you can access a flag with flags.flag1
You need to take care to match the length of fvalue and fnames. if they are different you can either generate an error or somehow correct it (remove the extra flags or fill the absent by default value).
varargin is the way to go for parsing a variable number of arbitrary input arguments. If you want somemore control over the calling syntax of the function (i.e. optional/required arguments) then I suggest looking into Matlab's input parser.

Passing matrices from function to function in MATLAB

I'm pretty new to MATLAB and I have a simple question. What if I have the following structured functions:
function[A] = test(A)
test1(A);
test2(A);
end
function test1(A)
#% do something with A
end
function test2(A)
#% do something else with the newly modified A
end
How do I pass around A from function to function keeping it's modified nature? (Suppose A is a matrix)
EDIT: let's make the situation a little simpler. Suppose my main function is:
function[a]=test(a)
test1(a);
#%test2(a);
end
and test1() is defined as:
function[a] = test1(a)
a=5;
end
Then, I call the function test with test(3), and I want it to report ans = 5, yet it still reports ans = 3.
Thanks!
Variables in MATLAB are passed using "call by value" (with some exceptions), so any value that you pass to a function and modify has to be returned from the function and either placed in a new variable or the old variable overwritten. Returning the value of a variable from a function is simple: you just place the variable name in the output argument list for the function.
For your example, you would do this:
function A = test(A)
A = test1(A); %# Overwrite A with value returned from test1
A = test2(A); %# Overwrite A with value returned from test2
end
function A = test1(A) %# Pass in A and return a modified A
#% Modify A
end
function A = test2(A) %# Pass in A and return a modified A
#% Modify A
end
One thing to be aware of is variable scope. Every function has its own workspace to store its own local variables, so there are actually 3 unique A variables in the above example: one in the workspace of test, one in the workspace of test1, and one in the workspace of test2. Just because they are named the same doesn't mean they all share the same value.
For example, when you call test1 from test, the value stored in the variable A in test is copied to the variable A in test1. When test1 modifies its local copy of A, the value of A in test is unchanged. To update the value of A in test, the return value from test1 has to be copied to it.
Return the object from the function and then pass it on to the next function.