我需要帮助克服牛顿算法中的错误

时间:2011-12-21 22:07:42

标签: algorithm

我的名字是柯蒂斯,我是日内瓦大学生物化学专业的一年级学生。我需要一些帮助来完成我的牛顿算法的代码。这是我们秋季学期数学考试的一个额外练习,我们可以把它交给或不。通常人们会复制并粘贴,但我决定坐下来审查理论,并向右和中心寻求帮助。相信我,我在过去3周(初学者)一直在这个任务中慢慢积累我的技能,但我已达到极限。

这是我的代码:

主要功能

f=function(x){ out=(2/(3))*exp(x^3)-(10)*log(x) return(out) }

1ST DERIVATIVE

fp=function(x){ out=(2)*(x^2)*exp(x^3)-(10/x) return(out) }

2ND DERIVATIVE

fpp=function(x){ out=(4)*(x)*exp(x^3)+(6)*(x^4)*exp(x^3)+(10/x^2) return(out) }

我试图用我的牛顿算法找到“fp”的“零”,我的第一个衍生物:

NEWTON ALGORITHM

newbon=function(x0,epsi,f,fp){

## where "a" corresponds to x^n and

## "b" corresponds to x^n+1

## We are looking for x^n+1 such that f(x^n+1)=0

## NB: fp(a)*(a-b)=f(b)-f(a) when f(b)=0 

  a=x0
  b=(fp(a)*a-f(a))/fp(a)
while(abs(-fp(a)*(b-a))>epsi){
  a=b
  b=(fp(a)*a-f(a))/fp(a)
} 
  out=NULL 
  out=a
return(out)
}

我必须承认我的算法非常拥挤,而且我一直很难让它运行起来。但是,我总是收到相同的错误消息:

错误消息

Erreur dans while (abs(-fp(a) * (b - a)) > epsi) { : 
  valeur manquante là où TRUE / FALSE est requis
De plus : Message d'avis :
In log(x) : production de NaN

请原谅法国人;这是我的学习语言。坦率地说,如果我没有获得奖励分数,我不介意,真正重要的是我理解为什么它不起作用以及缺少什么条件。

对你的帮助将不胜感激。

Curtis MOYO

1 个答案:

答案 0 :(得分:1)

log正在返回NaN,所以我猜你在某处以某种方式给它带来负值。

所以我可以从中收集到的是fp是一个包含日志的函数,很可能function(x){ out=(2/(3))*exp(x^3)-(10)*log(x) return(out) }
并且它正在被一个负面的论点,即返回NaN。这不能与epsi进行比较,因此不会向循环condiditon返回布尔值。

b=(fp(a)*a-f(a))/fp(a)调用f的情况下,也可能更早地生成此NaN,因为那是应该包含log的那个,并且它导致上述问题相反。

有了更多信息以及你的x0,epsi,f,fp参数是什么,我可以在Matlab中尝试(或者可能在你使用的任何地方)


请记住,实现牛顿方法的标准方法就是

while (abs(f(x)) > TOL)
  x = x - f(x)/fp(x);

找到f的根


以下是我自己用于作业的内容:

%x0 is a guess, a,b are bounds, f is the function, g is the derivative, TOL is epsi
function [x, flag] = SafeNewton1D(f, g, x0, a, b, TOL)
x = x0;
  while (abs(f(x)) > TOL)
    x = x - f(x)/g(x);
    if (x < a || b < x)
       %value does not fall between a and b, shorten bounds and then guess
       %again from the midpoint.
       midpoint = a + (b - a)/2;
       if (sign(f(a)) == sign(f(midpoint)))
           a = midpoint;
       else
           b = midpoint;
       end
       x = a + (b - a)/2;
    else
        %value falls between a and b, so may as well shorten the bounds.
       if (sign(f(x)) ==  sign(f(a)))
           a = x; 
       else
           b = x;
       end

    end

  end
end