如何高效地計算sin(x)與cos(x)的值?

sin(x)=x-x^3/3!+x^5/5!-。。。。 我覺得這個收斂比較慢, 有沒有收斂比較快的級數呢?, 就好比pi有收斂比較快的級數, 也有收斂比較慢的級數, 同樣cos(x)呢? 我又查到一個連分數計算方法, 請問有沒有比較好的精度高的辦法?

。。。。。。。。。。。。

2015.06.19更新。

萬能公式。

sin(x)=2t/(1+t^2)

t=tan(x/2)

然後對t泰勒展開,是否更快?


如果固定精度,可以用Cordic之類的查表法解決。

如果需要任意高精度,演算法就不那麼直接了,我貼一個apfloat庫用的演算法吧,假定輸入是實數。

分三步

第一步利用關係式

e^{ix}=cos x+isin x

所以sin x=old{Im}(e^{ix})cos x=old{Re}(e^{ix})

這樣,我們只要求得e^{ix}就萬事大吉了

第二步假定我們有了log z的演算法,那麼計算e^z就是解方程f(x)=log x-z=0,可以用牛頓迭代法解決,迭代公式為z_{n+1}=z_n(1+z-log z_n)

第三步,我們需要log z的任意精度演算法,基本原理是用Arithmetic–Geometric Mean迭代。

先解釋一下AGM的原理,選定a_0,b_0後,進行迭代a_{n+1}=frac{a_n+b_n}{2};b_{n+1}=sqrt{a_nb_n},那麼序列{a_n},{b_n}有公共極限,記作	extrm{AGM}(a_0,b_0)

現在有定理,對xin(1/2,1)ngeqslant3

left|log x-frac{pi}{2}left[frac{1}{	extrm{AGM}(1,10^{-n})}-frac{1}{	extrm{AGM}(1,10^{-n}x)} 
ight]
ight|leqslantfrac{n}{10^{2(n-1)}}

且此式子對於x為複數也成立(當然1/2<|x|<1)。

所以,我們可以對log z逼近到任意精度,當然必須把z的縮放下,使得1/2<|z|<1,否則AGM不收斂。這樣的演算法收斂速度指數級的。


Sin是周期函數,可以選擇0-45度的部分計算( @王希 已經說了,周期性和誘導函數)。

對於硬體來說:

0. 利用周期性縮小定義域。

1. 有限精度下的Sin和Cos都使用查表法(CORDIC)。

2. 擴展精度的部分用泰勒展開。

對於軟體來說:

1. 有限精度可以選擇多項式逼近;

2. 擴展精度用泰勒展開。

-------------------------------------------------

StackOverflow:

c++ - How does C compute sin() and other math functions?


有比泰勒級數更好的做法,簡單來講,sin(x)是函數空間中的一個矢量,然後5次多項式構成的空間是函數空間的一個子空間,sin(x)在五次多項式空間上的正交投影就是對sin(x)的最佳五次多項式逼近,這個近似在整個周期內的精度都非常高。這個五次多項式的表達式是

y = 0.987862x - 0.155271x^3 + 0.00564312x^5

具體內容見《線性代數應該怎麼學》第六章。

--------------------

為了方便大家,具體步驟列在下面

求sin(x)的逼近等價於求使如下積分最小的函數f(x)

int_{-pi}^{pi}|sin(x)-f(x)|^2dx

為了找到這樣的f(x)可定義如下內積

<f,g>=int_{-pi}^{pi}f(x)g(x)dx

u=sin(x)U為次數不超過五的實係數多項式組成的子空間,那麼問題重述為找到uin U

使得||u-v||最小,由正交投影的性質可知,當u=P_Uv時該值最小。為了求得正交投影P_Uv,首先需要知道U的一組規範正交基,對U的基(1,x,x^2,x^3,x^4,x^5)進行格拉姆-施密特正交化過程可得規範正交基為

(e_1,e_2,e_3,e_4,e_5,e_6)=(frac{1}{sqrt{2pi}}, \frac{sqrt{frac{3}{2}}x}{pi^{3/2}},  \ -frac{sqrt{frac{5}{2}}(pi^2-3x^2)}{2pi^{5/2}}, \<br />frac{sqrt{frac{7}{2}}(3pi^2x-5x^3)}{2pi^{7/2}}, \<br />frac{3(3pi^4-30pi^2x^2+35x^4)}{8sqrt{2}pi^{9/2}}, \<br />-frac{sqrtfrac{11}{2}(15pi^4x-70pi^2x^3+63x^5)}{8pi^{11/2}})

最後,可求得

P_Uv  = <v,e_1>e_1+<v,e_2>e_2+<v,e_3>e_3+<v,e_4>e_4+<v,e_5>e_5+<v,e_6>e_6 \<br />= frac{105(1485-153pi^2+pi^4)}{8pi^6}x - frac{315(1155-125pi^2+pi^4)}{4pi^8}x^3+frac{693(945-105pi^2+pi^4)}{8pi^{10}}x^5<br />

即為所求得得多項式近似,為了直觀地比較近似地精度,現將sin(x)和所求得的近似繪於同一圖中

其中藍色曲線是sin(x),紅色曲線是近似多項式,可以觀察到二者幾乎完全重合。為了和泰勒級數的精度作比較,現將泰勒級數所得的結果也繪於圖中,可以觀察到在靠近pi-pi的地方結果已經完全偏離了。

如果只需要在半個周期內作近似的話,求正交投影這種方法的精度還會更高。


前面的都說的很具體,幾乎所有的解析函數的數值計算都是通過Pade 近似來獲得的,可以搜一下pade近似,


謝邀。我還沒有無聊到假裝被邀請。

因為它們都是奇函數或者偶函數,偶次冪/奇次冪均為0,因此級數展開其實是完全沒問題的,重要的是展開之前的處理:

  1. 利用周期性把x變成(-pi,pi]中的數,

  2. 再利用奇偶性把x變成[0,pi]中的數,

  3. 再用誘導公式把x變成[0,frac{pi}{2}]中的數,

  4. 用誘導公式把x變成[0,frac{pi}{4}]中的數

  5. 最後級數展開。

例如要計算sinfrac{50pi}{9},就有

sinfrac{50pi}{9}=sin(-frac{4pi}{9})=-sin(frac{4pi}{9})=-cos(frac{pi}{2}-frac{4pi}{9})=-cos(frac{pi}{18})

(這裡解釋一下,泰勒級數無論展開多少項,只要這個項數設定好就是O(n)的演算法,所以能做的就是優化常數。而計算機存儲實數的精度是有限的,一個操作如果即有利於速度(少展開)又有利於減小精度損失(比如上述處理),我就認為它是有意義的。)

由於二者都是交錯級數,故誤差不會超過最後一項的絕對值。上述公式可以將x的絕對值減小到不超過frac{pi}{4},即精度可以近似為frac{1}{n!}cdot (frac{pi}{4})^{n}.我們看看其收斂情況:

注意到正弦函數和餘弦函數都是隔項的,因此實際需要的項數是n的一半。也就是說達到9位精度只需要5項即可。這已經是非常不錯的了。而且這裡列舉的是最大可能的誤差,實際的誤差比這個誤差要小一些。

個人認為無論如何,這個周期性都是必須利用的,再精確的多項式直接把十萬帶進去肯定抓瞎。不過如評論區知友所說,後邊幾步可能意義不大。而答主才疏學淺,沒聽過simd和cordic。

當然了,如果確定區間為[0,frac{pi}{4}],我們就可以先把最佳近似多項式設出來,比如f(x)=ax+bx^{3}+cx^{5}.然後設目標函數z(a,b,c)=int_{0}^{frac{pi}{4}}[f(x)-sin x]^{2}mathrm{d}x

取目標函數最小值,求出a,b,c。結果會和泰勒展開有一定差別,但只要自變數足夠小,實際差距也沒有多大。


cordic演算法介紹,簡單容易明白!

http://m.blog.csdn.net/blog/liyuanbhu_11109/8458769


Cordic


sicp上看來的。

主要是lim_{aph 
ightarrow 0}{sin(aph)}  = aph,其他情況下3*sin(frac{aph}{3} )-4*sin(frac{aph}{3} )^{3}

我試了一下,當abs(aph)&<1e-14時令sin(aph)返回aph,大概就跟c函數math庫算出的一樣了。

static double Cube(double x){
return x*x*x;
}
static double p(double x){
return 3 * x - 4 * Cube(x);
}
static double ABS(double x){
return x &> 0 ? x : -x;
}
static double Sin(double angle){
if (ABS(angle) &<= 1e-14) { return angle; } return p(Sin(angle / 3.0)); }


查表法,簡單粗暴!


https://github.com/golang/go/blob/master/src/math/sin.go


推薦閱讀:

彈性力學裡的平面問題差分解中如何區分向前差分和向後差分?
為什麼不動點迭代法的收斂與其導數有關?
最近在學數值分析,有誰能跟我簡單講講啥是範數啊?
學化學專業必修課程學數值分析的意義在哪?

TAG:數學 | 微積分 | 數學分析 | 數值分析 | 級數 |