Проблема связана с тем, что Matlab сохраняет значение y
в рабочем пространстве, локальном для анонимной функции, сохраняя при этом символ функции y
. Затем, как вы указали, функция func2str
преобразует определение без замены символа на его значение. Поскольку ваш пример указывает, что вы хотите, чтобы функциональный дескриптор работал даже после очистки переменной y
(оба значения и символа) из текущего рабочего пространства, я бы предложил два пути вперед.
Первый заключается в создании функции ручки с str2func
используя значение y
вместо того, чтобы позволить анонимные функции держать его:
fun = str2func(['@(x) x + ',num2str(y)]);
Другой написать вариант func2str
, что делает замену значения после преобразование функции в строку. Функция functions
может использоваться для получения рабочей области анонимной функции, а некоторые регулярные выражения могут использоваться для замены символов литералами. Вот минимальный рабочий пример:
function str = func2strrep(fun)
% Grab workspace information
info = functions(fun);
workspace = info.workspace{1};
symbols = fieldnames(workspace);
% Initialize string
str = func2str(fun);
% Replace workspace variables with numeric literals
if not(isempty(symbols))
seps = '[\s\+\-\*\/\\\^\:\=\>\<]';
expr = @(s) ['(',seps,'{1})',s,'(',seps,'{1})'];
for k = 1:numel(symbols)
symbol = symbols{k};
value = num2str(workspace.(symbol));
% Check end of string
str = regexprep(str,['(',seps,'{1})',symbol,'$'],['$1',value]);
% Check bulk
stro = regexprep(str,expr(symbol),['$1',value,'$2']);
%
% Put in loop for repeated replacement since
% 'all' is not working as I thought it would.
while not(strcmp(stro,str))
str = stro;
stro = regexprep(str,expr(symbol),['$1',value,'$2']);
end
end
end
end
Я не настолько талантлив с регулярными выражениями, поэтому метод замены может потребоваться некоторые настройки (особенно с regexprep
не заменит то, что я думал, будет все матчи за повторен символы). Однако это первый идти производит
>> y = 1;
>> z = 2;
>> yy = 3;
>> f = @(x) x + y + y + z + yy;
>> func2strrep(f)
ans =
@(x)x+1+1+2+3
Оба подхода опираются на num2str
и, следовательно, хороши только для скалярных значений. Для векторных значений для работы метода необходим вариант num2str
, который создает допустимый литерал массива в строковой форме.
Второй подход также работает только для простого хранения переменных, как в примере. Вложенные ручки и затворы и подобные им потребуют более сложный алгоритм определения значения символа и, возможно, замены.
Это не совсем так. Он хранится с анонимной функцией, а затем теряется при преобразовании в строку. Вы можете очистить y и по-прежнему вызывать анонимную функцию. – Kim
@ Ким, вы правы. Удаление ... – excaza