不动点迭代算法
Posted sinkinben
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不动点迭代算法相关的知识,希望对你有一定的参考价值。
今天有个小朋友向我提出了一个「了不起」的问题。
一个有趣的现象
打开一个没有 Bug 的计算器,任意输入一个数值 (x),然后找到函数 (sin(x)) 或者 (cos(x)) ,连续点击这个函数若干次,你会发现一个有趣的现象:无论初始的 (x) 为多少,最后的值总是接近某一个数值(这些数值在某个精度范围内是相等的)。(sin(x)) 最后总为 (0) ,(cos(x)?) 最后为 0.73 或者 0.99 (取决于你的计算器是否开启弧度制)。
从数学的角度来看,实际上就是:定义 (f^1(x) = f(x), f^2(x)=f(f(x)), f^{n}(x)=f(f(f(...f(x))))) ,(n) 个 (f) 进行复合函数运算,求 (limlimits_{n ightarrow infty} f^{n}(x)) 。
显然,这道证明题我不会??。
万能的搜索引擎
虽然我不会证明,但是找一下是什么知识点还是挺简单的。查了一圈回来,发现这其实是「数值分析」中的 不动点方程 。上述证明题,(limlimits_{n
ightarrow infty} f^{n}(x)) 的值实际上是 (x = f(x)?) 的根。这个方程用「零点定理」,写一个 while-loop
就出来了,所以就不说了。
算了,还是说一下吧,反正闲着也是闲着。设 (g(x) = x - cos(x)?),显然 (g(0) cdot g(1) < 0?),(g(x)?) 为增函数,因此在 ((0,1)?) 上有 1 个零点。
#include <iostream>
#include <cmath>
using namespace std;
double func(double x)
{
return x - cos(x);
}
int main()
{
const double eps = 1e-8;
double l = 0, r = 1;
while ((r - l) >= eps)
{
double mid = (l + r) / 2;
func(mid) > 0 ? (r = mid) : (l = mid);
}
printf("%.8lf %.8lf
", l, r);
}
不动点迭代算法
这是扩展阅读部分,因为这篇文章看起来篇幅不太够,所以就凑点字数,反正看 blog 的人大多数都是一些「无聊的人」O(∩_∩)O 。
不动点迭代 (Fixed Point Iteration) ,用于求解某些非线性函数 (f(x)?) 的零点,也就是解方程 (f(x) = 0?) 。那么这个「不动点迭代算法」到底有什么用呢?
比如我想求 (f(x) = 1 + 0.5 sin{x} - x?) 的根,那么可以进行如下变换:
[
f(x) = 0 quad Rightarrow quad x = 1+0.5sin{x}
]
然后令 (g(x) = 1+0.5 sin {x}) ,对 (x_{i+1} = g(x_i)) 执行迭代若干次,就可以得到原方程的根 (x_n) 。
有这个「不动点迭代」法,求根就可以简单一点(虽然比「二分法」没简单多少??)。
double func(double x)
{
return 1 + 0.5 * sin(x);
}
int main()
{
srand(time(NULL));
double x = rand();
for (int i = 0; i < 10; i++)
x = func(x);
printf("%.10lf", x);
}
但这个算法其实对于 (g(x)) 来说是有条件的,并不是所有的方程都适用。如果对于方程 (x = 2x^3-1, g(x)=2x^3-1) 执行上面的算法,我们是得不到正确的答案 (x=1) 的。
Aside
设迭代函数 (g(x)) 在 ([a,b]) 上连续,且满足:
- 当 (x in [a,b]) 时,(a le g(x) le b)
- 存在一正数 (L) 满足 (0 < L < 1),且 (forall{x} in [a,b]) 均有 (|g^{'}(x)| le L)
则方程 (x = g(x)) 在 ([a,b]) 上有唯一解 (x_n) 。对于任意的初值 (x_0 in [a,b]) ,均可通过 (x_{i+1} = g(x_i)) 迭代求得 (x_n) 。
详细的证明请看这里。
总结
实际上我并没有解决这个小朋友的疑问(因为??也??懂怎么证明),但是至少我又水了一篇 blog,打发了两个小时的无聊时间。唉,什么时候才动手搞毕业设计呢,真是有够堕落的。
众所周知,百度是一家大型广告公关公司,附带高质量的站内搜索引擎??,但有一说一,百度文库确实挺好用的??,特别是找课件看,找期末题库。
以上是关于不动点迭代算法的主要内容,如果未能解决你的问题,请参考以下文章
MATLAB用二分法不动点迭代法及Newton迭代(切线)法求非线性方程的根