证明存在这样的a,如果|x-e|<a方法收敛
牛顿法在近似解接近正确解时起作用。
当候选解发散或振荡时,牛顿法会失败。
添加发散测试(例如:a 变为非数字或无穷大)和循环迭代限制。
使用二分搜索找到a 的上限:在近似解 (a = e) 和发散点 (a = e + 100) 之间。见下文。
重复(对a_min, a_max 角色和初始值进行代码调整)以找到a 的下限。未显示,留给 OP 查找。 (我发现低边 a 在 1.0 到 1.5 范围内)
int main() {
double x, eps = 1.e-16;
printf("Enter x :\n");
//scanf("%le", &x);
x = e*1.0001;
printf("%le\n", newton(x, eps));
double a_min = e;
double a_max = e + 100.0;
double a;
while (1) {
a = a_min + (a_max - a_min)/2;
if (a == a_min) break;
else if (a == a_max) break;
if (a_min >= a_max) break;
printf("a_min:%20e a_max:%20e a:%20e\n", a_min, a_max, a);
if (isnan(newton(a, eps))) {
a_max = a;
} else {
a_min = a;
}
}
printf("a high side:%e\n", a);
return 0;
}
double newton(double x, double eps) {
double x1;
int i;
for (i=10; i>0; i--) {
//printf("%2d %20e %20e %20e\n", i, x, fd(x), f(x));
if (isnan(x)) return x;
x1 = x - f(x) / fd(x);
if (fabs(x1-x) < eps)
return x1;
x = x1;
}
return 0.0/0.0;
}
结果
Enter x :
2.718282e+00
a_min: 2.718282e+00 a_max: 1.027183e+02 a: 5.271828e+01
a_min: 2.718282e+00 a_max: 5.271828e+01 a: 2.771828e+01
a_min: 2.718282e+00 a_max: 2.771828e+01 a: 1.521828e+01
a_min: 2.718282e+00 a_max: 1.521828e+01 a: 8.968282e+00
a_min: 2.718282e+00 a_max: 8.968282e+00 a: 5.843282e+00
a_min: 2.718282e+00 a_max: 5.843282e+00 a: 4.280782e+00
a_min: 2.718282e+00 a_max: 4.280782e+00 a: 3.499532e+00
a_min: 3.499532e+00 a_max: 4.280782e+00 a: 3.890157e+00
a_min: 3.890157e+00 a_max: 4.280782e+00 a: 4.085469e+00
a_min: 4.085469e+00 a_max: 4.280782e+00 a: 4.183126e+00
a_min: 4.085469e+00 a_max: 4.183126e+00 a: 4.134297e+00
a_min: 4.085469e+00 a_max: 4.134297e+00 a: 4.109883e+00
...
a_min: 4.104323e+00 a_max: 4.104323e+00 a: 4.104323e+00
a high side:4.104323e+00
导出方程以找到这个“a”并求解它。
"Derive" --> dang,更有趣的模拟如上找到它。
考虑两个x:x_lo、x_hi 和牛顿迭代x_better(x) = x - f(x)/f'(x)。
当next_better(x_lo) == next_better(x_hi) 和x_lo < x_hi 时,我们处于一个振荡对中。
剩下的留给 OP。该走了。