What's wrong with my CORDIC algorithm?

Adapted to Java from the CORDIC Wikipedia page :

class MathFunctions {
final static double[] angles = {
    0.78539816339745, 0.46364760900081, 0.24497866312686, 0.12435499454676,
    0.06241880999596, 0.03123983343027, 0.01562372862048, 0.00781234106010,
    0.00390623013197, 0.00195312251648, 0.00097656218956, 0.00048828121119,
    0.00024414062015, 0.00012207031189, 0.00006103515617, 0.00003051757812,
    0.00001525878906, 0.00000762939453, 0.00000381469727, 0.00000190734863,
    0.00000095367432, 0.00000047683716, 0.00000023841858, 0.00000011920929,
    0.00000005960464, 0.00000002980232, 0.00000001490116, 0.00000000745058};
final static double[] Kvalues = {
    0.70710678118655, 0.63245553203368, 0.61357199107790, 0.60883391251775,
    0.60764825625617, 0.60735177014130, 0.60727764409353, 0.60725911229889,
    0.60725447933256, 0.60725332108988, 0.60725303152913, 0.60725295913894,
    0.60725294104140, 0.60725293651701, 0.60725293538591, 0.60725293510314,
    0.60725293503245, 0.60725293501477, 0.60725293501035, 0.60725293500925,
    0.60725293500897, 0.60725293500890, 0.60725293500889, 0.60725293500888};
public static double[] cordic(double theta, int n) {
    double[] v = new double[2];
    if (theta < -Math.PI/2 || theta > Math.PI/2) {
        v = (theta < 0)? cordic(theta + Math.PI, n):cordic(theta - Math.PI, n);
        return new double[]{-v[0],-v[1]};
    }
    double angle=angles[0], Kn=Kvalues[Math.min(n, Kvalues.length-1)];
    double sigma, factor, poweroftwo=1;
    for (int i=0; i<n-1; i++) {
        sigma = (theta < 0)? -1 : 1;
        factor = sigma*poweroftwo;
        v = new double[]{v[0] - v[1]*factor, v[0]*factor + v[1]};
        theta -= sigma*angle;
        poweroftwo /= 2;
        angle = (i+2 > angles.length)? angle/2 : angles[i+2];
    }
    return new double[]{v[0]*Kn, v[1]*Kn};
}}

      

I just tested the code with the cos PI

following:

double cosPI = MathFunctions.cordic(Math.PI, 8)[0];
System.out.printf("cos(PI) = %f%n",cosPI);

      

and for some reason he gave me -0.0

instead -1

.

+1


source to share


2 answers


The short answer is that you didn't initialize the vector v correctly. The updated code is below. Note that in java this is still not very accurate.



class MathFunctions {
  final static double[] angles = {
    0.78539816339745d, 0.46364760900081d, 0.24497866312686d, 0.12435499454676d,
    0.06241880999596d, 0.03123983343027d, 0.01562372862048d, 0.00781234106010d,
    0.00390623013197d, 0.00195312251648d, 0.00097656218956d, 0.00048828121119d,
    0.00024414062015d, 0.00012207031189d, 0.00006103515617d, 0.00003051757812d,
    0.00001525878906d, 0.00000762939453d, 0.00000381469727d, 0.00000190734863d,
    0.00000095367432d, 0.00000047683716d, 0.00000023841858d, 0.00000011920929d,
    0.00000005960464d, 0.00000002980232d, 0.00000001490116d, 0.00000000745058d};
  final static double[] Kvalues = {
    0.70710678118655d, 0.63245553203368d, 0.61357199107790d, 0.60883391251775d,
    0.60764825625617d, 0.60735177014130d, 0.60727764409353d, 0.60725911229889d,
    0.60725447933256d, 0.60725332108988d, 0.60725303152913d, 0.60725295913894d,
    0.60725294104140d, 0.60725293651701d, 0.60725293538591d, 0.60725293510314d,
    0.60725293503245d, 0.60725293501477d, 0.60725293501035d, 0.60725293500925d,
    0.60725293500897d, 0.60725293500890d, 0.60725293500889d, 0.60725293500888d};

  public static double[] cordic(double theta, int n) {
    double[] v;
    if (theta < -Math.PI/2 || theta > Math.PI/2) {
      v = (theta < 0)? cordic(theta + Math.PI, n):cordic(theta - Math.PI, n);
      return new double[]{-v[0],-v[1]};
    }
    // You didn't initialise v properly
    v = new double[] {1.0d, 0, };
    double angle=angles[0], Kn=Kvalues[Math.min(n, Kvalues.length-1)];
    double sigma, factor, poweroftwo=1;
    for (int i=0; i<n; i++) {
      sigma = (theta < 0)? -1 : 1;
      factor = sigma*poweroftwo;
      v = new double[]{v[0] - v[1]*factor, v[0]*factor + v[1]};
      theta -= sigma*angle;
      poweroftwo /= 2;
      angle = (i+2 > angles.length)? angle/2 : angles[i+2];
    }
    return new double[]{v[0]*Kn, v[1]*Kn};
  }

  public static void main(String[] args)
  {
    double[] values;
    values = MathFunctions.cordic(Math.PI, 8);
    System.out.printf("cos(PI)   = %f, sin(PI)   = %f%n",values[0], values[1]);
    values = MathFunctions.cordic(Math.PI/2, 8);
    System.out.printf("cos(PI/2) = %f, sin(PI/2) = %f%n",values[0], values[1]);
    values = MathFunctions.cordic(0, 15);
    System.out.printf("cos(0)    = %f, sin(0)    = %f%n",values[0], values[1]);
  }
}

      

+2


source


The code still has a serious bug. Code

angle = (i+2 > angles.length)? angle/2 : angles[i+2];

      



it should be

angle = (i+2 > angles.length)? angle/2 : angles[i+1];

      

+1


source







All Articles