2017-01-25 3 views
2

Мой вопрос: С помощью дескриптора функции обрабатывает ли строка Matlab каждый раз, когда ей нужно ее оценить, или только один раз, а затем он кэширует ее?Matlab синтаксический анализ во время выполнения функциональных дескрипторов

Пример

Рассмотрим гениального функцию

function [] = foo(func) 
for j=1:1e4 
    func(j); 
end 

и сценарий

func1 = @(x) 5*abs(x)^2 
function foo(func1); 

во время выполнения, Matlab необходимо интерпретировать @(x) 5*abs(x)^2 как функцию. В этом примере он делает это один раз или тысячу раз?

ответ

6

Прежде всего @(x)cos(x) не является строкой, это anonymous function declaration. Когда вы создаете анонимную функцию, MATLAB по существу создает объект функции, который содержит всю необходимую ему информацию. Затем эта анонимная функция может быть передана различным функциям или даже сохранена в файле. Таким образом, он строится только один раз и оценивается много раз.

При оценке MATLAB не выполняет кеширование, поэтому много раз вызывает одну и ту же анонимную функцию с одними и теми же входами, из-за чего содержимое анонимной функции оценивается каждый раз.

Если вы хотите получить более подробную информацию о вашей анонимной функции, в том числе локальной рабочей функции, вы можете использовать functions функцию

f = @(x)cos(x); 

functions(f) 

%   function: '@(x)cos(x)' 
%    type: 'anonymous' 
%    file: '' 
%   workspace: {[1x1 struct]} 
% within_file_path: '__base_function' 

Это, как говорится, в вашем примере, это может действительно сводятся к function handle, а не анонимной функции, так как вы передаете все входные аргументы напрямую на cos, не изменяя их. Как вы можете видеть, у этого есть другое внутреннее представление и из некоторых предварительных тестов, это кажется немного более быстрым.

f = @cos 

functions(f) 

% function: 'cos' 
%  type: 'simple' 
%  file: '' 

И быстрый эталонные

function benchit 
    fprintf('Anonymous function: %0.4f\n', timeit(@option1)); 
    fprintf('Function handle: %0.4f\n', timeit(@option2)); 
end 

function option2() 
    f = @(x)cos(x); 
    for k = 1:10000 
     f(k); 
    end 
end 

function option1() 
    f = @cos; 
    for k = 1:10000 
     f(k); 
    end 
end 

И результаты (на самом деле не огромная разница)

Anonymous function: 0.0056 
Function handle: 0.0049 

несколько вещей

  • При создании анонимной функции объявление анонимной функции должно по-прежнему придерживаться всех стандартных правил синтаксиса MATLAB, иначе оно не будет создано. Например, следующий будет выдавать ошибку при анонимной функции создания, поскольку он является недействительным синтаксис

    func = @(x)thing] 
    

    Error: Unbalanced or unexpected parenthesis or bracket.

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

    func = @(x) x + [1 2]; 
    
    func([3 4]) 
    % 4 6 
    
    % Now we're going to pass an array that isn't 1 x 2 
    func([5 6 7]) 
    

    Matrix dimensions must agree.
    Error in @(x)x+[1,2]

+2

'functions' документирована: [https://www.mathworks.com/help/matlab/ref/functions.html](https://www.mathworks.com/ help/matlab/ref/functions.html) - однако он рекомендуется только для отладки. – horchler

+0

@horchler Welp, не знаю, почему я так думал. Обновлено. Благодарю. – Suever

+0

@Suever спасибо. Пара последующих действий. (a) Я вижу, почему косинус - плохой пример, я дам тот, который действительно требует анонимной функции. (b) Много раз анонимная функция создается, но только когда вы пытаетесь ее оценить или выполнить, она выдает исключение, которое является недопустимым. Попробуйте определить 'func2 = (x) dfadf9x)'. Итак, какую функцию он хранит для 'func2'? –