【问题标题】:Matlab: Convert function handle to string preserve parametersMatlab:将函数句柄转换为字符串保留参数
【发布时间】:2015-07-14 17:19:49
【问题描述】:

如果您使用 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 的帮助下)针对对齐过程的一些自定义函数进行拟合。我现在想存储所有数据以供将来分析。

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

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

【问题讨论】:

  • 这并不完全正确。它与匿名函数一起存储,然后在将其转换为字符串时丢失。您可以清除 y 并仍然调用匿名函数。
  • @Kim 哎呀,你是对的。正在删除...

标签: matlab anonymous-function


【解决方案1】:

问题源于 Matlab 将 y 的值存储在匿名函数的本地工作区中,同时将符号 y 保留在函数定义的一部分中。 然后,正如您所指出的,func2str 函数转换定义而不用其值替换符号。 由于您的示例表明即使在从当前工作区中清除变量 y(值和符号)之后,您也希望函数句柄能够工作,所以我建议两条路径前进。

首先是使用y 的值创建带有str2func 的函数句柄,而不是让匿名函数持有它:

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 变体。

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

【讨论】:

  • 感谢您的回答。我实际上是想避免使用strrepregex,因为我想给用户提供用户定义函数的可能性(当然不链接到文件(matlab 内置函数很好))。因此,我无法确定内部结构,恐怕我会替换太多,但也许用一个非常聪明的正则表达式可以做到这一点。如果其他人提出其他解决方案,我会再等一会儿。再次感谢您抽出宝贵时间。
  • 您能否再解释一下该用例,并可能在您的问题中提供一个额外的示例?我认为你的问题的答案很大程度上取决于你到底想做什么。
猜你喜欢
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多