将MatLab的fZERO函数(Brent方法)转换为C代码

mo49yndu  于 2022-11-15  发布在  Matlab
关注(0)|答案(2)|浏览(258)

我正试着用C语言写一个类似于MatLab中的函数,叫做fzero,我发现fero使用布伦特方法来求根。

T=fzero(MyFunction,CATHRESHOLD);

这就是我需要的函数,它应该给出CATHRESHOLD附近的MyFunction的零点。
当我尝试实现Brent方法以找到所需的结果时,我发现除了MyFunction之外,我还需要两个输入ab
b被认为是当前对MyFunction根的猜测。a是这样一个点,MyFunction(a)MyFunction(b)具有相反的符号,所以区间[a, b]包含解。
我可以写一个Brent方法的C代码,知道所有的输入,但我不能写一个只知道函数和我称之为CATHRESHOLD的代码。我应该如何选择a的值?!
谁能给我解释一下fzero是如何工作的,也许这会有帮助!

fykwrbwg

fykwrbwg1#

fzero(fun,x0)documentation可以看出,x0应该在*区间[a,b]内,使得f(a)f(b)具有不同的符号。
通过在命令窗口中输入edit fzero,我们可以打开函数本身。通过查看非模糊代码,这可能会帮助您编写自己的版本。在该函数的顶部,我们可以看到说明:

%   X = FZERO(FUN,X0) tries to find a zero of the function FUN near X0, 
%   if X0 is a scalar.  It first finds an interval containing X0 where the 
%   function values of the interval endpoints differ in sign, then searches 
%   that interval for a zero.

所以fzero仍然使用区间[a,b],它只找到标量X0周围的区间。注意:您还可以将间隔传递给fzero,如第二个输入选项所述:

%   X = FZERO(FUN,X0), where X0 is a vector of length 2, assumes X0 is a 
%   finite interval where the sign of FUN(X0(1)) differs from the sign of 
%   FUN(X0(2)). An error occurs if this is not true.

具体地说,请参见函数的开头部分

% Interval input

在这里我们可以看到上面两个输入选项的处理

if (numel(x) == 2) 
    % ...
    a = x(1); savea=a;
    b = x(2); saveb=b;
    % ... 
elseif (numel(x) == 1)
    % ...
    % method for calculating a and b
    % ...
end
pzfprimi

pzfprimi2#

我已经成功地用C语言完成了这项工作,并针对fero进行了测试。最大的帮助来自Mathworks的创始人,也是70年代初布伦特的顾问之一,克利夫·莫勒。
最好的fero引用是用FORTRAN编写的netlib(as stated in this article)。基本上是布伦特1971年的论文(用ALGOR 60写的)中的内容。维基百科上的伪代码不起作用(有一个关于它的警告横幅)-我已经证实了这一点。

相关问题