Допускает ли новая проверка аргументов функции Matlab непревзойденные аргументы имени-значения?

#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 и корректно игнорировать их, что было всем, что я искал.