#matlab #optional-arguments
#matlab #необязательно-аргументы
Вопрос:
Tl; Dr: Есть ли способ иметь непревзойденные необязательные аргументы имени-значения при проверке аргументов новой функции Matlab (2019b)?
У меня есть существующий код Matlab, который использует анализатор ввода для отправки необязательных аргументов моей sim-карте. Sim настроен таким образом, что вы выбираете несколько функций, которые определяют, как ваш объект ведет себя в своей среде, и вызываете runSim
. В этом воображаемом примере мой sim определяется с помощью двух функций, которые принимают как уникальные, так и общие необязательные входные данные.
runSim('sharedArg', sa, 'func1Arg1', f1a1, 'func1Arg1', f1a2, 'func2Arg1', f2a1)
runSim
вызовет соответствующие функции, которые вы выбрали для определения вашего sim, и передаст эти необязательные аргументы каждой функции. В этом случае анализатор ввода в func1
будет игнорировать func2arg1
, а анализатор ввода в func2
будет игнорировать func1Arg1
и func1Arg2
.
Все работает отлично, но моя sim-карта тратит треть своего времени на синтаксический анализ входных данных, поскольку эти функции вызываются тысячи раз в цикле. И анализатор ввода Matlab имеет документированную историю медленной работы (вставьте ненормативную лексику здесь).
Недавно обновившись до 2020a, я обнаружил проверку аргументов функции, которая намного менее ужасна, чем синтаксические анализаторы ввода. Протестировав его на нескольких из множества функций, код не только стал намного более читаемым, но и я вижу огромный прирост производительности.
function output = func1FirstTry(options)
% This function does some things
arguments
options.sharedArg
options.func1Arg1 double = 1
options.func1Arg2 double = 2
end
output = 2;
end
Нравится. Отлично. Потрясающе. НО…
… новая проверка функции не допускает непревзойденных аргументов (или, по крайней мере, связанная страница не объясняет это, и я не нашел более подробной документации). Раньше func1
нужно было знать только о его необязательных аргументах. Если бы я указал func2arg1
в качестве входных данных func1
, он просто проигнорировал бы это. При проверке новой функции это приведет к ошибке, поскольку я не определил func2Arg1
как разрешенный ввод в блоке аргументов. Поэтому, когда я выполнял этот тест, мне пришлось вместо этого выполнить следующее:
function output = func1SecondTry(options)
% This function does some things
arguments
options.sharedArg
options.func1Arg1 double = 1
options.func1Arg2 double = 2
options.func2Arg1 double = Nan
end
% Rest of the code goes here
end
Теперь это работает, но я также должен изменить func2
, чтобы принять func1
необязательные аргументы. И у меня есть еще 20 функций с необязательными аргументами для рассмотрения, поэтому очевидно, что эта стратегия не сработает. Есть ли способ указать, что я хочу принимать и игнорировать любые неназванные необязательные входные данные таким же образом, как и анализатор ввода? В частности, я хотел func1FirstTry('func2Arg1', 3)
бы не допускать ошибок, не добавляя func2Arg1
к блоку аргументов.
Комментарии:
1. Я бы предложил вообще пропустить проверку, если важна скорость, и передавать аргументы в виде структуры.
args.func1=1; args.func3=NaN;
2. Я должен уточнить, что меня действительно не волнует проверка. Проверка аргумента функции просто является именем функции. Я просто хочу передать необязательные аргументы этим новым способом, что, я думаю, является огромным шагом в правильном направлении для Matlab. Это просто несовместимо с моим существующим кодом без принятия непревзойденных аргументов.
Ответ №1:
В конечном итоге это не было решением, которое я принял, но я думаю, что возможный ответ — определить фиктивный класс со всеми возможными входными данными для анализатора в качестве общедоступных свойств, а затем использовать значения из синтаксиса свойств класса. Таким образом, все свойства этого класса являются законными входными данными для функций, но тогда вы получите доступ только к параметрам, специфичным для этой функции. Этот синтаксис также позволяет переопределять любые конкретные параметры, если вы хотите изменить значения по умолчанию.
% Define this in its own file
classdef OptionalArgumentClass
properties
sharedArg
func1Arg1
func1Arg2
func2Arg1
argumentUndefinedByOtherFunctions
end
end
% In a separate file from class
function output = func1(options)
% This function does some things
arguments
options.?Path.To.OptionalArgumentClass
options.func1Arg1 = 1 % Can choose specific default values here if needed
end
% options.func1Arg2 has no default value, so this will error if unspecified
output = options.func1Arg1 options.func1Arg2;
end
Включение options.?Path.To.OptionalArgumentClass
означает, что я могу указать func2Arg1
или argumentUndefinedByOtherFunctions
и корректно игнорировать их, что было всем, что я искал.