当前位置: 首页 > news >正文

探秘基带算法:从原理到5G时代的通信变革【五】CORDIC算法

文章目录

      • 2.4 CORDIC算法
        • 2.4.1 CORDIC算法的基本原理
        • 2.4.2 方法论与分类体系
          • 旋转模式
          • 矢量模式
          • 线性模式
        • 2.4.3 **CORDIC 算法中的误差来源**
          • **角度逼近误差的分析**
          • **缩放效应误差的分析**
          • **精度需求与迭代次数的关系**
          • **常见应用场景下的迭代次数建议**
          • **总结**
        • 2.4.4优缺点分析
        • 2.4.5 应用方向
        • 2.4.6实现细节
          • 软件实现
          • 硬件实现
        • 2.4.7 总结

本博客为系列博客,主要讲解各基带算法的原理与应用,包括:viterbi解码、Turbo编解码、Polar编解码、CORDIC算法、CRC校验、FFT/DFT、QAMtiaozhi/解调、QPSK调制/解调。其他博客链接如下:

  1. 探秘基带算法:从原理到5G时代的通信变革【一】引言
  2. 探秘基带算法:从原理到5G时代的通信变革【二】Viterbi解码
  3. 探秘基带算法:从原理到5G时代的通信变革【三】Turbo 编解码
  4. 探秘基带算法:从原理到5G时代的通信变革【四】Polar 编解码(一)
  5. 探秘基带算法:从原理到5G时代的通信变革【四】Polar 编解码(二)
  6. 探秘基带算法:从原理到5G时代的通信变革【五】CORDIC算法
  7. 探秘基带算法:从原理到5G时代的通信变革【六】CRC 校验
  8. 探秘基带算法:从原理到5G时代的通信变革【七】FFT/DFT
  9. 探秘基带算法:从原理到5G时代的通信变革【八】QAM 调制 / 解调
  10. 探秘基带算法:从原理到5G时代的通信变革【九】QPSK调制/解调
  11. 探秘基带算法:从原理到5G时代的通信变革【十】基带算法应用与对比

2.4 CORDIC算法

在现代计算领域,许多复杂数学运算(如三角函数、指数函数和对数函数)的高效实现离不开一种经典算法——CORDIC(Coordinate Rotation Digital Computer)。本文将深入探讨CORDIC算法的原理、分类体系、优缺点分析以及其广泛的应用方向,并通过详细的公式推导和实例解析帮助读者理解这一强大的数字计算工具。


2.4.1 CORDIC算法的基本原理

CORDIC算法是一种用于高效计算旋转、矢量模长和三角函数等操作的迭代方法。它的核心思想是通过一系列简单的移位和加法操作来逼近复杂的数学运算。这种方法特别适合硬件实现,因为移位和加法操作在数字电路中非常高效。

假设我们希望计算一个向量 ( x , y ) (x, y) (x,y) 绕原点旋转角度 θ \theta θ 后的新坐标 ( x ′ , y ′ ) (x', y') (x,y)。根据旋转矩阵公式:

[ x ′ y ′ ] = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] ⋅ [ x y ] \begin{bmatrix} x' \\ y' \end{bmatrix} {=} \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} [xy]=[cosθsinθsinθcosθ][xy]

直接计算 cos ⁡ θ \cos\theta cosθ sin ⁡ θ \sin\theta sinθ 需要大量乘法操作,而CORDIC算法通过以下方式简化了这一过程。

首先,我们将旋转角度 θ \theta θ 分解为一系列小角度 θ i \theta_i θi 的组合,这些小角度满足:

tan ⁡ − 1 ( 2 − i ) = θ i \tan^{-1}(2^{-i}) = \theta_i tan1(2i)=θi

其中 i = 0 , 1 , 2 , … i = 0, 1, 2, \dots i=0,1,2,。因此,每次迭代只需要计算一个简单的旋转操作,而不是直接计算复杂的三角函数值。

迭代公式如下:

x i + 1 = x i − d i ⋅ y i ⋅ 2 − i x_{i+1} = x_i - d_i \cdot y_i \cdot 2^{-i} xi+1=xidiyi2i

y i + 1 = y i + d i ⋅ x i ⋅ 2 − i y_{i+1} = y_i + d_i \cdot x_i \cdot 2^{-i} yi+1=yi+dixi2i

z i + 1 = z i − d i ⋅ θ i z_{i+1} = z_i - d_i \cdot \theta_i zi+1=zidiθi

这里:

  • d i = sgn ( z i ) d_i = \text{sgn}(z_i) di=sgn(zi),表示当前剩余角度的方向。
  • θ i = tan ⁡ − 1 ( 2 − i ) \theta_i = \tan^{-1}(2^{-i}) θi=tan1(2i) 是预定义的角度序列。

经过多次迭代后,最终可以得到旋转后的坐标 ( x ′ , y ′ ) (x', y') (x,y) 和剩余角度 z ′ z' z

图:CORDIC算法的基本几何原理。


2.4.2 方法论与分类体系

CORDIC算法可以根据不同的应用场景分为三种主要模式:旋转模式、矢量模式和线性模式。

旋转模式

在CORDIC算法的旋转模式下,目标是将一个初始向量 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 绕原点旋转到目标角度 z 0 z_0 z0。这种模式广泛应用于需要频繁进行旋转操作的场景,例如信号处理中的调制解调、图像处理中的几何变换以及导航系统中的姿态计算等。为了实现这一目标,CORDIC算法通过一系列简单的迭代步骤逐步逼近目标角度。

具体来说,旋转模式的核心思想是将复杂的旋转操作分解为一系列小角度的旋转。这些小角度 θ i \theta_i θi 满足 tan ⁡ − 1 ( 2 − i ) = θ i \tan^{-1}(2^{-i}) = \theta_i tan1(2i)=θi,其中 i = 0 , 1 , 2 , … i = 0, 1, 2, \dots i=0,1,2, 是迭代次数。每次迭代中,算法根据当前剩余角度的方向调整旋转方向,并通过移位和加法操作完成一次近似旋转。最终,经过多次迭代后,输入向量会逐渐逼近目标旋转角度。


  • 迭代公式

公式总结如下:

x i + 1 = x i − d i ⋅ y i ⋅ 2 − i x_{i+1} = x_i - d_i \cdot y_i \cdot 2^{-i} xi+1=xidiyi2i

y i + 1 = y i + d i ⋅ x i ⋅ 2 − i y_{i+1} = y_i + d_i \cdot x_i \cdot 2^{-i} yi+1=yi+dixi2i

z i + 1 = z i − d i ⋅ θ i z_{i+1} = z_i - d_i \cdot \theta_i zi+1=zidiθi

这里, d i = sgn ( z i ) d_i = \text{sgn}(z_i) di=sgn(zi) 表示当前剩余角度的方向(正或负), θ i = tan ⁡ − 1 ( 2 − i ) \theta_i = \tan^{-1}(2^{-i}) θi=tan1(2i) 是预定义的小角度序列。每次迭代中, x i x_i xi y i y_i yi 分别表示向量的横纵坐标,而 z i z_i zi 表示当前剩余的角度偏差。通过不断更新这三个变量,算法逐步逼近目标状态。


  • 示例

例如,在 CORDIC 算法的旋转模式下,我们将初始向量 ( x 0 , y 0 ) = ( 1 , 0 ) (x_0, y_0) = (1, 0) (x0,y0)=(1,0) 绕原点旋转到目标角度 z 0 = π 3 z_0 = \frac{\pi}{3} z0=3π(即 60 度)。为了完整展示 CORDIC 的计算过程,我们将逐步进行多次迭代,直到逼近目标角度。


初始条件

首先,我们需要初始化变量:

  • x 0 = 1 x_0 = 1 x0=1
  • y 0 = 0 y_0 = 0 y0=0
  • z 0 = π 3 ≈ 1.0472 z_0 = \frac{\pi}{3} \approx 1.0472 z0=3π1.0472 (以弧度为单位)

预先计算出小角度序列 θ i \theta_i θi

  • θ 0 = tan ⁡ − 1 ( 1 ) = π 4 ≈ 0.7854 \theta_0 = \tan^{-1}(1) = \frac{\pi}{4} \approx 0.7854 θ0=tan1(1)=4π0.7854
  • θ 1 = tan ⁡ − 1 ( 0.5 ) ≈ 0.4636 \theta_1 = \tan^{-1}(0.5) \approx 0.4636 θ1=tan1(0.5)0.4636
  • θ 2 = tan ⁡ − 1 ( 0.25 ) ≈ 0.245 \theta_2 = \tan^{-1}(0.25) \approx 0.245 θ2=tan1(0.25)0.245
  • θ 3 = tan ⁡ − 1 ( 0.125 ) ≈ 0.1244 \theta_3 = \tan^{-1}(0.125) \approx 0.1244 θ3=tan1(0.125)0.1244
  • θ 4 = tan ⁡ − 1 ( 0.0625 ) ≈ 0.0624 \theta_4 = \tan^{-1}(0.0625) \approx 0.0624 θ4=tan1(0.0625)0.0624

第一次迭代 ( i = 0 i = 0 i=0)

计算方向 d 0 d_0 d0 和小角度 θ 0 \theta_0 θ0

  • d 0 = sgn ( z 0 ) = sgn ( 1.0472 ) = 1 d_0 = \text{sgn}(z_0) = \text{sgn}(1.0472) = 1 d0=sgn(z0)=sgn(1.0472)=1
  • θ 0 = 0.7854 \theta_0 = 0.7854 θ0=0.7854

代入公式计算新的坐标和剩余角度:
x 1 = x 0 − d 0 ⋅ y 0 ⋅ 2 0 = 1 − 1 ⋅ 0 ⋅ 1 = 1 x_1 = x_0 - d_0 \cdot y_0 \cdot 2^0 = 1 - 1 \cdot 0 \cdot 1 = 1 x1=x0d0y020=1101=1

y 1 = y 0 + d 0 ⋅ x 0 ⋅ 2 0 = 0 + 1 ⋅ 1 ⋅ 1 = 1 y_1 = y_0 + d_0 \cdot x_0 \cdot 2^0 = 0 + 1 \cdot 1 \cdot 1 = 1 y1=y0+d0x020=0+111=1

z 1 = z 0 − d 0 ⋅ θ 0 = 1.0472 − 1 ⋅ 0.7854 = 0.2618 z_1 = z_0 - d_0 \cdot \theta_0 = 1.0472 - 1 \cdot 0.7854 = 0.2618 z1=z0d0θ0=1.047210.7854=0.2618

经过第一次迭代后:

  • x 1 = 1 x_1 = 1 x1=1
  • y 1 = 1 y_1 = 1 y1=1
  • z 1 = 0.2618 z_1 = 0.2618 z1=0.2618

第二次迭代 ( i = 1 i = 1 i=1)

计算方向 d 1 d_1 d1 和小角度 θ 1 \theta_1 θ1

  • d 1 = sgn ( z 1 ) = sgn ( 0.2618 ) = 1 d_1 = \text{sgn}(z_1) = \text{sgn}(0.2618) = 1 d1=sgn(z1)=sgn(0.2618)=1
  • θ 1 = 0.4636 \theta_1 = 0.4636 θ1=0.4636

代入公式计算新的坐标和剩余角度:
x 2 = x 1 − d 1 ⋅ y 1 ⋅ 2 − 1 = 1 − 1 ⋅ 1 ⋅ 0.5 = 0.5 x_2 = x_1 - d_1 \cdot y_1 \cdot 2^{-1} = 1 - 1 \cdot 1 \cdot 0.5 = 0.5 x2=x1d1y121=1110.5=0.5

y 2 = y 1 + d 1 ⋅ x 1 ⋅ 2 − 1 = 1 + 1 ⋅ 1 ⋅ 0.5 = 1.5 y_2 = y_1 + d_1 \cdot x_1 \cdot 2^{-1} = 1 + 1 \cdot 1 \cdot 0.5 = 1.5 y2=y1+d1x121=1+110.5=1.5

z 2 = z 1 − d 1 ⋅ θ 1 = 0.2618 − 1 ⋅ 0.4636 = − 0.2018 z_2 = z_1 - d_1 \cdot \theta_1 = 0.2618 - 1 \cdot 0.4636 = -0.2018 z2=z1d1θ1=0.261810.4636=0.2018

经过第二次迭代后:

  • x 2 = 0.5 x_2 = 0.5 x2=0.5
  • y 2 = 1.5 y_2 = 1.5 y2=1.5
  • z 2 = − 0.2018 z_2 = -0.2018 z2=0.2018

第三次迭代 ( i = 2 i = 2 i=2)

计算方向 d 2 d_2 d2 和小角度 θ 2 \theta_2 θ2

  • d 2 = sgn ( z 2 ) = sgn ( − 0.2018 ) = − 1 d_2 = \text{sgn}(z_2) = \text{sgn}(-0.2018) = -1 d2=sgn(z2)=sgn(0.2018)=1
  • θ 2 = 0.245 \theta_2 = 0.245 θ2=0.245

代入公式计算新的坐标和剩余角度:
x 3 = x 2 − d 2 ⋅ y 2 ⋅ 2 − 2 = 0.5 − ( − 1 ) ⋅ 1.5 ⋅ 0.25 = 0.875 x_3 = x_2 - d_2 \cdot y_2 \cdot 2^{-2} = 0.5 - (-1) \cdot 1.5 \cdot 0.25 = 0.875 x3=x2d2y222=0.5(1)1.50.25=0.875

y 3 = y 2 + d 2 ⋅ x 2 ⋅ 2 − 2 = 1.5 + ( − 1 ) ⋅ 0.5 ⋅ 0.25 = 1.375 y_3 = y_2 + d_2 \cdot x_2 \cdot 2^{-2} = 1.5 + (-1) \cdot 0.5 \cdot 0.25 = 1.375 y3=y2+d2x222=1.5+(1)0.50.25=1.375

z 3 = z 2 − d 2 ⋅ θ 2 = − 0.2018 − ( − 1 ) ⋅ 0.245 = 0.0432 z_3 = z_2 - d_2 \cdot \theta_2 = -0.2018 - (-1) \cdot 0.245 = 0.0432 z3=z2d2θ2=0.2018(1)0.245=0.0432

经过第三次迭代后:

  • x 3 = 0.875 x_3 = 0.875 x3=0.875
  • y 3 = 1.375 y_3 = 1.375 y3=1.375
  • z 3 = 0.0432 z_3 = 0.0432 z3=0.0432

第四次迭代 ( i = 3 i = 3 i=3)

计算方向 d 3 d_3 d3 和小角度 θ 3 \theta_3 θ3

  • d 3 = sgn ( z 3 ) = sgn ( 0.0432 ) = 1 d_3 = \text{sgn}(z_3) = \text{sgn}(0.0432) = 1 d3=sgn(z3)=sgn(0.0432)=1
  • θ 3 = 0.1244 \theta_3 = 0.1244 θ3=0.1244

代入公式计算新的坐标和剩余角度:
x 4 = x 3 − d 3 ⋅ y 3 ⋅ 2 − 3 = 0.875 − 1 ⋅ 1.375 ⋅ 0.125 = 0.7219 x_4 = x_3 - d_3 \cdot y_3 \cdot 2^{-3} = 0.875 - 1 \cdot 1.375 \cdot 0.125 = 0.7219 x4=x3d3y323=0.87511.3750.125=0.7219

y 4 = y 3 + d 3 ⋅ x 3 ⋅ 2 − 3 = 1.375 + 1 ⋅ 0.875 ⋅ 0.125 = 1.4844 y_4 = y_3 + d_3 \cdot x_3 \cdot 2^{-3} = 1.375 + 1 \cdot 0.875 \cdot 0.125 = 1.4844 y4=y3+d3x323=1.375+10.8750.125=1.4844

z 4 = z 3 − d 3 ⋅ θ 3 = 0.0432 − 1 ⋅ 0.1244 = − 0.0812 z_4 = z_3 - d_3 \cdot \theta_3 = 0.0432 - 1 \cdot 0.1244 = -0.0812 z4=z3d3θ3=0.043210.1244=0.0812

经过第四次迭代后:

  • x 4 = 0.7219 x_4 = 0.7219 x4=0.7219
  • y 4 = 1.4844 y_4 = 1.4844 y4=1.4844
  • z 4 = − 0.0812 z_4 = -0.0812 z4=0.0812

第五次迭代 ( i = 4 i = 4 i=4)

计算方向 d 4 d_4 d4 和小角度 θ 4 \theta_4 θ4

  • d 4 = sgn ( z 4 ) = sgn ( − 0.0812 ) = − 1 d_4 = \text{sgn}(z_4) = \text{sgn}(-0.0812) = -1 d4=sgn(z4)=sgn(0.0812)=1
  • θ 4 = 0.0624 \theta_4 = 0.0624 θ4=0.0624

代入公式计算新的坐标和剩余角度:
x 5 = x 4 − d 4 ⋅ y 4 ⋅ 2 − 4 = 0.7219 − ( − 1 ) ⋅ 1.4844 ⋅ 0.0625 = 0.8012 x_5 = x_4 - d_4 \cdot y_4 \cdot 2^{-4} = 0.7219 - (-1) \cdot 1.4844 \cdot 0.0625 = 0.8012 x5=x4d4y424=0.7219(1)1.48440.0625=0.8012

y 5 = y 4 + d 4 ⋅ x 4 ⋅ 2 − 4 = 1.4844 + ( − 1 ) ⋅ 0.7219 ⋅ 0.0625 = 1.4451 y_5 = y_4 + d_4 \cdot x_4 \cdot 2^{-4} = 1.4844 + (-1) \cdot 0.7219 \cdot 0.0625 = 1.4451 y5=y4+d4x424=1.4844+(1)0.72190.0625=1.4451

z 5 = z 4 − d 4 ⋅ θ 4 = − 0.0812 − ( − 1 ) ⋅ 0.0624 = − 0.0188 z_5 = z_4 - d_4 \cdot \theta_4 = -0.0812 - (-1) \cdot 0.0624 = -0.0188 z5=z4d4θ4=0.0812(1)0.0624=0.0188

经过第五次迭代后:

  • x 5 = 0.8012 x_5 = 0.8012 x5=0.8012
  • y 5 = 1.4451 y_5 = 1.4451 y5=1.4451
  • z 5 = − 0.0188 z_5 = -0.0188 z5=0.0188

总结

通过五次迭代,初始向量 ( x 0 , y 0 ) = ( 1 , 0 ) (x_0, y_0) = (1, 0) (x0,y0)=(1,0) 已经被旋转到接近目标角度 π 3 \frac{\pi}{3} 3π。最终结果为:

  • x 5 ≈ 0.8012 x_5 \approx 0.8012 x50.8012
  • y 5 ≈ 1.4451 y_5 \approx 1.4451 y51.4451
  • z 5 ≈ − 0.0188 z_5 \approx -0.0188 z50.0188 (剩余角度非常接近零)

CORDIC 算法通过简单的移位和加法操作逐步逼近目标角度,非常适合硬件实现,尤其在嵌入式系统中具有广泛应用。

需要注意的是,CORDIC算法在旋转模式下的应用可以分为不同的分类体系。例如,根据输入数据的类型,可以将其分为浮点数实现和定点数实现;根据硬件架构的不同,又可以分为串行实现和并行实现等。这些分类方式为实际应用提供了灵活性,同时也带来了性能和资源消耗之间的权衡问题。

CORDIC算法详解(一)- CORDIC 算法之圆周系统之旋转模式( Rotation Mode )_cordic旋转迭代算法-CSDN博客

图:旋转模式迭代次数与角度。

矢量模式

在 CORDIC 算法的矢量模式下,目标是计算一个给定向量 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 的模长 r r r 和方向角 θ \theta θ。这种模式适用于需要快速计算向量极坐标表示的场景,例如信号处理中的相位检测、雷达系统中的目标定位等。为了实现这一目标,CORDIC 算法通过一系列简单的迭代操作逐步逼近向量的方向角,并利用归一化常数补偿每次迭代引入的缩放效应。

具体来说,矢量模式的核心思想是将初始向量逐步旋转到 y = 0 y = 0 y=0 的轴线上,从而使得最终的 x N x_N xN 值等于向量的模长(经过归一化后)。同时,在每次迭代中记录旋转的角度变化,最终得到向量的方向角 θ \theta θ。以下是详细的公式推导和计算步骤。


  • 核心迭代公式

首先,矢量模式的核心迭代公式如下:
x i + 1 = x i − d i ⋅ y i ⋅ 2 − i x_{i+1} = x_i - d_i \cdot y_i \cdot 2^{-i} xi+1=xidiyi2i

y i + 1 = y i + d i ⋅ x i ⋅ 2 − i y_{i+1} = y_i + d_i \cdot x_i \cdot 2^{-i} yi+1=yi+dixi2i

z i + 1 = z i + d i ⋅ θ i z_{i+1} = z_i + d_i \cdot \theta_i zi+1=zi+diθi

这里:

  • d i = sgn ( y i ) d_i = \text{sgn}(y_i) di=sgn(yi) 表示当前剩余角度的方向(正或负),用于决定旋转的方向。
  • θ i = tan ⁡ − 1 ( 2 − i ) \theta_i = \tan^{-1}(2^{-i}) θi=tan1(2i) 是预定义的小角度序列。

每次迭代中,算法会根据当前 y i y_i yi 的符号调整旋转方向,使向量逐渐靠近 y = 0 y = 0 y=0 的轴线。同时,记录每次旋转的角度变化,累加到 z i z_i zi 中,最终得到方向角 θ = z N \theta = z_N θ=zN


  • 归一化常数K

接下来,我们详细分析如何计算向量的模长 r r r 和方向角 θ \theta θ。假设初始向量为 ( x 0 , y 0 ) (x_0, y_0) (x0,y0),目标是计算其模长和方向角。由于每次迭代都会引入一定的缩放效应,因此最终的模长需要乘以一个归一化常数 K K K,该常数由所有迭代的缩放因子累积得到。具体地,归一化常数 K K K 定义为:
K = ∏ i = 0 N − 1 1 + 2 − 2 i K = \prod_{i=0}^{N-1} \sqrt{1 + 2^{-2i}} K=i=0N11+22i

对于有限次迭代 N N N K K K 的值可以通过预先计算并存储来简化实际应用中的复杂度。


  • 示例:计算模长和方向角

假设我们有一个初始向量 ( x 0 , y 0 ) = ( 3 , 4 ) (x_0, y_0) = (3, 4) (x0,y0)=(3,4),目标是使用 CORDIC 矢量模式计算其模长和方向角。我们将进行多次迭代,直到达到所需的精度。

(1)第一次迭代 ( i = 0 i = 0 i=0)

初始条件为:

  • x 0 = 3 x_0 = 3 x0=3
  • y 0 = 4 y_0 = 4 y0=4
  • z 0 = 0 z_0 = 0 z0=0

计算方向 d 0 d_0 d0 和小角度 θ 0 \theta_0 θ0

  • d 0 = sgn ( y 0 ) = sgn ( 4 ) = 1 d_0 = \text{sgn}(y_0) = \text{sgn}(4) = 1 d0=sgn(y0)=sgn(4)=1
  • θ 0 = tan ⁡ − 1 ( 1 ) = π 4 ≈ 0.7854 \theta_0 = \tan^{-1}(1) = \frac{\pi}{4} \approx 0.7854 θ0=tan1(1)=4π0.7854

代入公式计算新的坐标和角度:
x 1 = x 0 − d 0 ⋅ y 0 ⋅ 2 0 = 3 − 1 ⋅ 4 ⋅ 1 = − 1 x_1 = x_0 - d_0 \cdot y_0 \cdot 2^0 = 3 - 1 \cdot 4 \cdot 1 = -1 x1=x0d0y020=3141=1

y 1 = y 0 + d 0 ⋅ x 0 ⋅ 2 0 = 4 + 1 ⋅ 3 ⋅ 1 = 7 y_1 = y_0 + d_0 \cdot x_0 \cdot 2^0 = 4 + 1 \cdot 3 \cdot 1 = 7 y1=y0+d0x020=4+131=7

z 1 = z 0 + d 0 ⋅ θ 0 = 0 + 1 ⋅ 0.7854 = 0.7854 z_1 = z_0 + d_0 \cdot \theta_0 = 0 + 1 \cdot 0.7854 = 0.7854 z1=z0+d0θ0=0+10.7854=0.7854

(2)第二次迭代 ( i = 1 i = 1 i=1)

当前状态为:

  • x 1 = − 1 x_1 = -1 x1=1
  • y 1 = 7 y_1 = 7 y1=7
  • z 1 = 0.7854 z_1 = 0.7854 z1=0.7854

计算方向 d 1 d_1 d1 和小角度 θ 1 \theta_1 θ1

  • d 1 = sgn ( y 1 ) = sgn ( 7 ) = 1 d_1 = \text{sgn}(y_1) = \text{sgn}(7) = 1 d1=sgn(y1)=sgn(7)=1
  • θ 1 = tan ⁡ − 1 ( 0.5 ) ≈ 0.4636 \theta_1 = \tan^{-1}(0.5) \approx 0.4636 θ1=tan1(0.5)0.4636

代入公式计算新的坐标和角度:
x 2 = x 1 − d 1 ⋅ y 1 ⋅ 2 − 1 = − 1 − 1 ⋅ 7 ⋅ 0.5 = − 4.5 x_2 = x_1 - d_1 \cdot y_1 \cdot 2^{-1} = -1 - 1 \cdot 7 \cdot 0.5 = -4.5 x2=x1d1y121=1170.5=4.5

y 2 = y 1 + d 1 ⋅ x 1 ⋅ 2 − 1 = 7 + 1 ⋅ ( − 1 ) ⋅ 0.5 = 6.5 y_2 = y_1 + d_1 \cdot x_1 \cdot 2^{-1} = 7 + 1 \cdot (-1) \cdot 0.5 = 6.5 y2=y1+d1x121=7+1(1)0.5=6.5

z 2 = z 1 + d 1 ⋅ θ 1 = 0.7854 + 1 ⋅ 0.4636 = 1.249 z_2 = z_1 + d_1 \cdot \theta_1 = 0.7854 + 1 \cdot 0.4636 = 1.249 z2=z1+d1θ1=0.7854+10.4636=1.249

(3)第三次迭代 ( i = 2 i = 2 i=2)

当前状态为:

  • x 2 = − 4.5 x_2 = -4.5 x2=4.5
  • y 2 = 6.5 y_2 = 6.5 y2=6.5
  • z 2 = 1.249 z_2 = 1.249 z2=1.249

计算方向 d 2 d_2 d2 和小角度 θ 2 \theta_2 θ2

  • d 2 = sgn ( y 2 ) = sgn ( 6.5 ) = 1 d_2 = \text{sgn}(y_2) = \text{sgn}(6.5) = 1 d2=sgn(y2)=sgn(6.5)=1
  • θ 2 = tan ⁡ − 1 ( 0.25 ) ≈ 0.245 \theta_2 = \tan^{-1}(0.25) \approx 0.245 θ2=tan1(0.25)0.245

代入公式计算新的坐标和角度:
x 3 = x 2 − d 2 ⋅ y 2 ⋅ 2 − 2 = − 4.5 − 1 ⋅ 6.5 ⋅ 0.25 = − 5.725 x_3 = x_2 - d_2 \cdot y_2 \cdot 2^{-2} = -4.5 - 1 \cdot 6.5 \cdot 0.25 = -5.725 x3=x2d2y222=4.516.50.25=5.725

y 3 = y 2 + d 2 ⋅ x 2 ⋅ 2 − 2 = 6.5 + 1 ⋅ ( − 4.5 ) ⋅ 0.25 = 5.375 y_3 = y_2 + d_2 \cdot x_2 \cdot 2^{-2} = 6.5 + 1 \cdot (-4.5) \cdot 0.25 = 5.375 y3=y2+d2x222=6.5+1(4.5)0.25=5.375

z 3 = z 2 + d 2 ⋅ θ 2 = 1.249 + 1 ⋅ 0.245 = 1.494 z_3 = z_2 + d_2 \cdot \theta_2 = 1.249 + 1 \cdot 0.245 = 1.494 z3=z2+d2θ2=1.249+10.245=1.494

(4)最终结果

经过多次迭代后,我们可以得到:

  • 模长 r = K ⋅ x N r = K \cdot x_N r=KxN,其中 K ≈ 0.60725 K \approx 0.60725 K0.60725(对于 N = 10 N = 10 N=10)。
  • 方向角 θ = z N \theta = z_N θ=zN

对于本例,最终结果为:
r = 0.60725 ⋅ ∣ x N ∣ ≈ 0.60725 ⋅ ∣ − 5.725 ∣ ≈ 3.47 r = 0.60725 \cdot |x_N| \approx 0.60725 \cdot |-5.725| \approx 3.47 r=0.60725xN0.607255.725∣3.47

θ = z N ≈ 1.494 弧度 ≈ 85. 6 ∘ \theta = z_N \approx 1.494 \, \text{弧度} \approx 85.6^\circ θ=zN1.494弧度85.6


  • 分类与应用场景

CORDIC 矢量模式可以根据实现方式分为以下几类:

  1. 浮点数实现:适用于高精度需求的场景,但硬件资源消耗较大。
  2. 定点数实现:适合嵌入式系统,具有较低的硬件开销。
  3. 串行实现:逐次完成每次迭代,适用于低功耗设备。
  4. 并行实现:同时进行多次迭代,提高计算速度,但硬件复杂度较高。

CORDIC 矢量模式广泛应用于信号处理、导航系统和图像处理等领域,尤其在需要实时计算向量模长和方向角的应用中表现出色。

简述:CORDIC的基本原理与应用 - OFweek工控网

图:矢量模式的工作原理。

线性模式

CORDIC 算法的线性模式是一种用于计算非线性函数(如双曲函数、对数和指数函数)的有效方法。与旋转模式和矢量模式不同,线性模式通过一系列简单的线性操作将复杂的非线性问题转化为易于实现的迭代过程。这种模式的核心思想是利用 CORDIC 的基本原理,在每次迭代中通过移位和加法操作逐步逼近目标值。

在线性模式下,输入通常是一个初始值 x 0 x_0 x0 和辅助变量 y 0 y_0 y0,输出则是经过一系列迭代后得到的目标值。例如,当计算对数或指数函数时,线性模式可以通过调整输入变量逐步逼近目标函数值。以下是线性模式的基本公式:

x i + 1 = x i − d i ⋅ y i ⋅ 2 − i x_{i+1} = x_i - d_i \cdot y_i \cdot 2^{-i} xi+1=xidiyi2i

y i + 1 = y i + d i ⋅ x i ⋅ A ⋅ 2 − i y_{i+1} = y_i + d_i \cdot x_i \cdot A \cdot 2^{-i} yi+1=yi+dixiA2i

其中:

  • d i = sgn ( y i ) d_i = \text{sgn}(y_i) di=sgn(yi) 表示当前剩余误差的方向。
  • A A A 是一个常数,取决于具体的应用场景(例如,对于对数函数, A = ln ⁡ ( 2 ) A = \ln(2) A=ln(2);对于指数函数, A = 1 / ln ⁡ ( 2 ) A = 1/\ln(2) A=1/ln(2))。

  • 示例:计算自然对数 ln ⁡ ( x ) \ln(x) ln(x)

假设我们需要计算 ln ⁡ ( 1.5 ) \ln(1.5) ln(1.5),并使用 CORDIC 线性模式逐步逼近结果。我们将初始值 y 0 y_0 y0 设置为 − 0.1 -0.1 0.1,以展示其对计算过程的影响。

初始条件

  • x 0 = 1.5 − 1 = 0.5 x_0 = 1.5 - 1 = 0.5 x0=1.51=0.5 (将输入标准化为 x = 1 + f x = 1 + f x=1+f 的形式)

  • y 0 = − 0.1 y_0 = -0.1 y0=0.1

  • A = ln ⁡ ( 2 ) ≈ 0.693 A = \ln(2) \approx 0.693 A=ln(2)0.693 是一个常数,用于线性模式下的对数计算。


(1)第一次迭代 ( i = 0 i = 0 i=0)

计算方向 d 0 d_0 d0

由于 y 0 = − 0.1 < 0 y_0 = -0.1 < 0 y0=0.1<0,因此:
d 0 = sgn ( y 0 ) = − 1 d_0 = \text{sgn}(y_0) = -1 d0=sgn(y0)=1

更新 x 1 x_1 x1 y 1 y_1 y1

代入公式计算:
x 1 = x 0 − d 0 ⋅ y 0 ⋅ 2 0 = 0.5 − ( − 1 ) ⋅ ( − 0.1 ) ⋅ 1 = 0.5 − 0.1 = 0.4 x_1 = x_0 - d_0 \cdot y_0 \cdot 2^0 = 0.5 - (-1) \cdot (-0.1) \cdot 1 = 0.5 - 0.1 = 0.4 x1=x0d0y020=0.5(1)(0.1)1=0.50.1=0.4

y 1 = y 0 + d 0 ⋅ x 0 ⋅ A ⋅ 2 0 = − 0.1 + ( − 1 ) ⋅ 0.5 ⋅ 0.693 ⋅ 1 = − 0.1 − 0.3465 = − 0.4465 y_1 = y_0 + d_0 \cdot x_0 \cdot A \cdot 2^0 = -0.1 + (-1) \cdot 0.5 \cdot 0.693 \cdot 1 = -0.1 - 0.3465 = -0.4465 y1=y0+d0x0A20=0.1+(1)0.50.6931=0.10.3465=0.4465


(2)第二次迭代 ( i = 1 i = 1 i=1)

计算方向 d 1 d_1 d1

由于 y 1 = − 0.4465 < 0 y_1 = -0.4465 < 0 y1=0.4465<0,因此:
d 1 = sgn ( y 1 ) = − 1 d_1 = \text{sgn}(y_1) = -1 d1=sgn(y1)=1

更新 x 2 x_2 x2 y 2 y_2 y2

代入公式计算:
x 2 = x 1 − d 1 ⋅ y 1 ⋅ 2 − 1 = 0.4 − ( − 1 ) ⋅ ( − 0.4465 ) ⋅ 0.5 = 0.4 − 0.22325 = 0.17675 x_2 = x_1 - d_1 \cdot y_1 \cdot 2^{-1} = 0.4 - (-1) \cdot (-0.4465) \cdot 0.5 = 0.4 - 0.22325 = 0.17675 x2=x1d1y121=0.4(1)(0.4465)0.5=0.40.22325=0.17675

y 2 = y 1 + d 1 ⋅ x 1 ⋅ A ⋅ 2 − 1 = − 0.4465 + ( − 1 ) ⋅ 0.4 ⋅ 0.693 ⋅ 0.5 = − 0.4465 − 0.1386 = − 0.5851 y_2 = y_1 + d_1 \cdot x_1 \cdot A \cdot 2^{-1} = -0.4465 + (-1) \cdot 0.4 \cdot 0.693 \cdot 0.5 = -0.4465 - 0.1386 = -0.5851 y2=y1+d1x1A21=0.4465+(1)0.40.6930.5=0.44650.1386=0.5851


(3)第三次迭代 ( i = 2 i = 2 i=2)

计算方向 d 2 d_2 d2

由于 y 2 = − 0.5851 < 0 y_2 = -0.5851 < 0 y2=0.5851<0,因此:
d 2 = sgn ( y 2 ) = − 1 d_2 = \text{sgn}(y_2) = -1 d2=sgn(y2)=1

更新 x 3 x_3 x3 y 3 y_3 y3

代入公式计算:
x 3 = x 2 − d 2 ⋅ y 2 ⋅ 2 − 2 = 0.17675 − ( − 1 ) ⋅ ( − 0.5851 ) ⋅ 0.25 = 0.17675 − 0.146275 = 0.030475 x_3 = x_2 - d_2 \cdot y_2 \cdot 2^{-2} = 0.17675 - (-1) \cdot (-0.5851) \cdot 0.25 = 0.17675 - 0.146275 = 0.030475 x3=x2d2y222=0.17675(1)(0.5851)0.25=0.176750.146275=0.030475

y 3 = y 2 + d 2 ⋅ x 2 ⋅ A ⋅ 2 − 2 = − 0.5851 + ( − 1 ) ⋅ 0.17675 ⋅ 0.693 ⋅ 0.25 = − 0.5851 − 0.03123 = − 0.61633 y_3 = y_2 + d_2 \cdot x_2 \cdot A \cdot 2^{-2} = -0.5851 + (-1) \cdot 0.17675 \cdot 0.693 \cdot 0.25 = -0.5851 - 0.03123 = -0.61633 y3=y2+d2x2A22=0.5851+(1)0.176750.6930.25=0.58510.03123=0.61633


(4)迭代收敛

随着迭代次数增加, x i x_i xi 将逐渐接近零,而 y i y_i yi 则逐步逼近 ln ⁡ ( 1.5 ) \ln(1.5) ln(1.5)。最终结果为:
ln ⁡ ( 1.5 ) ≈ y N \ln(1.5) \approx y_N ln(1.5)yN

在实际应用中,通常需要进行更多次迭代以达到更高的精度。例如,经过 10 次迭代后,结果可以精确到小数点后 4 位。


总结

通过上述计算过程,我们可以看到,即使初始值 y 0 ≠ 0 y_0 \neq 0 y0=0,CORDIC 线性模式仍然可以通过简单的移位和加法操作逐步逼近目标值。初始值 y 0 y_0 y0 的选择不会影响最终结果的正确性,但它会影响每次迭代的具体路径。这种方法不仅高效,而且非常适合硬件实现,尤其在嵌入式系统中具有广泛应用。


  • 分类与应用场景

CORDIC 线性模式可以根据应用需求分为以下几类:

  1. 定点数实现:适用于嵌入式系统,具有较低的硬件开销。
  2. 浮点数实现:适用于高精度需求的场景,但硬件资源消耗较大。
  3. 对数与指数计算:通过调整常数 A A A,可以灵活计算各种对数和指数函数。
  4. 双曲函数计算:例如 sinh ⁡ ( x ) \sinh(x) sinh(x) cosh ⁡ ( x ) \cosh(x) cosh(x),可以通过类似的方法实现。

总之,线性模式通过简单高效的迭代操作,为复杂非线性函数的计算提供了强大的工具。

2.4.3 CORDIC 算法中的误差来源

在 CORDIC 算法中,确定迭代次数 N N N 是一个关键问题,因为它直接影响计算的精度和硬件资源消耗。为了确保结果满足所需的精度要求,同时避免过多的迭代导致效率降低或资源浪费,我们需要根据具体的应用场景和误差容忍度来选择合适的迭代次数。以下是详细的分析和方法,帮助我们确定 CORDIC 算法的迭代次数 N N N

在 CORDIC 算法中,误差主要来源于以下两个方面:

  • 角度逼近误差:每次迭代只能旋转一个小角度 θ i = tan ⁡ − 1 ( 2 − i ) \theta_i = \tan^{-1}(2^{-i}) θi=tan1(2i),因此需要多次迭代才能逼近目标角度。
  • 缩放效应误差:每次迭代都会引入一定的缩放因子,累积后会导致最终结果偏离真实值。这种误差可以通过归一化常数 K K K 来补偿,但在定点数实现中可能会有额外的量化误差。

为了保证计算结果的精度,我们需要控制这两种误差在可接受范围内。


角度逼近误差的分析

假设目标角度为 θ \theta θ,通过 CORDIC 算法进行 N N N 次迭代后,剩余的角度误差可以表示为:

Δ z N = ∣ θ − ∑ i = 0 N − 1 d i ⋅ θ i ∣ \Delta z_N = \left| \theta - \sum_{i=0}^{N-1} d_i \cdot \theta_i \right| ΔzN= θi=0N1diθi

其中:

  • θ i = tan ⁡ − 1 ( 2 − i ) \theta_i = \tan^{-1}(2^{-i}) θi=tan1(2i) 是第 i i i 次迭代的小角度。
  • d i = ± 1 d_i = \pm 1 di=±1 表示旋转方向。

随着迭代次数 N N N 的增加, Δ z N \Delta z_N ΔzN 会逐渐减小。通常情况下, θ i \theta_i θi 的值随 i i i 增加而迅速减小,因此后续迭代对结果的影响较小。经验表明,对于大多数应用场景,当 N ≥ 16 N \geq 16 N16 时,角度逼近误差已经足够小(小于 1 0 − 4 10^{-4} 104 弧度)。


缩放效应误差的分析

每次迭代都会引入一个缩放因子 1 + 2 − 2 i \sqrt{1 + 2^{-2i}} 1+22i ,所有迭代的累积缩放因子为:

K = ∏ i = 0 N − 1 1 + 2 − 2 i K = \prod_{i=0}^{N-1} \sqrt{1 + 2^{-2i}} K=i=0N11+22i

理论上, K K K 的值会随着 N N N 的增加逐渐接近其极限值。例如:

  • N = 10 N = 10 N=10 时, K ≈ 1.64676 K \approx 1.64676 K1.64676
  • N = 16 N = 16 N=16 时, K ≈ 1.64686 K \approx 1.64686 K1.64686

可以看到, K K K 的变化非常缓慢,因此即使增加迭代次数,缩放效应误差的变化也较小。在实际应用中,通常会预先计算 K K K 的值并存储,从而避免动态计算带来的额外开销。


精度需求与迭代次数的关系

确定迭代次数 N N N 的关键是根据精度需求设定一个误差容忍度 ϵ \epsilon ϵ。假设目标是使最终结果的误差小于 ϵ \epsilon ϵ,则可以通过以下步骤估算 N N N

(1) 角度逼近误差的容忍度

角度逼近误差 Δ z N \Delta z_N ΔzN 随着 N N N 的增加呈指数级减小。经验公式为:

Δ z N ≈ 2 − N \Delta z_N \approx 2^{-N} ΔzN2N

如果要求角度误差小于 ϵ θ \epsilon_\theta ϵθ,则可以通过以下公式估算 N N N

N ≥ log ⁡ 2 ( 1 ϵ θ ) N \geq \log_2\left(\frac{1}{\epsilon_\theta}\right) Nlog2(ϵθ1)

例如,如果要求角度误差小于 1 0 − 4 10^{-4} 104 弧度,则:

N ≥ log ⁡ 2 ( 1 0 4 ) ≈ 14 N \geq \log_2(10^4) \approx 14 Nlog2(104)14

(2) 模长计算的精度需求

对于矢量模式,最终的模长 r = K ⋅ x N r = K \cdot x_N r=KxN 的精度取决于 x N x_N xN 的精度。假设输入向量的初始模长为 r 0 r_0 r0,则经过 N N N 次迭代后,模长的相对误差可以表示为:

Relative Error ≈ Δ r r 0 ≈ 2 − N \text{Relative Error} \approx \frac{\Delta r}{r_0} \approx 2^{-N} Relative Errorr0Δr2N

如果要求模长的相对误差小于 ϵ r \epsilon_r ϵr,则可以通过以下公式估算 N N N

N ≥ log ⁡ 2 ( 1 ϵ r ) N \geq \log_2\left(\frac{1}{\epsilon_r}\right) Nlog2(ϵr1)

例如,如果要求模长的相对误差小于 1 0 − 4 10^{-4} 104,则:

N ≥ log ⁡ 2 ( 1 0 4 ) ≈ 14 N \geq \log_2(10^4) \approx 14 Nlog2(104)14


常见应用场景下的迭代次数建议

根据实际应用的需求和经验,以下是一些常见的迭代次数建议:

应用场景精度要求推荐迭代次数 N N N
低精度信号处理 ϵ ∼ 1 0 − 2 \epsilon \sim 10^{-2} ϵ102 N ≥ 8 N \geq 8 N8
中等精度导航系统 ϵ ∼ 1 0 − 4 \epsilon \sim 10^{-4} ϵ104 N ≥ 14 N \geq 14 N14
高精度科学计算 ϵ ∼ 1 0 − 6 \epsilon \sim 10^{-6} ϵ106 N ≥ 20 N \geq 20 N20

总结

确定 CORDIC 算法的迭代次数 N N N 需要综合考虑角度逼近误差、缩放效应误差以及具体的精度需求。一般来说, N N N 的选择应满足以下条件:

  1. 角度逼近误差小于指定的容忍度 ϵ θ \epsilon_\theta ϵθ
  2. 模长计算的相对误差小于指定的容忍度 ϵ r \epsilon_r ϵr

通过合理选择 N N N,可以在精度和效率之间找到平衡点。例如,在大多数嵌入式系统中,推荐使用 N = 16 N = 16 N=16 或更高,以确保计算结果的准确性,同时避免过多的迭代带来的资源消耗。

2.4.4优缺点分析

CORDIC算法具有许多显著的优点,但也存在一些局限性。

优点

  1. 高效性:CORDIC算法仅使用加法和移位操作,避免了复杂的乘法和除法运算,非常适合硬件实现。
  2. 通用性:该算法可以应用于多种数学运算,包括三角函数、双曲函数、对数和指数函数等。
  3. 可扩展性:通过增加迭代次数,可以提高计算精度,适应不同的应用场景。

缺点

  1. 收敛速度有限:CORDIC算法的精度依赖于迭代次数,对于高精度需求可能需要较多的迭代步骤。
  2. 范围限制:某些模式下的输入范围受到限制,例如矢量模式要求输入向量的初始角度接近零。
  3. 硬件资源消耗:尽管单次操作简单,但大规模实现仍需占用一定硬件资源。

表:CORDIC算法的优缺点对比

特性优点缺点
计算效率使用加法和移位操作,硬件实现高效收敛速度较慢
应用范围可用于多种数学运算输入范围受限
精度控制通过增加迭代次数可提高精度高精度需求时资源消耗较大

2.4.5 应用方向

CORDIC算法因其高效性和通用性,在多个领域得到了广泛应用。它通过一系列简单的移位和加法操作,能够快速实现复杂的数学运算,如三角函数、对数函数、双曲函数以及矩阵变换等。这种特性使得CORDIC算法在数字信号处理、计算机图形学和嵌入式系统中具有不可替代的地位。


  • 数字信号处理中的应用

在数字信号处理(DSP)领域,CORDIC算法被广泛用于实现正弦波生成、快速傅里叶变换(FFT)和调制解调等功能。例如,在无线通信系统中,载波信号的生成是一个关键步骤,而CORDIC算法可以高效地计算正弦和余弦值。假设我们需要生成一个频率为 f 0 f_0 f0的正弦波信号,可以通过以下公式实现:

x ( t ) = A ⋅ sin ⁡ ( 2 π f 0 t + ϕ ) x(t) = A \cdot \sin(2\pi f_0 t + \phi) x(t)=Asin(2πf0t+ϕ)

其中, A A A是振幅, ϕ \phi ϕ是初始相位。使用CORDIC算法时,我们可以通过旋转模式逐步逼近目标角度 θ = 2 π f 0 t + ϕ \theta = 2\pi f_0 t + \phi θ=2πf0t+ϕ,从而计算出对应的正弦值。这种方法相比于直接使用查表法或泰勒级数展开,不仅节省了存储空间,还降低了计算复杂度。

此外,在快速傅里叶变换(FFT)中,CORDIC算法可用于计算复数乘法中的旋转因子。传统的FFT算法需要大量的复数乘法操作,而CORDIC算法可以通过简单的迭代过程完成这些计算,显著提高了效率。


  • 计算机图形学中的应用

在计算机图形学中,CORDIC算法主要用于加速二维和三维图形的旋转和缩放操作。相比于传统的矩阵乘法方法,CORDIC算法能够显著降低计算复杂度。例如,在二维平面中,将一个点 ( x , y ) (x, y) (x,y)绕原点旋转角度 θ \theta θ,可以通过以下公式表示:

x ′ = x ⋅ cos ⁡ ( θ ) − y ⋅ sin ⁡ ( θ ) x' = x \cdot \cos(\theta) - y \cdot \sin(\theta) x=xcos(θ)ysin(θ)

y ′ = x ⋅ sin ⁡ ( θ ) + y ⋅ cos ⁡ ( θ ) y' = x \cdot \sin(\theta) + y \cdot \cos(\theta) y=xsin(θ)+ycos(θ)

在实际应用中,直接计算 cos ⁡ ( θ ) \cos(\theta) cos(θ) sin ⁡ ( θ ) \sin(\theta) sin(θ)可能需要较高的计算成本。而使用CORDIC算法的旋转模式,可以通过迭代公式逐步逼近目标角度 θ \theta θ,从而避免直接计算三角函数。这种方法特别适合硬件实现,因为它仅涉及移位和加法操作,非常适合嵌入式图形处理器(GPU)的应用场景。


  • 嵌入式系统中的应用

在嵌入式系统中,CORDIC算法常用于实现轻量级的数学运算模块。例如,在无人机导航系统中,实时计算飞行姿态和位置信息是一项重要任务。假设无人机需要计算其当前的姿态角(如俯仰角、滚转角和偏航角),可以使用CORDIC算法的矢量模式来完成。具体来说,假设无人机的姿态由加速度计和陀螺仪提供的原始数据 ( x , y , z ) (x, y, z) (x,y,z)表示,我们可以将其转换为模长 r r r和方向角 θ \theta θ

r = K ⋅ x N r = K \cdot x_N r=KxN

θ = z N \theta = z_N θ=zN

其中, K K K是一个归一化常数,用于补偿每次迭代引入的缩放效应。通过多次迭代,最终可以得到精确的姿态角,从而指导无人机的飞行控制。

此外,在嵌入式系统中,CORDIC算法还可以用于实现其他数学运算,如对数、指数和双曲函数等。这些功能在传感器校准、信号处理和控制系统中具有重要意义。


2.4.6实现细节

在实际应用中,CORDIC算法可以通过软件或硬件两种方式实现。

软件实现

在软件实现中,CORDIC算法通常以循环结构编写,便于移植到各种处理器平台上。以下是一个简单的Python实现示例:

import mathdef cordic_rotation(x, y, z, iterations=10):x, y, z = float(x), float(y), float(z)angle_table = [math.atan(2**-i) for i in range(iterations)]k = 0.6072529350088814  # Normalization factorfor i in range(iterations):d = 1 if z > 0 else -1x_new = x - d * y * 2**-iy_new = y + d * x * 2**-iz_new = z - d * angle_table[i]x, y, z = x_new, y_new, z_newreturn k * x, k * y, zresult = cordic_rotation(1, 0, math.pi / 4, 20)
print("Result:", result)
硬件实现

在硬件实现中,CORDIC算法通常通过FPGA或ASIC设计完成。硬件实现的优势在于速度快、功耗低,但开发成本较高。


2.4.7 总结

CORDIC算法作为一种经典的数值计算方法,凭借其高效性和通用性在多个领域得到了广泛应用。通过本文的详细讲解,我们不仅了解了其基本原理和实现细节,还探讨了其优缺点和具体应用场景。希望本文能为读者提供全面而深入的理解,激发更多关于CORDIC算法的研究与实践。

相关文章:

探秘基带算法:从原理到5G时代的通信变革【五】CORDIC算法

文章目录 2.4 CORDIC算法2.4.1 CORDIC算法的基本原理2.4.2 方法论与分类体系旋转模式矢量模式线性模式 2.4.3 **CORDIC 算法中的误差来源****角度逼近误差的分析****缩放效应误差的分析****精度需求与迭代次数的关系****常见应用场景下的迭代次数建议****总结** 2.4.4优缺点分析…...

golang介绍,特点,项目结构,基本变量类型与声明介绍(数组,切片,映射),控制流语句介绍(条件,循环,switch case)

目录 golang 介绍 面向并发 面向组合 特点 项目结构 图示 入口文件 main.go 基本变量类型与声明 介绍 声明变量 常量 字符串(string) 字符串格式化 空接口类型 数组 切片 创建对象 追加元素 复制切片 map(映射) 创建对象 使用 多重赋值 控制流语句…...

大语言模型学习--本地部署DeepSeek

本地部署一个DeepSeek大语言模型 研究学习一下。 本地快速部署大模型的一个工具 先根据操作系统版本下载Ollama客户端 1.Ollama安装 ollama是一个开源的大型语言模型&#xff08;LLM&#xff09;本地化部署与管理工具&#xff0c;旨在简化在本地计算机上运行和管理大语言模型…...

力扣-动态规划-53 最大子数组和

思路 dp数组定义&#xff1a;以i为结尾的字符串的最大子数组和为dp[i]递推公式&#xff1a; dp[i] max(nums[i], dp[i-1] nums[i]);dp数组初始化&#xff1a;dp[0] nums[0];遍历顺序&#xff1a;顺序时间复杂度&#xff1a; 代码 class Solution { public:int maxS…...

论文阅读和代码实现EfficientDet(BiFPN)

BiFPN 采用双向特征融合&#xff0c;让 P3 和 P4 不仅能获取来自 Backbone 的信息&#xff0c;还可以有效吸收 P5 的高级语义特征&#xff0c;增强小目标的判别能力 通过 加权特征融合&#xff08;Weighted Feature Fusion&#xff09;&#xff0c;BiFPN 让 P3 层能够 自动调整…...

[杂学笔记] 封装、继承、多态,堆和栈的区别,堆和栈的区别 ,托管与非托管 ,c++的垃圾回收机制 , 实现一个单例模式 注意事项

文章目录 1.封装、继承、多态2. 堆和栈的区别3.指针和引用的区别4. 托管与非托管5. c的垃圾回收机制6. 实现一个单例模式 注意事项 1.封装、继承、多态 封装就是将数据和内部的方法封装到一个类中&#xff0c;对外隐藏内部实现细节&#xff0c;但是留下了公共接口提供给外部使…...

c++ std::bind、std::bind_front使用笔记

c std::bind、std::bind_front使用笔记 std::bind 和 std::bind_front 的使用说明std::bind (C11 引入)std::bind_front (C20 引入) 应用场景应用注意事项应用注意事项的例子 std::bind 和 std::bind_front 的使用说明 std::bind (C11 引入) std::bind 用于创建一个新的可调用…...

神策数据严正声明

近日&#xff0c;我们发现有不法分子冒充神策网络科技&#xff08;北京&#xff09;有限公司&#xff08;以下简称”神策数据”&#xff09;的名义&#xff0c;发布虚假的招聘广告、面试邀请&#xff0c;企图误导求职者并进行不法行为。对此&#xff0c;我司发布严正声明&#…...

vue+elementui 实现上传文件/导入文件的功能

vueelementui 实现上传文件/导入文件的功能 1. 上传组件 <el-form-item label"上传文件&#xff1a;"><el-uploadaction"":file-list"fileList":show-file-list"false":http-request"handUpLoad"drag:limit"…...

FastGPT 引申:知识库辅助开发(代码符号自动提取与文件匹配工具详解)

文章目录 FastGPT 引申&#xff1a;知识库辅助开发&#xff08;代码符号自动提取与文件匹配工具详解&#xff09;1. 符号提取 prompt2. 文件查询 prompt3. 总结 FastGPT 引申&#xff1a;知识库辅助开发&#xff08;代码符号自动提取与文件匹配工具详解&#xff09; 在开发过程…...

李国杰院士 “七问” DeepSeek:深度剖析 AI 发展新态势

李国杰院士 “七问” DeepSeek&#xff1a;深度剖析 AI 发展新态势 在人工智能领域的探索之路上&#xff0c;李国杰院士凭借深厚的学术造诣和前瞻性的眼光&#xff0c;成为指引方向的重要灯塔。 李国杰院士任职于中国科学院计算技术研究所&#xff0c;担任研究员一职。他不仅是…...

C#中泛型的协变和逆变

协变&#xff1a; 在泛型接口中&#xff0c;使用out关键字可以声明协变。这意味着接口的泛型参数只能作为返回类型出现&#xff0c;而不能作为方法的参数类型。 示例&#xff1a;泛型接口中的协变 假设我们有一个基类Animal和一个派生类Dog&#xff1a; csharp复制 public…...

transformer架构解析{掩码,(自)注意力机制,多头(自)注意力机制}(含代码)-3

目录 前言 掩码张量 什么是掩码张量 掩码张量的作用 生成掩码张量实现 注意力机制 学习目标 注意力计算规则 注意力和自注意力 注意力机制 注意力机制计算规则的代码实现 多头注意力机制 学习目标 什么是多头注意力机制 多头注意力计算机制的作用 多头注意力机…...

SpringBoot生成唯一ID的方式

1.为什么要生成唯一ID&#xff1f; 数据唯一性&#xff1a;每个记录都需要有一个独一无二的标识符来确保数据的唯一性。这可以避免重复的数据行&#xff0c;并有助于准确地查询、更新或删除特定的记录。 数据完整性&#xff1a;通过使用唯一ID&#xff0c;可以保证数据库中的数…...

认识时钟树

时钟源 高速外部震荡器HSE 低速外部震荡器LSE 高速内部震荡器HSI 低速内部震荡器LSI 易混淆点&#xff1a; RC&#xff08;Resistor-Capacitor&#xff0c;电阻-电容振荡器&#xff09;一般是内部时钟源 RTC&#xff08;Real-Time Clock&#xff0c;实时时钟&#xff09;…...

NLP如何训练AI模型以理解知识

一、自然语言处理&#xff08;NLP&#xff09;的定义与核心目标 1. 什么是自然语言处理&#xff1f; NLP是计算机科学与人工智能的交叉领域&#xff0c;旨在让机器具备以下能力&#xff1a; • 理解&#xff1a;解析人类语言&#xff08;文本或语音&#xff09;的语法、语义和…...

linux如何在某个文件夹下查看所有文件(层级只到当前文件夹的两层)并找到‘XXXX’ 这个单词

问了AI写的不错&#xff0c;记录一下&#xff0c;排查一些报错的时候比较好用 在 Linux 中&#xff0c;您可以通过命令行工具查看某个文件夹下的所有文件&#xff08;限制到当前文件夹及其子文件夹两层深度&#xff09;&#xff0c;并搜索包含特定单词&#xff08;如 XXXXX&am…...

Android 常见View的防抖

在开发Android应用时&#xff0c;我们经常会遇到用户快速点击按钮或者频繁触发某个事件的情况。这种行为可能会导致不必要的重复操作&#xff0c;例如多次提交表单、重复加载数据等。为了避免这些问题&#xff0c;我们需要对这些事件进行防抖处理。本文将详细介绍如何在Kotlin中…...

Unity打包到webgl鼠标图标大小不正确

我使用了自定义鼠标纹理&#xff0c;打包出来发现鼠标特别的大&#xff0c;位置也不对劲 研究了一下&#xff0c;不考虑浏览器界面缩放的话&#xff0c;可以直接改import settings的最大尺寸&#xff0c;改成合适的尺寸。 暂时先这样解决吧 最后贴一个设置鼠标图标的代码 pub…...

CentOS 7中安装Dify

Dify 是一个开源的 LLM 应用开发平台。其直观的界面结合了 AI 工作流、RAG 管道、Agent、模型管理、可观测性功能等&#xff0c;让您可以快速从原型到生产。尤其是我们本地部署DeepSeek等大模型时&#xff0c;会需要用到Dify来帮我们快捷的开发和应用。 大家可以参考学习它的中…...

爬蟲動態IP代理與數據採集穩定性

對於從事爬蟲開發的人來說&#xff0c;IP代理的使用直接影響了爬蟲的效率和穩定性。爬蟲的本質是模擬用戶訪問網站&#xff0c;通過抓取網頁內容來獲取所需數據。但大多數網站為了保護自己的數據或防止濫用&#xff0c;會設置諸如IP訪問頻率限制、登錄驗證甚至封禁等反爬蟲措施…...

excel 斜向拆分单元格

右键-合并单元格 右键-设置单元格格式-边框 在设置好分割线后&#xff0c;你可以开始输入文字。 需要注意的是&#xff0c;文字并不会自动分成上下两行。 为了达到你期望的效果&#xff0c;你可以通过 同过左对齐、上对齐 空格键或使用【AltEnter】组合键来调整单元格中内容的…...

React Native 实现滑一点点内容区块指示器也滑一点点

效果图如上&#xff0c;内容滑一点点&#xff0c;指示器也按比例话一点点&#xff0c;列表宽度跟数据有关。 实现思路如下&#xff1a; 1.监听列表滑动事件&#xff0c;获取列表横向滑动距离&#xff0c;假设为A&#xff1b; 2.获取列表的宽度&#xff0c;及列表可滑动的宽度…...

解决Vscode项目同时运行两个项目终端无法自动叠加的问题

终端&#xff08;如命令行工具或服务进程&#xff09;无法自动“叠加”使用同一资源&#xff08;如端口号、进程ID等&#xff09;的核心原因在于操作系统的资源管理机制和网络协议规范的限制。以下是具体分析&#xff1a; 以下是解决 VSCode 同时运行两个项目时终端被前一个占…...

vuex中的state是响应式的吗?

在 Vue.js 中&#xff0c;Vuex 的 state 是响应式的。这意味着当你更改 state 中的数据时&#xff0c;依赖于这些数据的 Vue 组件会自动更新。这是通过 Vue 的响应式系统实现的&#xff0c;该系统使用了 ES6 的 Proxy 对象来监听数据的变化。 当你在 Vuex 中定义了一个 state …...

k8s面试题总结(九)

1.K8s中pod删除失败&#xff0c;有哪些情况&#xff1f;如何解决&#xff1f; Pod删除失败的情况&#xff1a; (1) Pod被其他资源&#xff08;如Deployment,ReplicaSet&#xff09;引用&#xff0c;无法删除pod 解决&#xff1a;先删除引用该pod的资源&#xff0c;再删除pod…...

【JQuery—前端快速入门】JQuery 操作元素

JQuery 操作元素 1. 获取/修改元素内容 三个简单的获取元素的方法&#xff1a; 这三个方法即可以获取元素的内容&#xff0c;又可以设置元素的内容. 有参数时&#xff0c;就进行元素的值设置&#xff0c;没有参数时&#xff0c;就进行元素内容的获取. 接下来&#xff0c;我们需…...

三维数据可视化与表面重建:Marching Cubes算法的原理与应用

1. 引言 随着现代医学影像技术的飞速发展&#xff0c;三维数据的可视化与重建已成为医学研究、临床诊断和手术规划的重要工具。在众多三维重建算法中&#xff0c;Marching Cubes算法因其高效、稳定的特性成为从离散数据场中提取等值面的经典方法。本报告将深入探讨Marching Cu…...

网络变压器的主要电性参数与测试方法(2)

Hqst盈盛&#xff08;华强盛&#xff09;电子导读&#xff1a;网络变压器的主要电性参数与测试方法&#xff08;2&#xff09;.. 今天我们继续来看看网络变压器的2个主要电性参数与它的测试方法&#xff1a; 1. 线圈间分布电容Cp:线圈间杂散静电容 测试条件:100KHz/0.1…...

端到端自动驾驶——cnn网络搭建

论文参考&#xff1a;https://arxiv.org/abs/1604.07316 demo 今天主要来看一个如何通过图像直接到控制的自动驾驶端到端的项目&#xff0c;首先需要配置好我的仿真环境&#xff0c;下载软件udacity&#xff1a; https://d17h27t6h515a5.cloudfront.net/topher/2016/November…...

# 【Unity】【游戏开发】赛车游戏中碰撞加速的实现方法

背景 在赛车类游戏开发中,常常需要实现赛车在碰撞某些道具或对象后加速的功能。例如,当赛车经过加速带或碰撞加速道具时,速度会瞬间增加,使游戏更具动态性和可玩性。本文将介绍一种通用的实现方式,并分析其逻辑。 分析 加速的核心逻辑如下: 判断碰撞条件:检测赛车是否…...

Dubbo本地服务调试

本地服务之间调试 参考这个文档&#xff1a; Dubbo本地调试 注意事项 本地主服务调用本地另外一个子服务&#xff0c;dubbo端口号与子服务的WEB端口号不一致。要查看子服务dubbo的配置文件&#xff0c;设置的rpc端口号是多少主服务中&#xff0c;最好在dubbo的配置文件&…...

SqlSugar 语法糖推荐方式

//方式1&#xff1a;var dd _repository._Db.Queryable<ConfigAggregateRoot, UserRoleEntity>((o, p) > o.Id p.Id).Select((o, p) > new{o.Id,o.Remark,p.RoleId,});//方式2&#xff1a;不推荐使用&#xff0c;建议优先使用 Lambda 表达式&#xff0c;因为它更…...

爬虫逆向实战小记——解决captcha滑动验证码

注意&#xff01;&#xff01;&#xff01;&#xff01;某XX网站实例仅作为学习案例&#xff0c;禁止其他个人以及团体做谋利用途&#xff01;&#xff01;&#xff01; IGh0dHBzOi8vY2FwdGNoYS5ydWlqaWUuY29tLmNuLw 第一步: 分析请求网址和响应内容 (1)通过观察&#xff0c;滑…...

printf 与前置++、后置++、前置--、后置-- 的关系

# 前置和前置-- 先看一段代码 大家是不是认为printf输出的是 2 3 3 2 1 1 但是实际输出的是 3 3 3 1 1 1 在这两行printf函数代码里&#xff0c;编译器会先计算 a 和 --a 的值&#xff0c;然后再 从右向左 开始输出。 printf函数中&#xff0c;如果有多个…...

【Web前端开发】---HTML标签及标签属性

1、单标签与双标签 HTML标签分为&#xff1a;双标签、单标签。 例如&#xff1a; <marquee>你好</marquee> 示例&#xff1a; 双标签&#xff1a;<标签名>标签体</标签名> 单标签&#xff1a;<标签名/>&#xff08;注意&#xff1a;/可以省…...

【大模型系列篇】国产开源大模型DeepSeek-V3技术报告解析

DeepSeek-V3技术报告 目录 DeepSeek-V3技术报告 1. 摘要 2. 引言 3. DeepSeek V3 架构 3.1 基础架构 3.1.1. 多头潜在注意力 3.1.2. DeepSeekMoE和无辅助损失的负载均衡 3.2 多令牌预测 4. 基础设施 4.1 计算集群 4.2 训练框架 4.2.1. DualPipe算法与计算通信协同优…...

【赵渝强老师】监控Redis

对运行状态的Redis实例进行监控是运维管理中非常重要的内容&#xff0c;包括&#xff1a;监控Redis的内存、监控Redis的吞吐量、监控Redis的运行时信息和监控Redis的延时。通过Redis提供的监控命令便能非常方便地实现对各项指标的监控。 一、监控Redis的内存 视频讲解如下 【…...

RocketMQ顺序消费机制

RocketMQ的顺序消费机制通过生产端和消费端的协同设计实现&#xff0c;其核心在于局部顺序性&#xff0c;即保证同一队列&#xff08;MessageQueue&#xff09;内的消息严格按发送顺序消费。以下是详细机制解析及关键源码实现&#xff1a; 一、顺序消费的核心机制 1. 生产端路…...

新装的conda 以及pycharm未能正确初始化,或conda环境变量配置错误问题解决!!!

Windows PowerShell 版权所有&#xff08;C&#xff09; Microsoft Corporation。保留所有权利。 安装最新的 PowerShell&#xff0c;了解新功能和改进&#xff01;https://aka.ms/PSWindows PS E:\Dev_project\MyProjects> conda cativate py12 usage: conda-script.py [-h…...

通往 AI 之路:Python 机器学习入门-线性代数

2.1 线性代数&#xff08;机器学习的核心&#xff09; 线性代数是机器学习的基础之一&#xff0c;许多核心算法都依赖矩阵运算。本章将介绍线性代数中的基本概念&#xff0c;包括标量、向量、矩阵、矩阵运算、特征值与特征向量&#xff0c;以及奇异值分解&#xff08;SVD&…...

2025国家护网HVV高频面试题总结来了03(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 0x1 高频面试题第一套 0x2 高频面试题第二套 0x3 高频面试题第三套 0x4高频面试题第四套 0x1 高频面试题…...

内容中台与企业内容管理架构解析

内容中台技术架构解析 内容中台的技术架构以数据资产化和服务API化为核心&#xff0c;通过解耦内容生产与消费环节构建数字化基础设施。其架构通常包含统一内容池、智能处理引擎和开放接口层三大模块&#xff1a;统一内容池通过标准化元数据模型对多源异构内容进行结构化存储&…...

希音(Shein)前端开发面试题集锦和参考答案

用 Node 写过什么工具或 npm 包 在实际开发中,使用 Node 编写过多种实用工具和 npm 包。 自动化构建工具 开发了一个简单的自动化构建工具,用于处理前端项目的资源压缩和合并。在前端项目中,为了优化性能,需要对 CSS 和 JavaScript 文件进行压缩,减少文件体积,同时将多个…...

《一个端粒到端粒的参考基因组为木瓜中五环三萜类化合物生物合成提供了遗传学见解》

A telomere-to-telomere reference genome provides genetic insight into the pentacyclic triterpenoid biosynthesis in Chaenomeles speciosa Amplification of transposable elements 转座元件的扩增 Sequence mining disclosed that TEs were one main event in the ex…...

使用easyocr、PyPDF2对图像及PDF文档进行识别

一、概述 本 Python 脚本的主要功能是对当前目录及其子目录下的图片和 PDF 文件进行光学字符识别&#xff08;OCR&#xff09;处理。它使用 easyocr 库处理图片中的文字&#xff0c;使用 PyPDF2 库提取 PDF 文件中的文本&#xff0c;并将处理结果保存为文本文件。同时&#xff…...

用AI学安卓游戏开发1——控制小球上下左右移动2

业务逻辑&#xff1a;初始化小球随机自有移动&#xff0c;遇到屏幕边缘反弹&#xff0c;摇杆介入后小球停止自有移动&#xff0c;按照摇杆控制方向移动。 https://download.csdn.net/download/AnalogElectronic/90453667 https://download.csdn.net/download/AnalogElectronic…...

计算机毕业设计SpringBoot+Vue.js医院挂号就诊系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

说一下redis事务底层原理

Redis事务 1. 事务的基本流程 Redis 事务通过 MULTI、EXEC、WATCH 等命令实现&#xff0c;底层原理可以分为以下几个步骤&#xff1a; (1) MULTI 命令 当客户端发送 MULTI 命令时&#xff0c;Redis 会将客户端标记为“事务模式”。在事务模式下&#xff0c;客户端发送的所有…...

eNSP中AR2220、AR201、AR1220、AR2240、AR3260、Router、NE40E、NE5000E、NE9000、CX路由器学习笔记

eNSP中常见华为路由器型号的接口特性详解及横向对比&#xff0c;重点关注接口类型、扩展能力和适用场景&#xff1a; 缩写解释&#xff1a; LPU&#xff1a;Line Processing Unit&#xff08;线路处理单元&#xff09; SPU&#xff1a;Service Processing Unit&#xff08;业务…...