passing anonymous functions through inputParser (matlab) - matlab

I'm trying to use Matlab's inputParser for the first time, and I have to say I'm finding it a bit confusing. I am unable to successfully provide an anonymous function as an optional parameter.
This is the function I am passing arguments to
function myfun(str,bounds,varargin)
p = inputParser;
p.FunctionName = mfilename;
p.addRequired('str',#isstr);
p.addRequired('bounds',#isvector);
p.addOptional('str_latex','',#isstr);
p.addOptional('seed',[], #(x) isa(x,'function_handle'))
p.parse(str,bounds,varargin{:});
p.Results
% do something here
end
And I am calling it like this...
myfun('str', 'epsilon',...
'str_latex', '\epsilon',...
'bounds', [0 1],...
'seed', #() betarnd(2,2))
But I get an error:
Error using my fun
The value of 'seed' is invalid. It must satisfy the function: #(x)isa(x,'function_handle').
I suspect a simple error, but I cannot figure it out.

Name-value pairs are declared using the addParameter method (R2013b+, addParamValue prior to that). addRequired and addOptional do not have name-value pairs associated with them, simply identifying/documenting argname inputs for internal use and association with the parsed struct. It appears you want to use all addParamter-s in this use case.
The main idea behind the three input types is
Required: the very first arguments with explicit, documented inputnames that absolutely need to be supplied by the user for the function to perform properly.
Optional: arguments that typically follow Required arguments with explicit, documented inputnames that are often input by the user for customized behavior.
Name-Value: arguments that typically follow Optional arguments with a name specifying the value to be set are often input by the user for customized behavior but not so often as to be given an upfront, explicit parameter like Optional arguments.
In my experience, Required arguments are almost always obvious, for good, well-defined functions, while Optional and Name-Value is more experience-, complexity-, and aesthetics-based. A simple example would be linspace: the start and end of the interval are absolutely needed for the function to work, but not necessarily the number of points which can be left to 100 by default, but giving it an explicit name-value pair is a little overkill. A more complex example would be the plot function: at a minimum y data is needed, then x,y pairs of data, then x,y,linSpec sets of data, and then a whole list of specific name-value pairs for pinpoint customization that users can use if they so choose.
With your input parser as written, the call sequence should be:
myfun('epsilon',[0,1],'\epsilon',#() betarnd(2,2));
Since no name-value pairs were declared, none exist, but the Optional arguments still have a positional order associated with them. You can re-write your parser as:
function myfun(varargin)
p = inputParser;
p.FunctionName = mfilename;
p.addParameter('str',[],#isstr);
p.addParameter('bounds',[],#isvector);
p.addParameter('str_latex','',#isstr);
p.addParameter('seed',[], #(x) isa(x,'function_handle'))
p.parse(str, bounds, varargin{:});
p.Results
% do something here
end
For something like the generic input sequence you may have been expecting. Notice that I used []-s to fail the simple validations without a good error message; you should add a good error message indicating that those name-value pairs are required for proper functionality, or do as you were doing and have explicit, upfront Required inputs with addRequired but without the name-value semantics.

Related

How to test arguments for a figure or axis object in MATLAB 2022?

A function receives a figure or axis object object as parameter.
I want to test this as shown in the FIXME line.
Which test should be used here in order to allow all valid objects for exportgraphics?
% myexportgraphics.m
function myexportgraphics(f)
arguments
f (1,1) {}; % FIXME add a test here
end
exportgraphics(f,...);
end
This full list of validation functions is documented here:
https://uk.mathworks.com/help/matlab/matlab_prog/argument-validation-functions.html
The only relevant one for checking the input type (other than ones for specific types like "double") is mustBeUnderlyingType
You can check which types are valid using underlyingType on example objects you want to accept.
underlyingType( figure() ); % 'matlab.ui.Figure'
underlyingType( axes() ); % 'matlab.graphics.axis.Axes'
So this would check for figures
function myexportgraphics(f)
arguments
f (1,1) {mustBeUnderlyingType(f,'matlab.ui.Figure')};
end
end
However, that doesn't allow multiple variable types, so per the docs you probably want to make your own validation function
function myexportgraphics(f)
arguments
f (1,1) {mustBeExportGraphicsType(f)};
end
end
function mustBeExportGraphicsType(g)
if ~ismember( class(g), {'matlab.ui.Figure','matlab.graphics.axis.Axes'} )
eidType = 'mustBeExportGraphicsType:notExportGraphicsType';
msgType = 'Input must be a figure or axes object';
throwAsCaller(MException(eidType,msgType));
end
end
These are the requirements for a custom validation function, emphasis mine:
Functions used for validation have these design elements:
Validation functions do not return outputs or modify program state. The only purpose is to check the validity of the input value.
Validation functions must accept the value being validated as an input argument. If the function accepts more than one input argument, the first input is the value to be validated.
Validation functions rely only on the inputs. No other values are available to the function.
Validation functions throw an error if the validation fails. Using throwAsCaller to throw exceptions avoids showing the validation function itself in the displayed error message.
Creating your own validation function is useful when you want to provide specific validation that is not available using the MATLAB validation functions. You can create a validation function as a local function within the function file or place it on the MATLAB path.
As an aside, you could use ishghandle within the custom validation function which returns true for figure and axes inputs. If you didn't use the arguments validation syntax, you could instead use ishghandle with the slightly older inputParser approach to input validation, or a simple assert near the start of your function, but that's probably beyond the scope of this question.

Built-in list of numeric types in Matlab

Does Matlab provide a list of numeric datatypes?
Some functions, like zeros, take an optional typename argument, a string naming a numeric type (e.g., 'double' or 'uint8'), that determines the type of the returned array. I would like to add something similar to my own code, and a complete list of numeric types would help with argument validation, as in:
ip = inputParer()
...
ip.addParameter('DataType', 'double', #(x) ismember(x, numeric_types()));
It seems as though something similar must exist, but I haven't been able to find it.
isnumeric checks an instance, rather than the typename itself.
superclasses doesn't return anything for numeric types on 2018b.
Obviously, this is not hard to implement, but it'd be nice to use a built-in if it existed.

What is the use of minizinc fix function?

i see that fix documentation says:
http://www.minizinc.org/doc-lib/doc-builtins-reflect.html#Ifunction-dd-T-cl-fix-po-var-opt-dd-T-cl-x-pc
function array [$U] of $T: fix(array [$U] of var opt $T: x)
Check if the value of every element of the array x is fixedat this point in evaluation. If all are fixed, return an array of their values, otherwise abort.
I am thinking it can be used to coerce a var to a par.
Here is the code.
array [1..num] of var int: value ;
%% generate random numbers from 0..num-1, this should fix the value of the var "value" or so i think
constraint forall(i in index_set(value))(let {int:temp_value=discrete_distribution([1|i in index_set(value)]); } in value[i]=trace(show(temp_value)++"\n", temp_value));
%%% this i was expecting to work, as "value" elements are fixed above
array [1..num] of int:value__ =[ trace(show(fix(value[i])), fix(value[i])) | i in index_set(value)] ;
But i get:
MiniZinc: evaluation error:
with i = 1
in call 'trace'
in call 'fix'
expression is not fixed
My questions are:
1) I think i should expect this error as minizinc is not sequential execution language?
2) Examples of fix in user guide is only where output statement is used. Is it the only place to use fix?
3) How would i coerce a var to a par?
By the way I am trying this var to par conversion because i am having problem with array generator expression. Here is the code
int:num__=200;
int:seed=134;
int: two_m=2097184;
%% prepare weights for generating numbers form 1..(two_m div 64), basically same weight
array [1..(two_m div 64)] of int: value_6_wt= [seed+1 | i in 1..(two_m div 64)] ;
%% generate numbers. this dose not work gives out
%% in variable declaration for 'value6'
%% parameter value out of range
array [1..num__] of int : value6 = [ discrete_distribution(value_6_wt) | j in 1..num__];
In the MiniZinc language the difference between a parameter and a variable is only the fact that a parameter must have a value at compile time. Within the compiler we turn as many variables into parameters as we can. This saves the solver from having to do some work. When we know that a variable has been turned into a parameter, then we can use the fix function to convince the type system that we really can use this variable as a parameter and see its value.
The problem here however is that fix is defined to abort when the variable is not fixed to one value. If no testing is done, this requires some (magic/)knowledge about the compilation process. In your case it seems that the second array is evaluated before the optimisation stage, in which all aliasing is resolved. This is the reason why it does not work. (This is indeed one of the things that is a consequence of a declarative language)
Although fix might only be used in the output statements in the examples (where it's guaranteed to work), it is used in many locations in the MiniZinc libraries. If we for example look at the library that is used for MIP solvers, there are many constraints that can be encoded more efficiently if one of the arguments is a parameter. Therefore, you will often see that the a constraint in this library first tests its arguments with is_fixed, and then use a better encoding if this returns true.
The output statement and when is_fixed returns true will both give the guarantee that a variable is fixed and ensure that the compilation doesn't abort. There is no other way to coerce a variable to a parameter, but unless you are dealing with dependant predicate definitions, you can just trust the MiniZinc compiler to ensure that the resulting FlatZinc will contain a parameter instead of a variable.

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.

matlab function with argument not required

I create a function
function y = getValue(modelName, param, option)
open_system(modelName);
runModel(option);
y = getActiveFun(param);
end
I would like when calling this function to have the choice to pass or not argument option
from some other files I call the function with all arguments and sometimes I would like to call it without passing option argument ?
I would like to call : getValue(modelName, param) from other files
How could I do that ?
The simplest way to do this is to use the nargin variable:
function y = getValue(modelName,param,option)
open_system(modelName);
if (nargin < 3)
# No option passed, do something like
runModel('defaultOption')
else
# Option passed
runModel(option);
end
y = getActiveFun(param);
end
nargin is just the number of input arguments that were actually submitted. Thus, nargin == 3 indicates that the option parameter has been set, nargin < 3 that it has not been set.
Thus, you could now always call your function like
result = getValue('myModel', myParameter)
or with all parameters
result = getValue('myModel', myParameter, someOption)
While solutions with nargin are already given and more or less a standard usage within most MATLAB codebases, I think there is a nicer alternative that is more readable.
With nargin in big functions, you have to remember what argument 3 was exactly. Especially if you have more optional arguments, it becomes cumbersome to keep track or to allow that some optional arguments are passed, while others are not.
The first and easier solution is my personal alternative to nargin, and that is using the exist function:
function [output] = getValue(modelName,param,option, otherOption)
if ~exist('option', 'var') || isempty(option)
option = 'defaultValueForOption';
end
if ~exist('otherOption', 'var') || isempty(otherOption)
otherOption = 'defaultValueForOption';
end
% perform other actions
The advantage is that now all input-related code is at the beginning and it is more verbose as to what should be happening. You won't clutter your other code with that logic. And you can also supplement those if statements with validation of the input and fall back onto the default when an invalid option is given.
The other possibility is standard in later versions of MATLAB: the inputParser class. With this class, you can define even more complicated scenarios of optional parameters and even key-value pairs.
Below is a self-descriptive example I have kept to avoid needing the documentation every time.
%% Usage Example input Parser
%
function output = FuncName(rParam1, rParam2, oParam1, oParam2, varargin)
p = inputParser();
defaultValue = 0;
validatorFunc = #(x)(true); % validator function should return true when x is valid
%% Input Format definition
p.addRequired('rParam1', validatorFunc);
p.addRequired('rParam2', validatorFunc);
p.addOptional('oParam1', defaultValue, validatorFunc);
p.addOptional('oParam2', defaultValue, validatorFunc);
p.addParamValue('kvParam1', defaultValue, validatorFunc);
p.addParamValue('kvParam2', defaultValue, validatorFunc);
p.addParamValue('kvParam3', defaultValue, validatorFunc);
p.addParamValue('kvParam4', defaultValue, validatorFunc)
%% Optional Settings
% expand supplied struct to ParamValue pairs (or other arguments)
p.StructExpand = true; % default: false
%% Parse
p.parse(rParam1, rParam2, oParam1, oParam2, varargin{:})
%% Retrieve results
values = p.Results(); % structure with all values
defaultedArgs = p.UsingDefaults; % cell array of all parameter names using defaults
end
This approach is even more verbose and personally, I don't quite like the fact that one has to redefine for every input whether it is required or optional and that it requires quite a lot of boilerplate code. But at least, it is a solution that is a standard solution and without a doubt to be preferred for larger functions.
Both approaches do suffer from a drawback compared to the nargin way of checking: they are both slower. So if you use these in functions that get called a lot (or only perform a very quick calculaion), it might be more worthwhile to use nargin instead.
For completeness, lets see the basics (see documentation here).
In a function if an argument is not used, it is only a "programming warning", nothing more. So the problem is that you use a parameter that may or may not be provided.
So this is handled using
nargin % the number of parameters provided in current call
nargin(function_name) % the number of parameters the declaration has
So based on these you may program some conditions and include there the code that uses the non-standard input parameters.
For more complex cases varargin is most proper that handles variable length parameter list where the ordering may not be defined. But this is too much for this question
Look at the following link:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/65943
they have several suggestions