Matlab:将函数句柄转换为字符串保留参数

时间:2015-07-14 17:19:49

标签: matlab anonymous-function

如果将函数句柄转换为字符串并使用func2str和str2func函数再次返回,则创建时最初存储在函数句柄中的任何变量及其值都将丢失。

有没有办法克服这个问题?

y = 1;
fun = @(x) x + y
fun_str = func2str(fun);

clear y

fun = eval(fun_str);
result = fun(12); % This doesn't work

具体我有一个测量方法,创建一些数据,然后在fminsearch的帮助下拟合对齐过程的某些自定义函数。我现在想存储所有数据以供将来分析。

由于Data通常比代码存活的时间更长,所以我想让它独立于任何源文件。这就是我将函数句柄转换为字符串的原因。在字符串中,只允许调用matlab builtin个函数。

现在我可以做的当然是在示例中存储y。但我想知道是否有一个更优雅的解决方案,我不需要这样做。

1 个答案:

答案 0 :(得分:1)

问题源于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变体才能使该方法起作用。

第二种方法也仅适用于示例中的简单变量存储。 嵌套的句柄和闭包等将需要更复杂的算法来确定符号值并可能替换。