不动点迭代算法

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,打发了两个小时的无聊时间。唉,什么时候才动手搞毕业设计呢,真是有够堕落的。

众所周知,百度是一家大型广告公关公司,附带高质量的站内搜索引擎??,但有一说一,百度文库确实挺好用的??,特别是找课件看,找期末题库。

以上是关于不动点迭代算法的主要内容,如果未能解决你的问题,请参考以下文章

超越MapReduce的并行大数据处理

tensorflow-不动点迭代求一元方程

不动点迭代法

MATLAB用二分法不动点迭代法及Newton迭代(切线)法求非线性方程的根

newton迭代法可以用matlab求非线性方程方程的全部根吗??一次就求出全部根吗??

数学动态规划:Blackwell引理,价值函数算法