Try   HackMD

mado: 三角函數

contributed by <jouae>

在 mado RP#27 中由ndsl7109256 貢獻改進三角函數查表的大小中,後續 ndsl7109256 採用五階固定點泰勒展開逼近正弦函數。

其中,遇到一個逼近問題「正切函數該怎麼計算?」

由於 mado 該專案希望最大限度地減少計算上使用到除法運算子 /,所以在計算正切函數時,避免直接以

tanx=sinxcosx
計算。mado 中是希望減少除法運算子 / 的使用。

另一個計算三角函數可行的方案是採用座標旋轉數位計算法(Coordinate Rotation Digital Computer, CORDIC)。

該算法的優點在於僅需要加法和乘法就可以計算一三角函數的逼近值。

CORDIC 綜覽可以看 50 Years of CORDIC: Algorithms, Architectures, and Applications 一文

Coordinate Rotation Digital Computer

以浮點數實作部分

CORDIC 是 Jack E. Volder 在 1956 年提出的一份技術報告中的計算方法,並於 1959 年正式公開在 Proceedings of the Western Joint Computer Conference (WJCC) 上。

以下內容摘自原始論文 The CORDIC Computing Technique, Jack Volder, 1959

其精神在於對一向量做旋轉迭代。考慮一二維座標中的旋轉矩陣跟一二維向量

[xi,yi]

[xi+1yi+1]=[cosθisinθisinθicosθi][xiyi]=cosθi[1tanθitanθi1][xiyi]

對於正整數

i ,固定旋轉角度
θi
使得
tanθi=2i
,其中該角度
θi
可以藉由反正切函數表示為
θi=arctan(2i)

則上述線性系統可以改寫成

[xi+1yi+1]=cos(arctan(2i))[1di2idi2i1][xiyi]=Ki[1di2idi2i1][xiyi]
其中,
Ki=cos(arctan(2i))
di=1
當旋轉為順時針旋轉,
di=1
當旋轉為逆時針旋轉。藉由
Ki
可以計算一縮放因子(scaling factor)
K(n)

K(n)=i=0n1Ki=i=0n1cos(arctan(2i))=i=0n111+22i

最後一個等式成立是基於

cosx=11+tan2x,此關係式從
1+tan2x=sec2x
推導。
n
為一自設定的迭代次數。

具體來說把這些旋轉角度

θi 加總起來則得到
θ=i=0n1diθi=i=0n1diarctan(2i)

其中

θ 為目標旋轉角度。

其中

xi 代表
cosθi
的值,所求
cosθ

xn1=cosθ=cos(i=0n1diθi)

yi 代表
sinθi
的值,所求
sinθ

yn1=sinθ=sin(i=0n1diθi)

為了確定

di
1
1
,令變數
zi
紀錄前
i1
次微旋轉角度總和,即
zi=k=0i1dkθk,for 0<i<n1

則關係式可以表達為

zi+1=zi+diθi

在令

z=θ 為目標旋轉角度,確認目標旋轉角度減去前
i
次微旋轉角度總和的正負號即可得知
di

di={1, if zzi>01, if zzi<0

變數

zi 的作用很簡單,其實就是確定該向量在
i
次旋轉後,下次該以逆時針(
di=1
)旋轉或是順時針旋轉(
di=1
)朝目標角度旋轉該微旋轉角度
θi

Max-Gulda 編寫的 Cordic-Math 以 C 語言實踐該算法。

收斂性分析

Expanding the range of convergence of the CORDIC algorithm, 1991

The Scaling Free Method

原始演算法的缺點之一在於需要計算縮放因子

Ki

An array architecture for fast computation of discrete hartley transform, A. S. Dhar and S. Banerjee, 1991 一文中提出小角度近似三角函數計算旋轉矩陣的方法,並附上一誤差估計。

考慮正弦與餘弦的在點

x0+ϵ 泰勒展開
sin(x0+ϵ)=sin(x0)+ϵcos(x0)1!+ϵ2sin(x0)2!ϵ3cos(x0)3!+cos(x0+ϵ)=cos(x0)+ϵsin(x0)1!ϵ2cos(x0)2!+ϵ3sin(x0)1!+

x0=0 時,上述三角函數的低階逼近為
sin(ϵ)=ϵϵ22!sin(ξs)cos(ϵ)=1ϵ22!+ϵ33!sin(ξc)

其中

ϵ22!sin(ξs)
ϵ33!sin(ξc)
為泰勒展開剩餘項,
ξs
ξc
皆介於
0
ϵ
之間。

簡易的說,用小角度

ϵ 近似三角函數,如
sin(ϵ)ϵ,cos(ϵ)1ϵ22

其誤差為

|sin(ϵ)ϵ|=ϵ22sin(ξs)ϵ22|cos(ϵ)(1ϵ22)|=ϵ36sin(ξc)ϵ36

在此將小角度

ϵ 皆以
2i
取代,分析
ϵ36

23i6=23i2131=2(3i+1+log23)<2(3i+2.585)

最後不等式成立的原因為

1+log232.58496250072 小於
2.585
。表示餘弦函數小角度近似的誤差不超過
2(3i+2.585)

|cos(2i)(122i2)|<2(3i+2.585)

2p 表示右移
p
位元運算,因為
i
為一變動的數,想要讓精度保持在
2(3i+2.585)
以內,令
n
表最大迭代次數,即
2n
為最小旋轉角度,則限制
n
滿足:
2n2(3i+2.585)

上述不等式限制,是為了確保誤差項

2(3i+2.585) 不超過最小旋轉角度
2n


n2.5853in

於是原旋轉矩陣可以近似表示為

[12(2i+1)2i2i12(2i+1)]

所以最終旋轉後的座標表示為:

[xnyn]=i=jn1[12(2i+1)2i2i12(2i+1)][xiyi], for j=p2.5853

The Look Up Table of the Angles

i 微角度表示為
θi=arctan(2i)
,則
tanθi=2i

θ=θL+θS

https://www.researchgate.net/publication/382638647_Flexible_and_Cost-Effective_Spherical_to_Cartesian_Coordinate_Conversion_Using_3-D_CORDIC_Algorithm_on_FPGA

i
θi
(radix)
tanθi
1
45
1
2
26.565
12
3
14.036
14
4
7.125
18
5
3.576
116
6
1.7876
132
7
0.8938
164
8
0.4469
1128
9
0.2238
1256

以有限集合表示查找表

S ,則,
S={arctan21,arctan22,arctan23,,arctan2n}

其中,
n
與經度

Hybird Method

  1. 表格多大
  2. 精度
  3. 程式碼,相依性,一個 cycle 幾道指令

Reference