最近出于项目需要,对CORDIC算法深入学习下。刚开始的时候上网搜了下资料发现一上来就直接是推导公式,然后工程运用与理论推导联系太少感觉无从下手!对于像我们数学丢了很多年的同学来说实在是痛苦啊。
好在痛苦归痛苦,几天下来也略有小小收获,分享给大家。
CORDIC算法应该能够称为非线性运算的“大杀器”了,包括了“sin,cos,sinh,cosh,tan-1”等等...。cordic算法全称叫做坐标旋转计算法,既然是有坐标那(x,y)是无疑的,旋转的话角度也就清楚了,根据这两个量利用数学知识即可求出上述算式。但是人可以把笔在纸上拿笔算算,可机器做不到啊,于是美国佬绞尽脑汁想出一种便于计算机计算的方法,下面我就直接列出它里面的精华部分做一次实例推导,看看他的神奇之处!
前面的推导就不放上来了,大家看着头疼。其中x y分别表示对应坐标轴上的两点,d表示判断他旋转的方向,
那我们设x=1,y=0,d=30度 d=1,通过上述公式如何得到确切值
好,到这部我们可以看到z1 为负角度也就是说转过头了,接下来继续转 d1=-1.
继续旋转这次z2 为正d=1。
迭代三次之后发现有些苗头啊,越来越靠近说要计算的值了。再来一次这次d=-1.
第四次,,
第五次。。
这么机械的活还是交给计算机吧~
clear;
clc;
close all;
N = 30;
x_i = [1,zeros(1,N-1)];%
y_i = [0,zeros(1,N-1)];%
z_i = [pi/6,zeros(1,N-1)];
d = 1 ;%[1,zeros(1,N-1)]
for n=1:30
if(z_i(n)>0)
d=1;
else
d=-1;
end
%x_temp_i = x_i;
x_i(n+1) = x_i(n) - ( y_i(n) *d *2^(-n) );
y_i(n+1) = y_i(n) + ( x_i(n) *d *2^(-n) );
z_i(n+1) = z_i(n) - (1 *atan(2^(-n))*d );
end
sin_30 = y_i./(sqrt(x_i.^2+y_i.^2));
cos_30 = x_i./(sqrt(x_i.^2+y_i.^2));
figure(1)
plot(1:31,sin_30,'r-')
xlabel('迭代次数')
ylabel('正弦余弦值')
grid on;
hold on;
plot(1:31,cos_30,'b--')
legend('r-=sin30°','b--=cos30°')
grid on;
按照上述公式编写程序,迭代30次。
最终sin30=0.5000;
cos30=0.8660
细心的同学可以观察到,在迭代过程中只含有加减,唯一一个乘运算可以用位移得到。所以通过硬件实现是非常方便的,不得不佩服当时美帝数学家的良苦用心啊!
用户377235 2016-5-26 16:12
文中公式编辑有缺失,符号也有用错的地方,不要因为这些孤独了一篇好文
用户377235 2016-5-24 14:45
d=30度,d = 1好混乱,d到底是什么
用户377235 2015-8-14 15:37
lichenjiee_535207808 2015-1-22 13:11
用户377235 2015-1-4 07:55
用户592202 2014-10-13 15:31
用户1778641 2014-8-31 12:13
小梅哥 2014-8-23 21:08
用户217227 2014-8-14 10:56
用户402158 2014-8-5 14:51