Understanding the CORDIC algorithm with Python

Hello, I've been trying to figure out the way the CORDIC algorithm works and I am not sure if this is the right place to post this, so feel free to point me in the right direction to get help.

I usually code a quick prototype in python for verification and understanding of an algorithm I need to implement. For those of you who don't know Python but know C, you should be able to follow it since python has a similar syntax to C. I've been struggling with this CORDIC algorithm, seems straight forward from the wikipedia page, but somehow I messing something up.

import math

# I know CORDIC is only valid for inputs between # -pi/2 and pi/2; I am not exactly sure what I need # to do add to make it where any input is acceptable # I believe is keep on adding/subtracting pi, but I don't # get why this works? def cordic_trig(beta,N=40): # in hardware, put this in a table. def K_vals(n): K = [] acc = 1.0 for i in range(0, n): acc = acc * (1.0/math.sqrt(1 + 2.0**(-2*i))) K.append(acc) return K

#K = K_vals(N) K = 0.6072529350088812561694 # emulation for hardware lookup table atans = [math.atan(2.0**(-i)) for i in range(0,N)] #print K #print atans x = 1 y = 0

for i in range(0,N): d = 1.0 if beta < 0: d = -1.0

x = (x - (d*(2.0**(-i))*y)) y = ((d*(2.0**(-i))*x) + y) # in hardware put the atan values in a table beta = beta - (d*math.atan(2**(-i))) return (K*x, K*y)

if __name__ == '__main__': beta = math.pi/6.0 print "Actual cos(%f) = %f" % (beta, math.cos(beta)) print "Actual sin(%f) = %f" % (beta, math.sin(beta)) cos_val, sin_val = cordic_trig(beta) print "CORDIC cos(%f) = %f" % (beta, cos_val) print "CORDIC sin(%f) = %f" % (beta, sin_val)

Reply to
Chico
Loading thread data ...

You're calculating y[i+1] from x[i+1], when it should be x[i].

Rewriting the above as:

(x,y) = (x - (d*(2.0**(-i))*y), (d*(2.0**(-i))*x) + y)

to update x and y concurrently gives the correct result.

Reply to
Nobody

y)

Thank you so much for the help (whoever you are), those are little subtle bugs that can drive you crazy. Now I know why our Prof. in Functional programming was making a big deal out of assignment statements! :)

As for the domain between -pi/2 and pi/2 do I just keep adding/ subtracting until I get it within that domain? Thanks.

Reply to
Chico

Usually with embedded trig algorithms you just implement a single quadrant (0 to pi/2), but you can use a half-circle if you want. And yes, it's mostly a matter of adding/subtracting. But for some quadrants you might need to negate the angle, or the result - I'll let you figure out the details yourself.

This is the first time I've heard someone describe Python syntax as being "similar to C" - it's about as different as you could get while still remaining an imperative programming language. But a well-written Python program should be fairly easily understood by C programmers.

When posting sample code in a newsgroup (or other public forum), it's a good idea to cut out unnecessarily or old code - keep it to a minimum. Including the nested function K_vals(), for example, serves only to confuse.

Reply to
David Brown

For any trigonometric function f, start by using the 2*pi periodicity, f(x+2*n*pi) = f(x) to coerce the value into the range 0..2*pi, e.g. x = x % 2*pi or x = x - 2*pi * floor(x / 2*pi) (but check how % handles negative values).

Then, for values outside of the range 0..pi/2, use the identities:

sin(x) = sin(pi - x) for pi/2

Reply to
Nobody

Also known as the ASTC rule

All, Sin, Tan, Cos

For the quadrants from 0 (rad/degree) that results are positive for.

--
Paul Carpenter          | paul@pcserviceselectronics.co.uk
    PC Services
 Timing Diagram Font
  GNU H8 - compiler & Renesas H8/H8S/H8 Tiny
 For those web sites you hate
Reply to
Paul Carpenter

es

cos, tan =3D -tan

n, cos =3D -cos

an =3D -tan

At school we learned that the trig functions that are positive in each quadrant are:

Quadrant +ve Mnemonic

0..pi/2 sin, cos, tan All pi/2..pi sin Stations pi..3*pi/2 tan To 3*pi/2..2*pi cos Crewe

Might mean something if you are English ;->

Reply to
s0lstice

If you represent angle such that 0 to pi maps to 0 to 2^n then getting within the domain only requires a bit-mask (no iteration).

Bob

Reply to
Bob

... snip ...

Much simpler, and not language dependent, is just think of the signs applied to the x and y axis when you draw a rt triangle in it. x is positive with displacement to right, y with displacement up. Now all you need to remember is what sin, cos, tan mean, i.e. the ratio of which sides.

--
 [mail]: Chuck F (cbfalconer at maineline dot net) 
 [page]: 
            Try the download section.
Reply to
CBFalconer

Your basic "unit circle" definitions. Sometimes, I wonder if it is even taught, anymore. Few younger folks in today's college calculus classes seem to even know about it -- and my latest experience with them was this last Winter term. Yet it's what I always go back to if I want to gain some insight on a new question (or one I have long since forgotten about.) You can't go wrong with that and Pythagorean. You also get all your half-angle and double-angle equivalences, etc. It's all there to be had with merely a gander.

Also, there are symmetries to exploit beyond the 180 or 90 degree ones that I've seen mentioned in this thread. At a minimum, octants (or 45 degrees) are your basic brain-dead demarcation for calculation. More is still possible. For those whose approximation exposure has been sadly limited only to the very easily understood Taylor's theorem, then if for no other reason than the fact that staying closer in range to where the approximation was taken improves retained precision per cpu cycle consumed.

Jon

Reply to
Jon Kirwan

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.