牛顿收敛法不起作用
Newton convergence method not working
我正在尝试使用 Newton-Raphson 方法逼近多项式的根。我为此编写的代码如下所示:
#include <stdio.h>
#include <math.h>
int main (){
double c, nq, nnq, nnnq, v, h, q, o;
o=2;
c=-0.55;
nq=-0.04625;
nnq=-0.55;
nnnq=1;
while(fabs(c-v) > 0.000001)
{
nq=((2*(o-1)+1)*(c)*(nnq)-(o-1)*nnnq)/((o-1)+1);
q=(-o*c*nq+o*nnq)/(1-(c*c));
h=(c-(nq/q));
printf("The better root is %.15lf\n",h);
v=c;
c=h;
}
}
我知道没有必要写变量 o、c、nq 等,因为我可以使用它们的确切值。这是一个更大问题的一部分,我需要那些变量,所以请忽略它。
这个程序输出这个:
The better root is -0.578030303030303
The better root is -0.591696792857493
The better root is -0.598609887802599
The better root is -0.602171714355970
The better root is -0.604024260228500
The better root is -0.604992519745332
The better root is -0.605499890229896
The better root is -0.605766110042157
The better root is -0.605905895095070
The better root is -0.605979319651017
The better root is -0.606017894664121
The better root is -0.606038162857992
The better root is -0.606048812800124
The better root is -0.606054408979837
The better root is -0.606057349623975
The better root is -0.606058894866533
The better root is -0.606059706860161
相反,它应该收敛到点 -0.57735026918963。我知道 Newton-Raphson 肯定会收敛,所以错误应该在代码上。我还尝试使用 printf 定位问题,我认为问题出现在第二次迭代中。我认为程序无法正确计算 nq 但我不知道为什么。
这是方程的牛顿法(这是一个快速代码,不要检查变量名):
#include <stdio.h>
#include <math.h>
int main ()
{
double s = 2.0, fx = 0, dfx = 0, p = 0;
while(fabs(s - p) > 0.000001)
{
fx = 0.5 * (3 * s * s - 1);
dfx = 3 * s;
p = s;
s = s - (fx / dfx);
printf("The better root is %.15lf\n", s);
}
return 0;
}
收敛到0.577350269189626
。您的问题是您试图同时计算 2 个递归。顺便说一句,在你的问题中你说你想要计算 "root of a polynomial"。我没有完全明白你的意思。如果从根开始你的意思是方程的平方根,你需要更新此代码并相应地更改 fx
和 dfx
。
而不是仅仅计算 x = sqrt(1.0/3)
,您想要将 Legendre 多项式的递归计算合并到 o
阶,可能是为了稍后将该方法扩展到 o
更大的值比2.迭代是
P(0,c) = 1; P(1,c) = c;
(n+1)*P(n+1,c) = (2*n+1)*c*P(n,c) - n*P(n-1,c), n=1, ... , o-1
导数可以计算为
(1-c^2)*P'(o,c) = -n*c*P(o,x) + n*P(o-1,c).
您需要将此迭代包含在牛顿循环内,在理想情况下,使用 Legendre 多项式的对象以及值和导数的方法。我已经修改了您的结构以在 JavaScript:
中工作
var my_div = document.getElementById("my_div");
var c = -0.55;
var v = -20;
var o = 2;
while( Math.abs(v-c) > 1e-12 ) {
p0 = 1;
p1 = c;
for(n=1; n<o; n++) {
// p0, p1, p2 stand for P(n-1,c), P(n,c), P(n+1,c)
p2 = ((2*n+1)*c*p1 - n*p0) / (n+1)
p0 = p1; p1 = p2;
}
// p0, p1 now contain p(o-1,x), p(o,x)
p1prime = ( -o*c*p1 + o*p0) / (1-c*c);
h = c - p1/p1prime;
my_div.innerHTML += "<p>The better root is "+h+"</p>";
v = c; c = h;
}
<div id="my_div"></div>
我正在尝试使用 Newton-Raphson 方法逼近多项式的根。我为此编写的代码如下所示:
#include <stdio.h>
#include <math.h>
int main (){
double c, nq, nnq, nnnq, v, h, q, o;
o=2;
c=-0.55;
nq=-0.04625;
nnq=-0.55;
nnnq=1;
while(fabs(c-v) > 0.000001)
{
nq=((2*(o-1)+1)*(c)*(nnq)-(o-1)*nnnq)/((o-1)+1);
q=(-o*c*nq+o*nnq)/(1-(c*c));
h=(c-(nq/q));
printf("The better root is %.15lf\n",h);
v=c;
c=h;
}
}
我知道没有必要写变量 o、c、nq 等,因为我可以使用它们的确切值。这是一个更大问题的一部分,我需要那些变量,所以请忽略它。
这个程序输出这个:
The better root is -0.578030303030303
The better root is -0.591696792857493
The better root is -0.598609887802599
The better root is -0.602171714355970
The better root is -0.604024260228500
The better root is -0.604992519745332
The better root is -0.605499890229896
The better root is -0.605766110042157
The better root is -0.605905895095070
The better root is -0.605979319651017
The better root is -0.606017894664121
The better root is -0.606038162857992
The better root is -0.606048812800124
The better root is -0.606054408979837
The better root is -0.606057349623975
The better root is -0.606058894866533
The better root is -0.606059706860161
相反,它应该收敛到点 -0.57735026918963。我知道 Newton-Raphson 肯定会收敛,所以错误应该在代码上。我还尝试使用 printf 定位问题,我认为问题出现在第二次迭代中。我认为程序无法正确计算 nq 但我不知道为什么。
这是方程的牛顿法(这是一个快速代码,不要检查变量名):
#include <stdio.h>
#include <math.h>
int main ()
{
double s = 2.0, fx = 0, dfx = 0, p = 0;
while(fabs(s - p) > 0.000001)
{
fx = 0.5 * (3 * s * s - 1);
dfx = 3 * s;
p = s;
s = s - (fx / dfx);
printf("The better root is %.15lf\n", s);
}
return 0;
}
收敛到0.577350269189626
。您的问题是您试图同时计算 2 个递归。顺便说一句,在你的问题中你说你想要计算 "root of a polynomial"。我没有完全明白你的意思。如果从根开始你的意思是方程的平方根,你需要更新此代码并相应地更改 fx
和 dfx
。
而不是仅仅计算 x = sqrt(1.0/3)
,您想要将 Legendre 多项式的递归计算合并到 o
阶,可能是为了稍后将该方法扩展到 o
更大的值比2.迭代是
P(0,c) = 1; P(1,c) = c;
(n+1)*P(n+1,c) = (2*n+1)*c*P(n,c) - n*P(n-1,c), n=1, ... , o-1
导数可以计算为
(1-c^2)*P'(o,c) = -n*c*P(o,x) + n*P(o-1,c).
您需要将此迭代包含在牛顿循环内,在理想情况下,使用 Legendre 多项式的对象以及值和导数的方法。我已经修改了您的结构以在 JavaScript:
中工作var my_div = document.getElementById("my_div");
var c = -0.55;
var v = -20;
var o = 2;
while( Math.abs(v-c) > 1e-12 ) {
p0 = 1;
p1 = c;
for(n=1; n<o; n++) {
// p0, p1, p2 stand for P(n-1,c), P(n,c), P(n+1,c)
p2 = ((2*n+1)*c*p1 - n*p0) / (n+1)
p0 = p1; p1 = p2;
}
// p0, p1 now contain p(o-1,x), p(o,x)
p1prime = ( -o*c*p1 + o*p0) / (1-c*c);
h = c - p1/p1prime;
my_div.innerHTML += "<p>The better root is "+h+"</p>";
v = c; c = h;
}
<div id="my_div"></div>