连分数逼近

数学中,分数繁分数即如下表达式:

x = a_0 + \cfrac{1}{a_1 + \cfrac{1}{a_2 + \cfrac{1}{a_3 + \cfrac{1}{\ddots\,}}}}

这里的 a0 是某个整数而所有其他的数 an 都是正整数。可依样定义出更长的表达式。如果部分分子(partial numerator)和部分分母(partial denominator)允许假定任意的值,在某些上下文中可以包含函数,则最终的表达式是广义连分数。在需要把上述标准形式与广义连分数相区别的时候,可称它为简单正规连分数,或称为是规范形式的。

 

 

 

连分数常用于无理数的逼近,例如:

\sqrt{2} = 1 + \frac{1}{2 + \frac{1}{2 + \frac{1}{2 + \frac{1}{2 + \frac{1}{2 + \frac{1}{2 + ...}}}}}} 由此得到\sqrt{2}渐近分数 \frac{1}{1}\frac{3}{2}\frac{7}{5}\frac{17}{12}、……

 

 

考虑实数 r。设 ir 的整数部分,而 f 是它的小数部分。则 r 的连分数表示是 [i; …],这里的“…”是 1/f 的连分数表示。习惯上用分号取代第一个逗号。

要计算实数 r 的连分数表示,写下 r 的整数部分(技术上 floor)。从 r 减去这个整数部分。如果差为 0 则停止;否则找到这个差的倒数并重复。这个过程将终止,当且仅当 r 是有理数。

找出 3.245 的连分数
3\,3.245 - 3\,= 0.245\,1 / 0.245\,= 4.082\,
4\,4.082 - 4\,= 0.082\,1 / 0.082\,= 12.250\,
12\,12.250 - 12\,= 0.250\,1 / 0.250\,= 4.000\,
4\,4.000 - 4\,= 0.000\,STOP
3.245 的连分数是 [3; 4, 12, 4]
3.245 = 3 + \cfrac{1}{4 + \cfrac{1}{12 + \cfrac{1}{4}}}

数 3.245 还可以表示为连分数展开 [3; 4, 12, 3, 1];参见下面的有限连分数。

这个算法适合于实数,但如果用浮点数实现的话,可能导致数值灾难。作为替代,任何浮点数是一个精确的有理数(在现代计算机上分母通常是 2 的幂,在电子计算器上通常是 10 的幂),所以欧几里德GCD算法的变体可以用来给出精确的结果。

 

 

 

\frac{\sqrt{5} -1}{2} = \frac{1}{1 + \frac{1}{1 + \frac{1}{1 + \frac{1}{1 + \frac{1}{1 + \frac{1}{1 + ...}}}}}} 由此得到黄金分割的渐近分数 \frac{1}{1}\frac{1}{2}\frac{2}{3}\frac{3}{5}\frac{5}{8}\frac{8}{13}、……

注意将上述系列的分子分母依序排列均可得到 斐波那契数列

\pi = 3 + \frac{1}{7 + \frac{1}{15 + \frac{1}{1 + \frac{1}{292 + \frac{1}{1 + \frac{1}{1 + ...}}}}}} 由此得到圆周率的渐近分数 \frac{3}{1}\frac{22}{7}约率)、\frac{333}{106}\frac{355}{113}密率)、\frac{103993}{33102}、……

数学上可以证明,由(狭义)连分数得到的渐近分数,在分子或分母小于下一个渐进分数的分数中,其值是最接近精确值的近似值。

 

 

 

研究连分数的动机源于想要有实数在“数学上纯粹”的表示。

多数人熟悉实数的小数表示:

r = \sum_{i=0}^\infty a_i 10^{-i}

这里的 a0 可以是任意整数,其它 ai 都是 {0, 1, 2, ..., 9} 的一个元素。在这种表示中,例如数 π 被表示为整数序列 {3, 1, 4, 1, 5, 9, 2, ...}。

这种小数表示有些问题。例如,在这种情况下使用常数 10 是因为我们使用了 10 进制系统。我们还可以使用 8 进制或 2 进制系统。另一个问题是很多有理数在这个系统内缺乏有限表示。例如,数 1/3 被表示为无限序列 {0, 3, 3, 3, 3, ....}。

连分数表示法是避免了实数表示的这两个问题。让我们考虑如何描述一个数如 415/93,约为 4.4624。近似为 4,而实际上比 4 多一点,约为 4 + 1/2。但是在分母中的 2 是不准确的;更准确的分母是比 2 多一点,约为 2 + 1/6,所以 415/93 近似为 4 + 1/(2 + 1/6)。但是在分母中的 6 是不准确的;更准确分母是比 6 多一点,实际是 6+1/7。所以 415/93 实际上是 4+1/(2+1/(6+1/7))。这样才准确。

去掉表达式 4 + 1/(2 + 1/(6 + 1/7)) 中的冗余部分可得到简略记号 [4; 2, 6, 7]。

实数的连分数表示可以用这种方式定义。它有一些可取的性质:

  • 一个数的连分数表示是有限的,当且仅当这个数是有理数
  • “简单”有理数的连分数表示是简短的。
  • 任何有理数的连分数表示是唯一的,如果它没有尾随的 1。(但是 [a0; a1, ... an, 1] = [a0; a1, ... an + 1]。)
  • 无理数的连分数表示是唯一的。
  • 连分数的项将会重复,当且仅当它是一个二次无理数(即整数系数的二次方程的实数解)的连分数表示 [1]
  • x 的截断连分数表示很早产生 x 的在特定意义上“最佳可能”的有理数逼近(参阅下述定理 5 推论 1)。

最后一个性质非常重要,且传统的小数点表示就不能如此。数的截断小数表示产生这个数的有理数逼近,但通常不是非常好的逼近。例如,截断 1/7 = 0.142857... 在各种位置上产生逼近比,如 142/1000、14/100 和 1/10。但是明显的最佳有理数逼近是“1/7”自身。π 的截断小数表示产生逼近比,如 31415/10000 和 314/100。π 的连分数表示开始于 [3; 7, 15, 1, 292, ...]。截断这个表示产生极佳的有理数逼近 3、22/7、333/106、355/113、103993/33102、...。 314/100 和 333/106 的分母相当接近,但近似值 314/100 的误差是远高于 333/106 的 19 倍。作为对π的逼近,[3; 7, 15, 1] 比 3.1416 精确 100 倍。

 

 

 

 

現在我們先回想一下歐幾里德計算法:

a,b 為兩整數,且 b>a,則

 

\begin{displaymath} \mbox{({\fontfamily{cwM7}\fontseries{m}\selectfont \char 66}... ...tfamily{cwM1}\fontseries{m}\selectfont \char 162}}) \end{cases}\end{displaymath}


 

 

這個計算法是在紀元前三世紀時由歐幾里德發現的,記載在他不朽的《原本》裡第七卷上。它的主要目的在於求兩數 ab 的最大公因數(即上式中之 rN)。今天,如果我們要電子計算機為我們設計解決最大公因數的問題的話,我們該為歐幾里德驕傲,因為他兩千年前用的這個方法仍然是目前最棒的。

現在,我們把(甲)組裡的式子全寫為分式,如下所示:

 

\begin{displaymath} \mbox{({\fontfamily{cwM3}\fontseries{m}\selectfont \char 14}... ...N}{r_{N-1}} \\ & \frac{r_{N-1}}{r_N}=a_N \end{eqalign}\right. \end{displaymath}


 

 

再將乙組中第一式之 ${\displaystyle \frac{r_1}{b} }$ 以第三式之倒數代入,接著 ${\displaystyle \frac{r_2}{r_1} }$ 以第三式之倒數代入,依次類推,即得

 

\begin{eqnarray*} \mbox{({\fontfamily{cwM3}\fontseries{m}\selectfont \char 6})} ... ...inus0.1pt{\fontfamily{cwM1}\fontseries{m}\selectfont \char 98}}) \end{eqnarray*}

 


上式之右邊即所謂的「連分數」(更精確地說,有窮簡單連分數)。為了節省篇幅及簡便起見,我們簡寫為

 

\begin{displaymath} a_0+\frac{1}{a_1}\; \lower1.5ex\hbox{$+$}\; \frac{1}{a_2} \;... ...fontseries{m}\selectfont \char 67}} \quad [a_0,a_1,\cdots,a_N] \end{displaymath}
 

 

以下是连分数代码的实现 纯属本人按图索骥 如有不足请指出

 

 

 

#include  < iostream >
#include 
< cmath >
using   namespace  std;

__int64 Num[
1000 ]; // 记录连分数数列

// Continued fractions

long  Fraction(__int64 r,__int64 f)
{
    __int64 m
= 1 ;
    
while  (m <= f)
    {
        m
*= 10 ;
    }

    __int64 s
= r * m + f;
    
long  len = 0 ;

    
    
while  (s % m != 0 )
    {
        __int64 t
= s % m;
        Num[len
++ ] = s / m;
        s
= m;
        m
= t;    
    }
    Num[len
++ ] = s / m;
    
// 将分母依次存入数列


    
return  len;
}


int  main()
{
    __int64 r,f;
    
while  (scanf( " %I64d.%I64d " , & r, & f) != EOF)
    {
        
long  len = Fraction(r,f);
        
long  i;
        
for  (i = 0 ;i < len; ++ i)
        {
            printf(
" %ld:%I64d\n " ,i + 1 ,Num[i]);
        }
    }
    
return   0 ;
}

 

 

转载于:https://www.cnblogs.com/zhuangli/archive/2008/08/19/1271069.html

参考资源链接:[圆周率计算探索:连分数逼近与算法实现](https://wenku.csdn.net/doc/64a8c829b9988108f2017948?utm_source=wenku_answer2doc_content) 为了精确计算圆周率π的近似值,可以利用连分数逼近和蒙特卡洛法进行编程。首先,连分数逼近是一种高效的数学方法,可以得到圆周率的高精度近似值。Maple中的`pi_thiele`程序就是一个很好的例子,它演示了如何使用Thiele公式来计算π。其次,蒙特卡洛法作为一种随机模拟方法,通过在单位正方形内随机投掷点,并计算这些点落在单位圆内的比例,从而估算π的值。以下是两种编程语言的具体示例: 在Maple中,可以编写如下代码来实现连分数逼近: ```maple pi_convergents := proc(n) local A, B, P, Q, temp, k, convergents; A[0] := 0; B[0] := 1; P[0] := 1; Q[0] := 0; A[1] := 1; B[1] := 1; P[1] := 3; Q[1] := 1; convergents := [3]; for k from 2 to n do temp := Q[k-1]; Q[k] := B[k-1] + 2*temp; A[k] := A[k-1] + A[k-2]; B[k] := B[k-1] + B[k-2]; P[k] := P[k-1] + (2*temp + 1)*P[k-2]; end do; convert(convergents, list); end proc; ``` 这段代码计算了π的前n个连分数逼近的值。 在Matlab中,可以使用以下代码来实现蒙特卡洛法: ```matlab function pi_estimate = monte_carlo_pi(n) x = rand(n, 1); y = rand(n, 1); distance = sqrt(x.^2 + y.^2); pi_estimate = 4 * sum(distance <= 1) / n; end ``` 这段代码通过随机生成n个点,然后计算落在单位圆内的点的数量,从而估算π的值。 结合这两种方法,可以在Maple中实现更精确的π计算,通过增加连分数逼近的迭代次数,并在Matlab中使用蒙特卡洛法时增加投掷点的数量,以获得更好的估算结果。读者可以参考《圆周率计算探索:连分数逼近与算法实现》来了解更深入的理论和算法实现细节。 参考资源链接:[圆周率计算探索:连分数逼近与算法实现](https://wenku.csdn.net/doc/64a8c829b9988108f2017948?utm_source=wenku_answer2doc_content)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值