八度,割线法

Octave, The secant method

我正在尝试使用 Octave 实现割线方法,特别是我创建了一个名为 secant("function","x0","x1","tolerance") 的函数。我使用 while 循环来计算函数的根,我认为问题出在循环中。

但是我得到的结果并不是我所期望的。正确答案是 x=0,49438.

我的代码如下:

tol = 10.^(-5); # tolerance
x0 = 0.4; # initial point
x1 = 0.6; # initial point
syms x;
fun = @(x) exp(sin(x)) - 2/(1+x.^2); # f(x) = exp(sin(x)) - 2/(1+x^2)
fprintf("Function f(x)\n");
fun
fprintf("\n");
fprintf("initial points: %f\n",x0,x1);
function[raiz,errel,niter] = secant(fun,x0,x1,tol)      
  niter = 0; # steps number
  errel = [];  # the vector of relative errors
  y0 = fun(x0); # f(x0)
  y1 = fun(x1); # f(x1)
  ra = 0.0; # ra is the variable of the function's root
  while abs(ra-x1)>= tol
    niter += 1;
    ra = x1 - ((x1-x0)./(y1-y0)).*y0; # formula of the secant method
    if abs((ra-x1))<tol
      raiz = ra;
      return;
    endif
    x0 = x1; y0 = y1; x1 = ra;
    y1 = fun(ra);
    errel(niter) = abs(ra-x1)/abs(ra); # Calcule of relative error
  endwhile
  if abs((ra-x1)/ra)<tol
    fprintf ('The method is over\n');
    fprintf ('\n');
  endif
  raiz = ra;
endfunction
[r,er,tot] = secant(fun,x0,x1,tol)

感谢您能给我的帮助

在循环条件中使用正割根没有什么意义。起初它没有定义,在循环内它被转移到下一个割线的支撑点。请注意,最后 rax1 包含相同的值,以错误的方式使循环条件变得微不足道。

接下来,割线有等式

y(x) = y1 + (y1-y0)/(x1-x0)*(x-x_1)

使用此公式检查 y(x0)=y0y(x1)=y1。因此割线根位于

x = x1 - (x1-x0)/(y1-y0)*y1

最后,在任何时候都没有使用符号表达式,将 x 定义为符号变量是多余的。

循环内的中断测试也是多余的,并且会阻止循环后的连贯状态。只需删除它并记住 x1 包含最后一个近似值。

通过所有这些,我得到如下执行日志:

Function f(x)
fun =

@(x) exp (sin (x)) - 2 / (1 + x .^ 2)

initial points: 0.400000
initial points: 0.600000
The method is over

r = 0.494379048216965
er =

   2.182723270633349e-01   3.747373180587413e-03   5.220701832080676e-05   1.899377363987941e-08

tot = 4