CORDIC(Coordinate Rotation Digital Computer)坐标旋转数字计算机,是数学与计算机技术交叉产生的一种机器算法,用于解决计算机的数学计算问题。发展到现在,CORDIC算法及其扩展算法大致有三种计算模式:圆周旋转模式、线性旋转模式和双曲线旋转模式,分别用来实现不同的数学运算。

本文介绍圆周旋转模式下的CORDIC算法原理及实现过程,另两种模式将分期介绍。

简单来讲,CORDIC利用近似逼近的思想,将计算机中三角函数、开根号、求对数等复杂运算,转化为简单的加减和移位操作。

对于实际只会识别0和1的计算机来说,加减和移位是它能轻松实现的操作,因此利用CORDIC算法将大大提升计算机对复杂运算的计算效率。目前,尽管计算机的运行速度已经足够使得大多数开发者不用太多考虑计算效率的问题,但在一些实时数据流比较大的场合(如通信、多媒体处理等),CORDIC算法依然是实现高速运算的关键。

类似CORDIC实现的数学思想早在1624年就由Henry Briggs提出并发表,但直到1956年,CORDIC算法才真正被美国工程师Jack E.Volder发现并运用,当时他正在寻找提高计算器计算精度和实时性的算法。直到1959年,Volder的算法才为公众所知,并在计算器上大行其道。

算法描述

1. 数学背景

如图,XY平面中一点(x1,y1)经圆周旋转θ角度,得到点(x2,y2)。经简单的三角函数关系,可得到:

通过提出因数cosθ,可得:

如果不考虑cosθ,得到“伪旋转”方程:

伪旋转仅实现了正确的角度旋转,但向量模值变为原来的1/cosθ。

2. CORDIC方法

若使得tanθ = 2^(-i),i为自然数,则上式变为:

注意!上式已经仅剩加减和移位运算。

如果我们把所有tanθi = 2^(-i)对应的角度和正切值制成一张表,如下所示:

……

可以确定的是,任意旋转角度θ,都可以由上表中的大小不同θi进行多次旋转得到。CORDIC正是利用这一点,将θ角度的旋转分解为从大到小、逐次逼近真实旋转角度的一组旋转,而这些旋转的实现又都可以由加减和移位运算来完成。θi可以预先制成表格,供计算机查找使用。

算法实现

1. 已知坐标(x,y),求其向量对应的相角θ(反正切)和模值

思想: 把原向量逐次向X正轴进行伪旋转逼近,整个过程的累计旋转角度即为θ,而旋转后的x坐标补偿模值增益K后即为原向量模值。

每次迭代的方程为:

模值总增益K为:

其中d决定旋转方向为逆时针还是顺时针,z为角度累加值。

注意!查找表中所有θi的总和约为99度,因此能实现计算的角度在-99~99度之间。实际算法实现时,我们可预先判断坐标象限,人为将其转化为第一象限内的计算,并在事后补偿为真实值。

如图:(x,y)=(3,sqrt(3)),迭代深度=16,CORDIC算法实现过程

matlab代码如下:

%% ***********************************************************************************
% 已知坐标,用cordic算法计算相角和幅值。基本公式如下:
% x(k+) = x(k) - d(k)*y(k)*^(-k)
% y(k+) = y(k) + d(k)*x(k)*^(-k)
% z(k) = z(k) - d(k)*actan(^(-k))
%% *********************************************************************************** clear;close all;clc;
% 初始化----------------------------------------
N = ; %迭代次数
tan_table = .^-( : N-);
angle_LUT = atan(tan_table); K = ;
for k = : N-
K = K*(/sqrt( + ^(-*k)));
end x = ;
y = sqrt();
angle_accumulate = ; % cordic算法计算-------------------------------
if (x== && y==)
radian_out = ;
amplitude_out = ;
else % 先做象限判断,得到相位补偿值
if (x > )
phase_shift = ;
elseif (y < )
phase_shift = -pi;
else
phase_shift = pi;
end for k = : N- % 迭代开始
x_temp = x;
if (y < ) % d(k)=,逆时针旋转
x = x_temp - y*^(-k);
y = y + x_temp*^(-k);
angle_accumulate = angle_accumulate - angle_LUT(k+);
else % d(k)=-,顺时针旋转
x = x_temp + y*^(-k);
y = y - x_temp*^(-k);
angle_accumulate = angle_accumulate + angle_LUT(k+);
end
radian_out = angle_accumulate + phase_shift; %弧度输出
end amplitude_out = x*K; %幅值输出
end angle_out = radian_out*/pi; %相角输出

2. 已知角度θ,求正弦sinθ和余弦cosθ

思想: 若向量模值为1,则其x坐标就是余弦值,y坐标就是正弦值。利用这一点,从(K,0)处迭代旋转至θ处的单位矢量即可。

迭代方程及K的计算同第一小节。同时也要注意预先对象限的判断和补偿。

如图:θ=60度,迭代深度=16,CORDIC算法实现过程

matlab代码如下:

%% ***********************************************************************************
% 已知相角theta,计算其正弦和余弦值。基本公式如下:
% x(k+) = x(k) - d(k)*y(k)*^(-k)
% y(k+) = y(k) + d(k)*x(k)*^(-k)
% z(k) = z(k) - d(k)*actan(^(-k))
%% ***********************************************************************************
clear;close all;clc; % 初始化----------------------------------------
N = ; %迭代次数
tan_table = .^-( : N-);
angle_LUT = atan(tan_table); K = ;
for k = : N-
K = K*(/sqrt( + ^(-*k)));
end theta = -;
x = ;
y = ;
phase_accumulate = theta/*pi; %转化为弧度 % cordic算法计算-------------------------------
if (phase_accumulate > pi/) % 先做象限判断,得到相位补偿值
phase_accumulate = phase_accumulate - pi;
sign_x = -;
sign_y = -;
elseif (phase_accumulate < -pi/)
phase_accumulate = phase_accumulate + pi;
sign_x = -;
sign_y = -;
else
sign_x = ;
sign_y = ;
end for k = : N- % 迭代开始
x_temp = x;
if (phase_accumulate > ) % d(k)=,逆时针旋转
x = x_temp - y*^(-k);
y = y + x_temp*^(-k);
phase_accumulate = phase_accumulate - angle_LUT(k+);
else % d(k)=-,顺时针旋转
x = x_temp + y*^(-k);
y = y - x_temp*^(-k);
phase_accumulate = phase_accumulate + angle_LUT(k+);
end
end cos_out = sign_x*x*K; %余弦输出
sin_out = sign_y*y*K; %正弦输出

参考文献/资料

【1】https://en.wikipedia.org/wiki/CORDIC

【2】Xilinx CORDIC算法(非常经典)——百度文库

【3】ANDRAKA R. A Survey of CORDIC Algorithms for FPGA Based Computers[C] ,1998

·END·

欢迎来我的微信公众号做客:信号君

专注于信号处理知识、高性能计算、现代处理器&计算机体系

技术成长 | 读书笔记 | 认知升级

幸会~

CORDIC算法(1):圆周旋转模式下计算三角函数和模值的更多相关文章

  1. FPGA之CORDIC算法实现_代码实现(下)

    关于FPGA之CORDIC算法的纯逻辑实现,博主洋葱洋葱“https://www.cnblogs.com/cofin/p/9188629.html”以及善良的一休军“https://blog.csdn ...

  2. win10下计算文件哈希值的方法

    cmd下使用certutil命令 使用方法: certutil -hashfile FILE_NAME ALGORITHM_NAME 支持的加密算法包括:MD2,MD4,MD5,SHA1,SHA256 ...

  3. Cordic算法——圆周系统之旋转模式

    三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)= ...

  4. FPGA算法学习(1) -- Cordic(圆周系统之旋转模式)

    三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)= ...

  5. Cordic算法——圆周系统之向量模式

    旋转模式用来解决三角函数,实现极坐标到直角坐标的转换,基础理论请参考Cordic算法--圆周系统之旋转模式.那么,向量模式则用来解决反三角函数的问题,体现的应用主要是直角坐标向极坐标转换,即已知一点的 ...

  6. 基于FPGA的Cordic算法实现

    CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数.双曲线.指数.对数的 ...

  7. cordic算法的verilog实现及modelsim仿真

    1. 算法介绍 CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数.双曲 ...

  8. 使用CORDIC算法求解角度正余弦及Verilog实现

    本文是用于记录在了解和学习CORDIC算法期间的收获,以供日后自己及他人参考:并且附上了使用Verilog实现CORDIC算法求解角度的正弦和余弦的代码.简单的testbench测试代码.以及在Mod ...

  9. 软件调试——IA-32 保护模式下寄存器一览

    最近在看张银奎先生的<调试软件>一书,想将关键的技术记录下来,以便日后查阅,也分享给想看之人吧. 1 通用寄存器 EAX,EBX,ECX,EDX:用于运算的通用寄存器,可以使用AX,BX等 ...

随机推荐

  1. sqlite 用法整理

    转载:http://blog.csdn.net/zhaoweixing1989/article/details/19080593 先纪录到这,以后慢慢整理. 1. 在Android下通过adb she ...

  2. Redis添加访问密码

    进入Redis的安装目录,找到redis.conf文件. 1.修改密码:使用vi命令打开redis.conf文件,先使用字符匹配查找到requirepass foobared对应的位置, 然后修改fo ...

  3. 代码大全读书笔记 Part 1

    简单的看了前言,印象最深的还是这本书崇尚"绝不注水"的原则.现实生活中,不仅仅有注水牛肉,瘦肉精的猪肉,很多书籍也是东拼西凑来的内容,不注水的厚书,是十分令人期待的. 第一章:欢迎 ...

  4. 简易log4j 父logger和子logger

    log4j 父logger和子logger         定义子logger其目的就是能够在某一范围内(某一个class或者某一个package)下面,日志的输出方式与其他地方的日志输出方式不同. ...

  5. MySQL错误问题

    启动Tomcat的时候报错:no suitable driver,MySql更新使用com.mysql.cj.jdbc.Driver,废弃老的com.mysql.jdbc.Driver驱动,需要将D: ...

  6. 2018.09.23模拟总结(T2)

    T1,T3我就不说啦,反正也不会.主要想讲的是T2. T2用了一个神奇的算法:折半搜索. 因为这个坑爹的数据范围告诉我们暴搜或是状压会TLE,而一半刚好能卡过去. 折半搜索其实跟暴搜没什么区别,就是折 ...

  7. 2019.1.7 Mac的Vscode插件总结

    Vscode插件 通用插件 Chinese 配置中文界面 HTML Snippets H5代码片段以及提示 HTML CSS Support 让 html 标签上写class 智能提示当前项目所支持的 ...

  8. Kali-linux安装并配置NVIDIA显卡驱动

    显卡驱动程序就是用来驱动显卡的程序,它是硬件所对应的软件.驱动程序即添加到操作系统中的一小块代码,其中包含有关硬件设备的信息.有了此信息,计算机就可以与设备进行通信.驱动程序是硬件厂商根据操作系统编写 ...

  9. 提交文件到ng-pages分支

    一.提交dist文件夹到ng-pages分支 git subtree push --prefix=dist origin gh-pages 二.提交所有文件到ng-pages分支 text git:( ...

  10. 双T滤波电路用于PWM方式DAC的分析

    双T滤波电路用于PWM方式DAC的分析   之前做温度控制的时候,用到了PWM到DAC的转化,PWM方波,经过滤波,怎么就变成了直流的信号,之前我也很困惑这一点.用频域的方法可以近似说明,但是严格的数 ...