合并MATLAB中的函数句柄

5

我目前正在用MATLAB编写模拟程序,需要在一个问题上寻求帮助。

我正在解决一个问题,其中我有n个单独的匿名函数句柄fi存储在单元数组中,每个函数都接受一个1×1数值数组xi并返回一个1×1数值数组yi

我试图将这些匿名函数句柄合并为一个单一的匿名函数句柄,该函数接受单个n×1数值数组X并返回单个n×1数值数组Y,其中XY的第i个元素分别为xiyi=fi (xi)。

例如,让n = 2,f_1f_2是两个输入和输出1×1数组的函数句柄,并存储在名为functions的单元数组中:

f_1 = @(x_1) x_1^2 
f_2 = @(x_2) x_2^3
functions = {f_1, f_2}

在这个例子中,我需要使用f_1f_2构建一个函数句柄F,用于输入和输出一个2×1的数值数组,具体如下:
F = @(x) [f_1(x(1,1)); f_2(x(2,1))]

问题是如何将此推广到任意数量的这些函数(n为任意整数)。

3个回答

5

使用内联@()匿名语法定义此类函数很困难(因为函数的主体必须是表达式)。

然而,可以定义一个常规函数,该函数在给定向量的项目上运行并将给定单元格数组中的函数应用于这些项目:

function y = apply_funcs(f, x)
    assert(length(f) == length(x));
    y = x;
    for i = 1 : length(f)
        y(i) = feval(f{i}, x(i));
    end
end

如果需要将此函数作为参数传递给另一个函数,只需通过获取其@句柄来引用它:

F = @apply_funcs

谢谢你!我需要代码尽可能高效,所以我可能会使用你的函数并删除长度/断言参数...另外,你是否知道feval比使用内联函数句柄评估更快?也就是说,y(i) = f{i}(x(i))是否比y(i) = feval(f{i},x(i))更快? - Berk U.

2
这可以通过使用我提供给类似先前问题的解决方案来解决,尽管在输入参数格式化方面会有一些差异。你可以使用CELLFUNFEVAL函数在一行中评估匿名函数并使用NUM2CELL函数将你的输入向量转换为单元数组以供CELLFUN使用,从而实现你想要的效果:
f_1 = @(x_1) x_1^2;     %# First anonymous function
f_2 = @(x_2) x_2^3;     %# Second anonymous function
fcnArray = {f_1; f_2};  %# Cell array of function handles
F = @(x) cellfun(@feval,fcnArray(:),num2cell(x(:)));

请注意,我使用了名称fcnArray来表示函数句柄的单元数组,因为内置函数FUNCTIONS已经使用了名称functions。如果fcnArray和输入参数x不是列向量,则使用冒号运算符(:)将它们转换为列向量。这可以确保输出是列向量。
以下是一些测试用例:
>> F([2;2])

ans =

     4
     8

>> F([1;3])

ans =

     1
    27

再次感谢您。您的方式确实更为简洁,不过我在想它是否比ib所描述的for循环更快? - Berk U.
我会尝试两种方法并比较哪种更好- 你知道有什么资源可以说明最佳的MATLAB实践吗?我总是试图使我的代码尽可能高效,尽管因为MATLAB内置函数经常有3-4种方法来完成这些事情,所以我很难弄清楚什么是昂贵的,什么是不昂贵的。 - Berk U.

1
#you can try 
f=@(x)[x(1)^2;x(2)^3]
>>f([1,2])
ans =
     1
     8
>>f([2,3])
ans =
     4
    27

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接