跳到内容

三角函数/爱好者/CORDIC 算法

来自维基教科书,自由的教科书,为自由的世界

它是什么

[编辑 | 编辑源代码]

CORDICCOordinate Rotation DIgital Computer 的缩写)是一种简单高效的算法,用于计算三角函数。它只需要以下运算:

  • 加法,
  • 减法,
  • 乘以 2 和除以 2,以及
  • 查表(一个包含 64 个数字的表格足以用于手持计算器可以计算的所有余弦和正弦)。

因为计算机内部使用二进制运算,所以乘以 2 和除以 2 操作非常快且易于执行。因此,CORDIC 算法允许使用相对简单的 CPU 高效地计算三角函数。

CORDIC 特别适合手持计算器,对于这种应用,成本(例如芯片门数必须最小化)远比速度重要。此外,用于三角函数和双曲函数的 CORDIC 子例程(在三角函数第 2 册中描述)可以共享大部分代码。


操作模式

[编辑 | 编辑源代码]

CORDIC 可以用来计算许多不同的函数。本解释展示了如何使用 CORDIC 的旋转模式来计算角度的正弦和余弦,并假设所需的角度以弧度表示,并以定点格式表示。为了确定角度 的正弦或余弦,必须找到与所需角度相对应的单位圆上一个点的 y 坐标或 x 坐标。使用 CORDIC,我们将从向量  

在第一次迭代中,该向量将逆时针旋转 45 度,得到向量 。后续的迭代将以逐渐减小的步长,沿一个或另一个方向旋转该向量,直到达到所需的角度。第 i 步的大小为 Artg(1/(2(i-1))),其中 i 为 1、2、3 等。

CORDIC 算法正在进行的插图。

更正式地说,每次迭代都会计算一个旋转,该旋转通过将向量 与旋转矩阵 相乘来完成。

旋转矩阵 R 由以下公式给出:

使用以下两个三角恒等式:

旋转矩阵变为

旋转后的向量 的表达式变为

其中, 的分量。限制角度 使得 取值 ,则与正切的乘法可以替换为除以2的幂,这在使用位移的数字计算机硬件中可以高效地完成。表达式变为

其中

并且 可以取值为 -1 或 1,用于确定旋转方向:如果角度 为正,则 为 1,否则为 -1。

我们可以忽略 在迭代过程中,然后通过缩放因子在之后应用它

这可以提前计算并存储在一个表中,或者如果迭代次数是固定的,则存储为一个常量。这种校正也可以提前进行,通过缩放 并且因此节省了乘法。此外,可以注意到

[1]

以允许进一步减少算法的复杂度。在足够多的迭代之后,向量的角度将接近于想要的角度 。对于大多数普通用途,40 次迭代 (n = 40) 足以获得小数点后第 10 位的正确结果。

剩下的唯一任务是确定每次迭代时旋转应该是顺时针还是逆时针(选择 的值)。这可以通过跟踪每次迭代我们旋转了多少并从想要的角度减去它来完成,然后检查 是正的,我们需要顺时针旋转,还是如果它是负的,我们必须逆时针旋转,以便更接近想要的角度

的值 也必须预先计算并存储。但对于小角度, 在定点表示中,减少了表的大小。

如上图所示,角度 的正弦是最终向量 的 y 坐标,而 x 坐标是余弦值。

硬件实现

[edit | edit source]

在硬件实现中,CORDIC 算法的主要用途是避免耗时的复杂乘法器。复数相位的计算可以使用硬件描述语言轻松实现,仅使用加法器和移位器电路,绕过笨重的复数乘法器。制造技术一直在稳步改进,现在可以以不高的时间、功耗或过大的芯片空间成本直接处理复数,因此在许多应用中,CORDIC 技术的使用不像以前那么关键。

[编辑 | 编辑源代码]

CORDIC 属于“移位-加”算法类别,就像从亨利·布里格斯(Henry Briggs)作品中衍生出来的对数和指数算法一样。另一种可用于计算许多基本函数的移位-加算法是 BKM 算法,它是对数和指数算法在复平面的推广。例如,BKM 可用于通过计算 的指数来计算实数角度(以弧度为单位)的正弦和余弦,即。BKM 算法比 CORDIC 稍微复杂,但它不需要缩放因子(K)。

现代 CORDIC 算法由杰克·E·沃尔德(Jack E. Volder)于 1959 年首次描述。它是在康维尔(Convair)的航空电子部门开发的,旨在替代 B-58 轰炸机导航计算机中的模拟解算器。[2]

尽管 CORDIC 与亨利·布里格斯(Henry Briggs)早在 1624 年发表的数学技术类似,但它针对低复杂度有限状态 CPU 进行了优化。

惠普(Hewlett-Packard)的约翰·斯蒂芬·沃尔特(John Stephen Walther)进一步推广了该算法,使其能够计算双曲函数和指数函数、对数、乘法、除法和平方根。[3]

最初,CORDIC 使用二进制数值系统实现。在 20 世纪 70 年代,十进制 CORDIC 在袖珍计算器中得到广泛使用,这些计算器大多使用二进制编码十进制 (BCD) 而不是二进制。


当硬件乘法器不可用(例如,在基于微控制器的系统中)或需要将实现其支持的函数所需的栅极数量降至最低(例如,在 FPGA 中)时,CORDIC 通常比其他方法更快。

另一方面,当硬件乘法器可用(例如,在 DSP 微处理器中)时,查表法和幂级数通常比 CORDIC 快。近年来,CORDIC 算法被广泛用于各种生物医学应用,尤其是在 FPGA 实现中。

许多具有仅整数 CPU 的旧系统在一定程度上在其 IEEE 浮点库中实现了 CORDIC。由于大多数现代通用 CPU 都有浮点寄存器,并具有常见的运算(如加、减、乘、除、正弦、余弦、平方根、log10、自然对数),因此在其中使用软件实现 CORDIC 的需求几乎不存在。只有微控制器或特殊的安全和时间约束软件应用程序需要考虑使用 CORDIC。

沃尔德(Volder)受到 1946 年版 CRC 化学和物理手册中以下公式的启发

其中[2]

CORDIC 的一些早期突出应用包括康维尔导航计算机 CORDIC I 到 CORDIC III[2]、惠普(Hewlett-Packard)的 HP-9100 和 HP-35 计算器[4]、英特尔(Intel)的 80x87 协处理器系列(直到英特尔 80486)和摩托罗拉(Motorola)的 68881[5]

十进制 CORDIC 最初由赫尔曼·施密特(Hermann Schmid)和安东尼·博加茨基(Anthony Bogacki)提出。[6]

  1. J.-M. Muller,基本函数:算法和实现,第二版 (Birkhäuser, Boston, 2006),第 134 页。
  2. a b c J. E. Volder,“CORDIC 的诞生”,VLSI 信号处理杂志 25,101 (2000)。
  3. J. S. Walther,“统一 CORDIC 的故事”,VLSI 信号处理杂志 25,107 (2000)。
  4. D. Cochran,“HP 35 中的算法和精度”,惠普杂志 23,10 (1972)。
  5. R. Nave,“数值处理器上超越函数的实现”,微处理和微编程 11,221 (1983)。
  6. H. Schmid 和 A. Bogacki,“使用十进制 CORDIC 生成许多超越函数”,EDN 杂志,1973 年 2 月 20 日,第 64 页。

参考文献

[编辑 | 编辑源代码]
华夏公益教科书