3

我一直在查看双曲线旋转模式下的 CORDIC 算法以找到变量的平方根。我不确定我的初始变量应该是什么 (x0, y0, z0) 才能找到平方根。我已经阅读了一些论文,指出要找到 sqrt(a),对于 x0、y0 和 z0,初始值应分别设置为 a+1、a-1、0。其他人说应该是a+0.25,a-0.25,0。我对此感到非常困惑

任何人都可以帮忙吗?

double x = (64.0+1);
double y = (64.0-1);
double z = 0; 


double k = 3;
double n = 1;
while(n <= 20 ){

    double xn = pow(2.0,-1.0*n) * x;
    double yn = pow(2.0,-1.0*n) * y;

    if(y < 0){ 
        x = x + xn;
        y = y + yn;
        z = z - atanh(pow(2.0,-1.0*n));
    }
    else
    {
        x = x - xn;
        y = y - yn;
        z = z + atanh(pow(2.0,-1*n));

    }

    if(k > 0){
        k = k-1;
    }
    else{
        k = 3;
        if(y < 0){ 
            x = x + xn;
            y = y + yn;
            z = z - atanh(pow(2.0,-1.0*n));
        }
        else
        {
            x = x - xn;
            y = y - yn;
            z = z + atanh(pow(2.0,-1.0*n));

        }
    }
    n++;
    cout << "x: " << x << " y: " << y << " z: " << z << endl;
}

编辑* 除了补偿 3j+1 次重复外,CORDIC 还需要在 n = 4、13、40 等实例中执行两次循环,...我已经更新了我的代码以弥补这一点,但它仍然不起作用。我在矢量模式下使用双曲线旋转,该变量d应基于 y 的符号

编辑* 结果表明,在计算较大的平方根值时,CORDIC 可能会失败,因此您必须将尝试查找平方根的数字标准化为 0.5 到 2 范围,然后按比例缩小答案。

4

3 回答 3

3

对于 x0、y0 和 z0,初始值应分别设置为 a+1、a-1、0。其他人说应该是a+0.25,a-0.25,0。我对此感到非常困惑

最终结果是sqrt((a+1)^2 - (a-1)^2)sqrt((a+0.25)^2 - (a-0.25)^2)。无论哪种方式,a^2条款取消并且常数条款取消。唯一的区别是第一个版本返回sqrt(4a)2sqrt(a)第二个sqrt(a)直接返回。我不知道为什么可能首选一种情况或另一种情况的数字原因。

编辑:您的错误是d基于设置的y,它应该基于z.

于 2013-09-06T01:28:27.567 回答
2

您应该将执行平方根的数字标准化为 [0.5,2) 范围,然后相应地按比例放大。

于 2013-10-16T17:30:44.860 回答
0

代码中有几个错误!

  1. 变量不交换。
     x = x + xn;
     y = y + yn;

应该:

     x = x + yn;
     y = y + xn;
  1. 迭代 4 和 13 未正确重复。需要在这些分支中重新计算以下内容:
     xn = pow(2.0,-1.0*n) * y;
     yn = pow(2.0,-1.0*n) * x;
  1. 应在输出 ( x/2*1.207497) 上进行比例校正。

看到这里丑陋的调试,但工作代码: https ://godbolt.org/z/ma4dCV

另请注意,不需要整个z频道(https://mathworks.com/help/fixedpoint/examples/compute-square-root-using-cordic.html)。

于 2020-04-02T21:33:20.057 回答