# CORDIC Implementations

``````circular = 1
linear = 0
hyperbolic = -1

def ROM_lookup(iteration, coord_mode):
if (coord_mode == circular):
return math.degrees(math.atan(2**(-1*iteration)))
elif (coord_mode == linear):
return 2**(-1*iteration)
elif (coord_mode == hyperbolic):
return (math.atanh(2**(-1*iteration)))

def rotation_mode(x, y, z, coord_mode, iterations):
a = 0.607252935;   # = 1/K

x_val_list = []
y_val_list = []
z_val_list = []
iterations_list = []

i = 0;                  # Keeps count on number of iterations

current_x = x         # Value of X on ith iteration
current_y = y         # Value of Y on ith iteration
current_z = z         # Value of Z on ith iteration

di = 0

if (coord_mode == hyperbolic):
i = 1
else:
i = 0

flag = 0

if (iterations > 0):
while (i < iterations):
if (current_z < 0):
di = -1
else:
di = +1
next_z = current_z - di * ROM_lookup(i, coord_mode)
next_x = current_x - coord_mode * di * current_y * (2**(-1*i))
next_y = current_y + di * current_x * 2**(-1*i)

current_x = next_x
current_y = next_y
current_z = next_z

x_val_list.append(current_x)
y_val_list.append(current_y)
z_val_list.append(current_z)

iterations_list.append(i)

if (coord_mode == hyperbolic):
if ((i != 4) & (i != 13) & (i!=40)):
i = i+1
elif (flag == 0):
flag = 1
elif (flag == 1):
flag = 0
i = i+1
else:
i = i+1
return { 'x':x_val_list, 'y':y_val_list, 'z':z_val_list,
'iteration':iterations_list, }

def vector_mode(x, y, z, coord_mode, iterations):
a = 1.2075;   # = 1/K

x_val_list = []
y_val_list = []
z_val_list = []
iterations_list = []

i = 0;                  # Keeps count on number of iterations

current_x = x         # Value of X on ith iteration
current_y = y         # Value of Y on ith iteration
current_z = z         # Value of Z on ith iteration

di = 0

# This is neccesary since result for i=0 doesn't exists for hyperbolic
# co-ordinate system.
if (coord_mode == hyperbolic):
i = 1
else:
i = 0

flag = 0

if (iterations > 0):
while (i < iterations):
di = -1*math.copysign(1, current_y);#*current_x);
next_x = current_x - coord_mode * di * current_y * (2**(-1*i))
next_y = current_y + di * current_x * 2**(-1*i)
next_z = current_z - di * ROM_lookup(i, coord_mode)

current_x = next_x
current_y = next_y
current_z = next_z

x_val_list.append(current_x)
y_val_list.append(current_y)
z_val_list.append(current_z)

iterations_list.append(i)

if (coord_mode == hyperbolic):
if ((i != 4) & (i != 13) & (i!=40)):
i = i+1
elif (flag == 0):
flag = 1
elif (flag == 1):
flag = 0
i = i+1
else:
i = i+1
return { 'x':x_val_list, 'y':y_val_list, 'z':z_val_list,
'iteration':iterations_list }
``````

Alternative in c:

`````` int i = 0;
int iterations = 0; // Number of times to run the algorithm
float K = 0.6073; // K
float v_x,v_y; // Vector v; x and y components

for(i=0; i < iterations; i++) {
arctanTable[i] = atan(pow(2,-i));
}

float vnew_x;   // To store the new value of x;
for(i = 0; i < iterations; i++) {
// If beta is negative, we need to do a counter-clockwise rotation:
if( beta < 0) {
vnew_x = v_x + (v_y*pow(2,-i));
v_y -= (v_x*pow(2,-i));
beta += arctanTable[i];
}
// If beta is positive, we need to do a clockwise rotation:
else {
vnew_x = v_x - (v_y*pow(2,-i));
v_y += (v_x*pow(2,-i));
beta -= arctanTable[i];
}
v_x = vnew_x;
}
v_x *= K;
v_y *= K;
``````

# Vector Length

http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-October/002982.html

With VLENGTH being also expressible as dotproduct followed by scalar sqrt, is it reasonable to have both normalisation as well as VLENGTH as macro op fused sequences?

Vector length would presumably involve dotting a vector with itself. The potential advantage I see is that the dot product might be tempted to read that vector twice; whereas the length would only read it once. If some other mechanism eliminates the duplicate read, they would be pretty well equivalent.