I have a MATLAB file containing one top-level function called sandbox. This function, in turn, contains two nested functions, mysumand myprodwhich are identical in functionality and what parameters they allow, except that one uses @suminternally and the other uses @prodinternally. My goal is to create a wrapper function for use in both mysum, and in myprod, which will take care of all the checks and input syntax. This function is called applyFunc.
Here, where it gets complicated. mysumand myprodhave two forms:
mysum(v)returns sum(v, 1).mysum(v, 'imag') returns sum(v, 1) + 1i
Any other input combinations should cause an error.
I'm having trouble using inputParserthese various input combinations to parse, in particular optional string input. Here is the code:
function sandbox()
%% Data
v = [1 4; 3 3];
%% Calculations
s = mysum(v);
si = mysum(v, 'imag');
p = myprod(v);
pi = myprod(v, 'imag');
%% Accuracy tests
assert(isequal(s, [4 7]))
assert(isequal(si, [4+1i 7+1i]))
assert(isequal(p, [3 12]))
assert(isequal(pi, [3+1i 12+1i]))
function x = mysum(varargin)
x = applyFunc(@sum, varargin{:});
end
function x = myprod(varargin)
x = applyFunc(@prod, varargin{:});
end
end
function x = applyFunc(func, varargin)
p = inputParser();
p.addRequired('func', @(x) validateattributes(x, {'function_handle'}, {'scalar'}));
p.addRequired('v', @(x) validateattributes(x, {'double'}, {}, 'applyFunc:msg', 'v'));
p.addOptional('imag', '', @(x) validatestring(x, {'imag', ''})); % THIS LINE IS THE PROBLEM
p.parse(func, varargin{:});
f = p.Results.func;
v = p.Results.v;
strflag = p.Results.imag;
x = f(v);
if ~isempty(strflag)
validatestring(strflag, {'imag'});
x = x + 1i;
end
end
The line causing the problem is this (as indicated in the code above):
p.addOptional('imag', '', @(x) validatestring(x, {'imag', ''}));
The documentation for inputParser states that:
For optional string entries, specify a validation function. Without a validation function, the input parser interprets valid string inputs as invalid parameter names and throws an error.
Unfortunately, I do not know how to do this. Is there something simple? If the argument 'imag'is not passed at all (as in assignment sand p), the code works fine, but if I pass it, I get this error:
Error using sandbox>applyFunc (line 32)
The value of 'imag' is invalid. It must satisfy the function:
@(x)validatestring(x,{'imag',''}).
Error in sandbox/mysum (line 18)
x = applyFunc(@sum, varargin{:});
Error in sandbox (line 7)
si = mysum(v, 'imag');
Any help?