У меня есть файл MATLAB, содержащий одну функцию верхнего уровня, называемую sandbox
. Эта функция, в свою очередь, содержит две вложенные функции: mysum
и myprod
, которые идентичны по функциональности и какие параметры они позволяют, за исключением того, что один использует @sum
внутренне, а другой использует @prod
внутри. Моя цель - создать функцию обертки для использования как в mysum
, так и в myprod
, которая выполняет все проверки и синтаксический анализ ввода. Эта функция называется applyFunc
.Как использовать входной парсер MATLAB с дополнительными строковыми вводами? В документации говорится: «используйте функцию проверки», но неясно, как это сделать
Вот где это сложно. mysum
и myprod
в двух формах:
mysum(v)
возвращаетсяsum(v, 1)
.mysum(v, 'imag')
sum(v, 1) + 1i
возвращает
Любые другие комбинации входных должны выдавать ошибку.
У меня возникли проблемы с использованием inputParser
для синтаксического анализа этих различных комбинаций ввода, в частности, необязательного ввода строки. Вот код:
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
Линия, которая вызывает проблемы в этом один (как отмечено в коде выше):
p.addOptional('imag', '', @(x) validatestring(x, {'imag', ''}));
Документация inputParser говорит, что:
For optional string inputs, specify a validation function. Without a validation function, the input parser interprets valid string inputs as invalid parameter names and throws an error.
К сожалению, я не знаю, как это сделать. Есть ли что-то простенькое? Если 'imag'
аргумент не передается вообще (как в назначении s
и p
), код работает отлично, но если я передать его, я получаю эту ошибку:
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');
Любая помощь?
+1 использование 'strcmp' решает проблему. Лично мне не нравятся «необязательные аргументы», я бы предпочел использовать аргумент параметра name-value: 'p.addParameter ('imag', false, @ (x) validateattributes (x, {'logical'}, {' скалярное '})) '. Тогда 'p.Result.imag' будет либо true, либо false. – Amro
Это хороший способ очистить сравнение позже и в коде. Это может быть аргумент param-value с логическим значением. – chappjc
@chappjc Спасибо за помощь. Мне действительно нравится использовать пару имя-значение вместо необязательного аргумента, поэтому я, вероятно, буду использовать это для нового кода. К сожалению, код Im, работающий на данный момент, является устаревшим материалом для API, который не может быть изменен. –