MATLAB中N个函数句柄的求和

3

我在MATLAB中有 N 个函数,我可以使用 strcatnum2streval 在for循环中定义它们。因此,无需手动定义,我就能够定义 N 个函数。假设 N=4,并给出如下:

f1=@(x) a1*x+1;
f2=@(x) a2*x+1;
f3=@(x) a3*x+1;
f4=@(x) a4*x+1;

现在我添加了这四个功能,可以手动执行以下操作:
f=@(x)(f1(x)+f2(x)+f3(x)+f4(x));

因为我知道 N=4 ,所以我可以手动完成。然而,通常情况下我不知道会有多少个函数。对于所有情况,我不能编写新函数。

有没有自动完成这个的方法?我的意思是,如果我给出 N=6 ,我希望看到 MATLAB 给我这个:

f=@(x)(f1(x)+f2(x)+f3(x)+f4(x)+f5(x)+f6(x));

每当我提供N=2时,就必须有如下定义的函数f:
f=@(x)(f1(x)+f2(x));

我们应该如何做到这一点?


使用循环?毕竟不是所有东西都必须是匿名函数。 - Cris Luengo
@CrisLuengo 我同意使用循环,但是怎么做呢?我不会。 - Seyhmus Güngören
1个回答

2
首先,你应该阅读这篇答案,其中列举了避免使用eval的一系列理由。在大多数情况下,除了极少数必须使用eval的场合外,其余情况下它只会让事情变得更加复杂。在这种情况下,你使用动态生成变量名的方式,这被认为是一种非常糟糕的做法。正如链接答案和那个答案中进一步阐述的那样,动态变量名使代码更难以阅读、维护,并且在MATLAB中执行速度更慢。
因此,你不需要定义函数f1f2f3,而是定义函数f{1}f{2}f{3},依此类推。也就是说,f是一个单元数组,其中每个元素都是匿名函数(或任何其他函数句柄)。
例如,不要写成:
f1=@(x) a1*x+1;
f2=@(x) a2*x+1;
f3=@(x) a3*x+1;
f4=@(x) a4*x+1;

you do

N = 4;
a = [4.5, 3.4, 7.1, 2.1];
f = cell(N,1);
for ii=1:N
   f{ii} = @(x) a(ii) * x + 1;
end

通过这些变化,我们可以轻松回答这个问题。现在我们可以编写一个函数,输出f中所有函数的总和:

function y = sum_of_functions(f,x)
   y = 0;
   for ii=1:numel(f)
      y = y + f{ii}(x);
   end
end

你可以将这段代码放在一个名为sum_of_functions.m的文件中,或者将其放在你的函数文件或脚本文件的末尾,都没有关系。现在,在你的代码中,当你想要求解y = f1(x) + f2(x) + f3(x)...时,你需要写成y = sum_of_functions(f,x)

我刚刚将我的代码更改为单元格结构,但我仍然遇到同样的问题。根据您的答案,我能够评估N个函数的总和,但我无法获得它们。为什么我需要它呢?因为有一个名为FindRoots(fun,parameters)的函数必须调用。这里fun是N个函数的总和。这就是为什么我不能简单地评估N个函数的总和并感到满意。我必须将其发送到另一个函数中,而另一个函数不是由我编写的。在这里该怎么办? - Seyhmus Güngören
@SeyhmusGüngören:你可以使用@sum_of_functions来获取函数的句柄。这就是你将作为参数传递给FindRoots函数的内容。 - Cris Luengo
我本来可以的,但是现在不行了。因为你的函数有两个输入:f 和 x,但是 FindRoots 只接受一个带有单个参数 x 的函数句柄。 - Seyhmus Güngören
啊,抱歉,是的。那么请使用@(x) sum_of_functions(f,x)。在编写时必须定义f,并将其嵌入匿名函数中。@SeyhmusGüngören - Cris Luengo
我有一种感觉,这可能比eval更好,但似乎不够高效。因为对于x的每次评估,都需要求和N个函数。复杂度是通常情况下的N倍。通常,可以进行一次N次计算,然后对于求和函数的每次评估,只需要进行1次计算而不是N次。 - Seyhmus Güngören
我刚刚问了另一个问题...似乎我的新问题中的分母使得使用您提供的代码出现了很多问题。 - Seyhmus Güngören

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