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

举报
李锐博恩 发表于 2021/07/15 04:04:29 2021/07/15
【摘要】 转发博文背景: 在项目中用到了下面的知识:数据都是R+jI 的复数形式,首先要用CORDIC算法将数据转换成Ae^(jωt+φ) 形式。一句话就引出了一个知识点,这篇博文来总结这种功能的CORDIC算法。 向量模式的Cordic算法虽然解决的是从直角坐标到极坐标的转换,但是和上述需求不谋而合。 前人栽树,后人乘凉。这里仍然借鉴好的博文。 博文地址:https://ww...

转发博文背景:

在项目中用到了下面的知识:数据都是R+jI 的复数形式,首先要用CORDIC算法将数据转换成Ae^(jωt+φ) 形式。一句话就引出了一个知识点,这篇博文来总结这种功能的CORDIC算法。

向量模式的Cordic算法虽然解决的是从直角坐标到极坐标的转换,但是和上述需求不谋而合。

前人栽树,后人乘凉。这里仍然借鉴好的博文。

博文地址:https://www.cnblogs.com/rouwawa/p/7101703.html


有了上篇博文的基础,看这篇博文就容易多了:CORDIC算法——圆周系统之旋转模式

旋转模式用来解决三角函数,实现极坐标到直角坐标的转换。那么,向量模式则用来解决反三角函数的问题,体现的应用主要是直角坐标向极坐标转换,即已知一点的直角坐标(x,y),求其极坐标(α,γ),实际上是求arctan(y/x)。

旋转模式下,每次迭代使z趋近于α(α-z趋近于0),而向量模式下,则使y趋近于0,这一点很好理解,即从坐标位置,旋转到x正半轴,一共旋转了多少角度,则该角度即为α,从而知道了极角。

如图所示,在单位圆上,向量OP与X轴的正半轴夹角为α,故P点的坐标可表示为

根据开头描述,我们需要转动向量OP,先顺时针旋转θ角至向量OQ,Q点的坐标可表示为

这里定义θ为目标旋转角度。根据三角函数公式可将上式展开为

现在已经有点 Cordic 算法的样子了,但是我们看到每次旋转都要计算 4 次浮点数的乘法运算,运算量还是太大了。还需要进一步的改进,改进的切入点当然还是坐标变换的过程。

将式(1.1)代入到式(1.3)中可得

用矩阵形式表示为:

旋转了i次以后,可以得到:

最终需将y_Q_i+1转为0,先按45°的二分法查找来解释过程,用C语言描述过程为:


  
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. double cordic_v(double x, double y);
  4. int main(viod)
  5. {
  6. double alfa = cordic_v(120.0,200.0); //直角坐标(x,y)
  7. printf("\n 极角为 = %f \n",alfa);
  8. return 0;
  9. }
  10. double cordic_v(double x, double y)
  11. {
  12. const double sine[] = {0.7071067811865,0.3826834323651,0.1950903220161,
  13. 0.09801714032956,0.04906767432742,0.02454122852291,0.01227153828572,
  14. 0.006135884649154,0.003067956762966,0.001533980186285,
  15. 7.669903187427045e-4,3.834951875713956e-4,1.917475973107033e-4,
  16. 9.587379909597735e-5,4.793689960306688e-5,2.396844980841822e-5
  17. };
  18. const double cosine[] = {0.7071067811865,0.9238795325113,0.9807852804032,0.9951847266722,
  19. 0.9987954562052,0.9996988186962,0.9999247018391,0.9999811752826,0.9999952938096,
  20. 0.9999988234517,0.9999997058629,0.9999999264657,0.9999999816164,0.9999999954041,
  21. 0.999999998851,0.9999999997128
  22. };
  23. int i = 0;
  24. double x_new, y_new;
  25. double angleSum = 0.0;
  26. double angle = 45.0; //第一次旋转角度为45°
  27. for( i=0; i<15;i++)
  28. {
  29. if(y > 0)
  30. {
  31. x_new = x * cosine[i] + y * sine[i];
  32. y_new = y * cosine[i] - x * sine[i];
  33. x = x_new;
  34. y = y_new;
  35. angleSum += angle;
  36. }
  37. else
  38. {
  39. x_new = x * cosine[i] - y * sine[i];
  40. y_new = y * cosine[i] + x * sine[i];
  41. x = x_new;
  42. y = y_new;
  43. angleSum -= angle;
  44. }
  45. printf("旋转次数: i = %2d 旋转角度 = %10f, 累计旋转角度 = %10f\n", i+1, angle,angleSum );
  46. angle /= 2;
  47. }
  48. return angleSum;
  49. }

经过旋转模式的推导,向量模式的伪旋转公式,可表示为

C语言描述过程,如下:


  
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. double cordic_v(double x, double y);
  5. double r = 0.0; //定义一个模长全局变量
  6. int main(viod)
  7. {
  8. double alfa = cordic_v(120.0,200.0); //直角坐标(x,y)
  9. printf("\n极角 = %5f, 模长 = %5f\n",alfa,r);
  10. return 0;
  11. }
  12. double cordic_v(double x, double y)
  13. {
  14. const double theta[] = { 45.0, 26.56505118, 14.03624347, 7.125016349,
  15. 3.576334375, 1.789910608, 0.8951737102, 0.4476141709,
  16. 0.2238105004, 0.1119056771, 0.05595289189, 0.02797645262,
  17. 0.01398822714, 0.006994113675, 0.003497056851, 0.001748528427
  18. }; //旋转角度
  19. int i = 0;
  20. double x_new, y_new;
  21. double angleSum = 0.0;
  22. r = sqrt(x*x+y*y);
  23. for( i=0; i<16;i++)
  24. {
  25. if(y > 0)
  26. {
  27. x_new = x + y/(1<<i);
  28. y_new = y - x/(1<<i);
  29. x = x_new;
  30. y = y_new;
  31. angleSum += theta[i];
  32. }
  33. else
  34. {
  35. x_new = x - y/(1<<i);
  36. y_new = y + x/(1<<i);
  37. x = x_new;
  38. y = y_new;
  39. angleSum -= theta[i];
  40. }
  41. printf("旋转次数: i = %2d 旋转角度 = %10f, 累计旋转角度 = %10f, y = %5f\n", i+1,theta[i],angleSum,y );
  42. }
  43. return angleSum;
  44. }

同样,向量模式的cordic算法适用于第一、四象限的坐标变换,在第二、三象限的坐标需要进行预处理。

 

 

 

 

 

 

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/87434332

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。