Обработчики функций Matlab / Octave и наргин

Я пишу программу на Octave, и я столкнулся с проблемой, я реализовал квадратуру Гаусса-Легандра, и я передаю своей функции Гаусса-Легандра несколько аргументов, и я передаю функцию, которая будет интегрирована в куб ячейки, поэтому я могу передать несколько функций в время. У меня есть этот фрагмент кода:

    for weight=1:length(w)
        temp=1; 
        for fun=1:length(c)
            %liczenie iloczynu f(x_i)g(x_i), x_i - pieriwastki wielomianu Legandra
            f=c{fun};
            nargin(func2str(c{fun}))
            if (nargin (func2str(c{fun})) == 1)
                disp('a');
                temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
            else
                    (b-a)/2 * x(weight) + (a+b)/2;  
                temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
            end
        end
        %mnozenie wyniku przez odpowiedni wspolczynnik - wage
        temp*=w(weight);
        result+=temp;
    end

В массиве ячеек есть обработчики функций для функций, которые я хочу интегрировать. В зависимости от количества аргументов, которые принимает функция, я хочу использовать два разных вызова функции. Если в массиве ячеек есть обработчик функции, которая записана в файле .m в том же каталоге, что и мой рабочий каталог Octave, все работает нормально, но когда я определяю функцию во время выполнения Octave, например:

    function result=a(x)
    result=x*x
    end

Тип

    c{1}=@a

и передайте этот массив ячеек моей функции Kwadratury, есть ошибка nargin

    error: nargin: invalid function
    error: called from:

Почему это так и как я могу это решить, поэтому я могу определять функцию не только в файлах .m, но и в Octave.


person Andna    schedule 20.11.2011    source источник


Ответы (1)


Я подозреваю, что у меня есть решение, но поскольку это зависит от Octave, и я в основном привык к MATLAB, ваш пробег может отличаться.

Вы вызываете функцию nargin, передавая строковый аргумент, это означает, что nargin должен будет разрешить эту функцию и проверить количество аргументов. Когда вы объявляете встроенную функцию, эта функция определяется в этой области (т. Е. В вашей базовой области), поэтому разрешение имени функции не будет работать изнутри какой-либо функции (или оно может преобразоваться во встроенную функцию, которая даже худшее поведение).

Лучшее решение - использовать nargin(c{fun}) вместо nargin(func2str(c{fun})). Таким образом, вы передаете фактический дескриптор функции, и нет необходимости преобразовывать имя функции в фактическую функцию, и, следовательно, нет возможной двусмысленности.

В общем, я рекомендую не использовать строки для передачи функций: именно поэтому дескрипторы функций включены в MATLAB, поэтому любой, кто читает ваш код (или инструмент статического анализа кода), сможет понять, что вы работаете с функциями. При использовании строк все становится неоднозначным: относится ли строка 'a' к функции a или к первой букве алфавита?

Что касается использования встроенных функций, я не знаю, поддерживает ли это Octave, но если ваша функция довольно проста, проще определить анонимную функцию, такую ​​как ваш пример, с помощью a = @(x)(x*x);. Эта конструкция поддерживается MATLAB, поэтому ваш код становится более переносимым в другие среды (ну, вам все равно нужно заменить X *= A на X = X * A;, чтобы быть совместимым с MATLAB).

edit: Другой вариант - просто проверить, работает ли форма с несколькими параметрами, и при необходимости вернуться к форме с одним параметром:

try
   (b-a)/2 * x(weight) + (a+b)/2;  
   temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
catch ME
   try
       disp('a');
       temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
   catch ME
   end
end

Возможно, вы захотите проверить, действительно ли в возвращенной ошибке ME указано, что для разрешения других ошибок используется неправильное количество аргументов. Я признаю, что это уродливый обходной путь, но поскольку Octave, по-видимому, не поддерживает дескрипторы функций для nargin, это может быть единственный способ получить то, что вы хотите для встроенных функций.

person Egon    schedule 20.11.2011
comment
Я начал использовать func2str, потому что в Octave nargin принимает только строку, но в любом случае я решил свою проблему, сделав свою ячейку также с другими параметрами, поэтому, когда я знаю, что моя функция принимает 3 переменных, я просто получаю их из c {fun, 2} и другие, и я поместил все функции в отдельные файлы, чтобы не беспокоиться об объемах. - person Andna; 21.11.2011
comment
Как я уже сказал, я решил свою проблему, поместив каждую функцию в отдельный файл, эти встроенные функции были необходимы для ускорения моего тестирования моего собственного кода, но я обошелся без «но», но спасибо за вашу помощь :). - person Andna; 22.11.2011