<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>C++ and JavaScript Programming</title>
	<atom:link href="http://programmer209.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmer209.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Sun, 18 Sep 2011 05:29:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='programmer209.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>C++ and JavaScript Programming</title>
		<link>http://programmer209.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://programmer209.wordpress.com/osd.xml" title="C++ and JavaScript Programming" />
	<atom:link rel='hub' href='http://programmer209.wordpress.com/?pushpress=hub'/>
		<item>
		<title>How To Implement CORDIC</title>
		<link>http://programmer209.wordpress.com/2011/09/18/how-to-implement-cordic/</link>
		<comments>http://programmer209.wordpress.com/2011/09/18/how-to-implement-cordic/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 05:20:21 +0000</pubDate>
		<dc:creator>programmer209</dc:creator>
				<category><![CDATA[Assembly Language]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[CORDIC]]></category>
		<category><![CDATA[PDP-11]]></category>
		<category><![CDATA[Trigonometry]]></category>

		<guid isPermaLink="false">http://programmer209.wordpress.com/?p=559</guid>
		<description><![CDATA[References A good discussion of the CORDIC algorithm can be found here: http://en.wikibooks.org/wiki/Digital_Circuits/CORDIC The original 1959 paper by Volder: http://lapwww.epfl.ch/courses/comparith/Papers/3-Volder_CORDIC.pdf CORDIC CORDIC (Coordinate Rotation Digital Computer) is an algorithm that enables the calculation of trigonometric functions using only addition and bit shifts. The method was originally invented in the fifties by Jack Volder for aircraft [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programmer209.wordpress.com&amp;blog=9397175&amp;post=559&amp;subd=programmer209&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>References</h2>
<p style="font-size:12pt;font-family:Verdana;">
A good discussion of the CORDIC algorithm can be found here:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<a href="http://en.wikibooks.org/wiki/Digital_Circuits/CORDIC">http://en.wikibooks.org/wiki/Digital_Circuits/CORDIC</a>
</p>
<p style="font-size:12pt;font-family:Verdana;">
The original 1959 paper by Volder:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<a href="http://lapwww.epfl.ch/courses/comparith/Papers/3-Volder_CORDIC.pdf">http://lapwww.epfl.ch/courses/comparith/Papers/3-Volder_CORDIC.pdf</a>
</p>
<h2>CORDIC</h2>
<p style="font-size:12pt;font-family:Verdana;">
CORDIC (Coordinate Rotation Digital Computer) is an algorithm that enables the calculation of trigonometric functions using only addition and bit shifts. The method was originally invented in the fifties by Jack Volder for aircraft navigation systems.
</p>
<p style="font-size:12pt;font-family:Verdana;">
The basic method as described by Volder has 2 modes &#8211; Rotational and Vectoring &#8211; corresponding to the 2 basic problems this algorithm is able to solve:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>Rotational:</strong> given an angle &theta;, find Cos(&theta;) and Sin(&theta;).
</p>
<p style="font-size:12pt;font-family:Verdana;">
This problem is solved by initially defining a vector of unit length that is aligned with the x-axis. This vector is then rotated until its angle with respect to the x-axis is &theta;. The coordinates (x,y) of the rotated vector will then be equal to Cos(&theta;) and Sin(&theta;) respectively.</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>Vectoring:</strong> given a vector (x,y), find R (the magnitude) and &theta;.
</p>
<p style="font-size:12pt;font-family:Verdana;">
The vector (x,y) is just rotated until it is aligned with the x-axis. The new value of x will then give the magnitude of the vector R, while &theta; will be the angle the vector was rotated through to become aligned with the x-axis.
</p>
<h2>The Mathematics of Cordic</h2>
<p style="font-size:12pt;font-family:Verdana;">
When a vector (x,y) is rotated by an angle &theta;, the new coordinates (x&#8217;,y&#8217;) are given by the equations:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>x&#8217; = x.Cos(&theta;) &#8211; y.Sin(&theta;)</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>y&#8217; = y.Cos(&theta;) + x.Sin(&theta;)</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
Dividing through by Cos(&theta;) gives:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>x&#8217;/Cos(&theta;) = x &#8211; y.Tan(&theta;)</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>y&#8217;/Cos(&theta;) = y + x.Tan(&theta;)</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
Using the identity:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>1/Cos(&theta;) = sqrt(1 + Tan<sup>2</sup>(&theta;))</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
Gives:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>x&#8217;.sqrt(1 + Tan<sup>2</sup>(&theta;)) = x &#8211; y.Tan(&theta;)</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>y&#8217;.sqrt(1 + Tan<sup>2</sup>(&theta;)) = y + x.Tan(&theta;)</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
Cordic uses this last form of the equations to implement vector rotations. But they need to be further adjusted so that they can be implemented using only additions and bit shifts. It is these adjustments that turn Cordic into an iterative method for solving the 2 basic problems defined above.
</p>
<p style="font-size:12pt;font-family:Verdana;">
The first adjustment is to restrict the values that Tan(&theta;) can take on, to powers of negative 2. In other words, Tan(&theta;) will only be allowed to take on the values 1, 1/2, 1/4, 1/8, &#8230; etc. This allows the terms x.Tan(&theta;) and y.Tan(&theta;) to be expressed as bit shifts:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>x.Tan(&theta;) = x &gt;&gt; i</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>y.Tan(&theta;) = y &gt;&gt; i</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
Where <strong>Tan(&theta;) = 1/pow(2,i)</strong> for some i &gt;= 0.
</p>
<p style="font-size:12pt;font-family:Verdana;">
This means that only specific angles of rotation are allowed, and that any required rotation of a vector will have to be built up by summing these specific angles. So multiple rotations (iterations) will be required to reach the target angle of rotation.
</p>
<p style="font-size:12pt;font-family:Verdana;">
The second adjustment is to deal with the factor: <strong>sqrt(1 + Tan<sup>2</sup>(&theta;))</strong>. It is handled by defining x&#8221; and y&#8221; as follows:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>x&#8221; = x&#8217;.sqrt(1 + Tan<sup>2</sup>(&theta;))</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>y&#8221; = y&#8217;.sqrt(1 + Tan<sup>2</sup>(&theta;))</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
And the equations become:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>x&#8221; = x &#8211; (y &gt;&gt; i)</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>y&#8221; = y + (x &gt;&gt; i)</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
These equations describe a pseudo-rotation where the angle of rotation remains the same, but where the length of the vector will grow by the removed factor.
</p>
<p style="font-size:12pt;font-family:Verdana;">
For any given number of iterations, the growth in the length of the vector can be accounted for by pre-computing a factor known as K. Given that:
</p>
<p style="font-size:12pt;font-family:Verdana;">
<strong>sqrt(1 + Tan<sup>2</sup>(&theta;)) = sqrt(1 + 1/pow(4,i))</strong>
</p>
<p style="font-size:12pt;font-family:Verdana;">
Then for N pseudo-rotations, K is computed by multiplying all of these factors together for i = 0 to N. Since 1/pow(4,i) converges to zero, this means that the K factor will converge to a constant value after a given number of iterations.
</p>
<p style="font-size:12pt;font-family:Verdana;">
In my Javascript code below, K converges to a value of <strong>1.6467602581210654</strong> after 26 iterations.
</p>
<p style="font-size:12pt;font-family:Verdana;">
There is one final detail to be considered before the final form of the equations for the Cordic pseudo-rotations can be defined. This is the direction of the angle of pseudo-rotation, which can be either positive or negative, which means that Tan(&theta;) will be either positive or negative. This is handled by including the term d(i) in the equations, which will be either 1 or -1 depending on the direction of rotation. So the final form of the equations for a pseudo-rotation is:
</p>
<table style="margin-left:15px;margin-top:10px;" border="0" bgcolor="#eeeeee">
<tr>
<td>
<pre style="font-size:11pt;font-family:Lucida Console;">
x(i+1) = x(i) - d(i).(y(i) &gt;&gt; i)

y(i+1) = y(i) + d(i).(x(i) &gt;&gt; i)

z(i+1) = z(i) - d(i).atan(pow(2,i))
</pre>
</td>
</tr>
</table>
<p style="font-size:12pt;font-family:Verdana;">
The z term is the current angle of rotation for the vector (x,y). The atan term gives the angle being added for each i.
</p>
<p style="font-size:12pt;font-family:Verdana;">
For each of the 2 modes of Cordic, the above equations are applied as below. The K length factor is accounted for by building it into the initial vector, which means that the final vector will be of the correct length.
</p>
<h2>Rotational Mode</h2>
<table style="margin-left:15px;margin-top:10px;" border="0" bgcolor="#eeeeee">
<tr>
<td>
<pre style="font-size:11pt;font-family:Lucida Console;">
Find Cos(&theta;) and Sin(&theta;), where -90<sup>o</sup> &lt;= &theta; &lt;= 90<sup>o</sup>:

Start with the vector x = 1/K and y = 0.

Rotate the vector towards the target angle &theta; as follows:

- if z(i) &lt; &theta;, set d(i) = 1.

- if z(i) &gt;= &theta;, set d(i) = -1.
</pre>
</td>
</tr>
</table>
<h2>Vectoring Mode</h2>
<table style="margin-left:15px;margin-top:10px;" border="0" bgcolor="#eeeeee">
<tr>
<td>
<pre style="font-size:11pt;font-family:Lucida Console;">
Find (R,&theta;) for the vector (x,y), where x &gt;= 0:

The target angle is 0 (the x axis).

Start with the vector x(0) = x/K and y(0) = y/K.

Rotate the vector towards the target angle 0 as follows:

- if z(i) &lt; 0, set d(i) = 1.

- if z(i) &gt;= 0, set d(i) = -1.
</pre>
</td>
</tr>
</table>
<h2>Implementation</h2>
<p style="font-size:12pt;font-family:Verdana;">
The aim of this project is to implement Cordic in assembly language using only shifts, adds and table lookups. To do this I will be using my PDP-11 assembly language simulator.
</p>
<h2>Javascript &#8211; Floating Point</h2>
<p style="font-size:12pt;font-family:Verdana;">
To begin with I write a version in Javascript using floating point numbers, to demonstrate the basic approach to implementing Cordic. Since this is using floating point numbers, there is no need to use the bit shifts as discussed above.
</p>
<p style="font-size:12pt;font-family:Verdana;">
Note: input angles are in degrees.
</p>
<table style="margin-left:15px;margin-top:10px;" border="0" bgcolor="#eeeeee">
<tr>
<td>
<pre style="font-size:11pt;font-family:Lucida Console;">
&lt;html&gt;

&lt;head&gt;

&lt;title&gt;CORDIC&lt;/title&gt;

&lt;style type="text/css"&gt;

*
{
 font-family: "Lucida Console";

 font-size: 11pt;
}

&lt;/style&gt;

&lt;/head&gt;

&lt;script type="text/javascript"&gt;

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Calc_Rotation()
{
 // CORDIC : Rotation Mode

 // Rotate the vector (1/K,0) through theta degrees,

 // to get cos(theta) and sin(theta). 

 var theta = parseFloat(document.getElementById("angle").value);

 if(theta &gt; 90 || theta &lt; -90)
 {
  document.getElementById("txtOut").value = "Theta must be in the range: [-90, 90].";

  return;
 }

 // calc K after 32 iterations:

 var K = calc_K(32);

 // the vector (x,y):

 var x = 1/K;

 var y = 0;

 // the initial angle, 0 degrees:

 var z = 0;

 // the array of angles to add to z:

 var atan_arr = [];

 atan_arr = calcAtanArr();

 var out_str = col_print(x) + col_print(y) + col_print(z) + "&#092;r&#092;n&#092;r&#092;n";

 // perform 32 iterations (pseudo-rotations):

 for(var i=0;i&lt;32;i++)
 {
  // tan(i) = 1, 1/2, 1/4, 1/8, ...

  var tan_i = 1/Math.pow(2,i);

  // the direction of rotation:

  var dir = -1;

  if(z &lt; theta)
  {
   dir = 1;
  }

  z += dir * atan_arr[i];

  var x_i = x - (dir * y * tan_i);

  var y_i = y + (dir * x * tan_i);

  x = x_i;

  y = y_i;

  out_str += col_print(x) + col_print(y) + col_print(z) + "&#092;r&#092;n";
 }

 document.getElementById("txtOut").value = out_str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Calc_Vector()
{
 // CORDIC : Vectoring Mode

 // Rotate the vector (x,y) to the x-axis,

 // to get R and theta. 

 var x = parseFloat(document.getElementById("x_input").value);

 var y = parseFloat(document.getElementById("y_input").value);

 // calc K after 32 iterations:

 var K = calc_K(32);

 // the vector (x,y):

 x = x/K; 

 y = y/K; 

 var theta = 0;

 // the array of angles to add to theta:

 var atan_arr = [];

 atan_arr = calcAtanArr();

 var out_str = col_print(x) + col_print(y) + col_print(theta) + "&#092;r&#092;n&#092;r&#092;n";

 // perform 32 iterations (pseudo-rotations):

 for(var i=0;i&lt;32;i++)
 {
  // tan(i) = 1, 1/2, 1/4, 1/8, ...

  var tan_i = 1/Math.pow(2,i);

  // the direction of rotation:

  var dir = -1;

  if(y &gt; 0)
  {
   dir = 1;
  }

  theta += dir * atan_arr[i];

  var x_i = x + (dir * y * tan_i);

  var y_i = y - (dir * x * tan_i);

  x = x_i;

  y = y_i;

  out_str += col_print(x) + col_print(y) + col_print(theta) + "&#092;r&#092;n";
 }

 document.getElementById("txtOut").value = out_str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function calcAtanArr()
{
 var tmp_arr = [];

 for(var i=0;i&lt;32;i++)
 {
  tmp_arr[i] = (360/(2*Math.PI)) * Math.atan(1/Math.pow(2,i));
 }

 return tmp_arr;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function calc_K(N)
{
 var K;

 var prev_K=1;

 for(var i=0;i&lt;N;i++)
 {
  K = 1/Math.pow(2,i);

  K *= K;

  K += 1;

  K = Math.sqrt(K);

  K *= prev_K;

  prev_K = K;
 }

 return K;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function col_print(val)
{
 var str = val.toFixed(10);

 while(str.length &lt; 16)
 {
  str += " ";
 }

 return str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Show_Atan()
{
 var atan_arr = calcAtanArr();

 var str = "";

 for(var i=0;i&lt;32;i++)
 {
  str += col_print(atan_arr[i]) + "&#092;r&#092;n";
 }

 document.getElementById("txtOut").value = str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Clear()
{
 document.getElementById("txtOut").value = "";
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

&lt;/script&gt;

&lt;body&gt;

&lt;input type="text" id="angle" size="10"&gt;

&lt;input type="button" value="Calc (x,y)" onclick="Calc_Rotation()"&gt;

&lt;input type="text" id="x_input" size="10"&gt;

&lt;input type="text" id="y_input" size="10"&gt;

&lt;input type="button" value="Calc (R,&amp;theta;)" onclick="Calc_Vector()"&gt;

&lt;input type="button" value="Show Atan" onclick="Show_Atan()"&gt;

&lt;input type="button" value="Clear" onclick="Clear()"&gt;

&lt;br&gt;&lt;br&gt;

&lt;textarea id="txtOut" rows="38" cols="80"&gt;&lt;/textarea&gt;

&lt;/body&gt;

&lt;/html&gt;
</pre>
</td>
</tr>
</table>
<h2>Javascript &#8211; Fixed Point</h2>
<p style="font-size:12pt;font-family:Verdana;">
Next, the above code is modified such that the values x, y, z and theta are represented as 32-bit signed integers (as they would have to be in an assembly language program targeted to a processor of limited power that did not have a Floating Point Unit). The scheme where a floating point number is represented by a large integer is known as fixed point.
</p>
<p style="font-size:12pt;font-family:Verdana;">
The floating point values are scaled up to 32 bit signed integers as follows:
</p>
<p style="font-size:12pt;font-family:Verdana;">
For the rotational mode, x and y are scaled up to a 32-bit signed integer by multiplying by 2 to the power of 30. In other words, x and y are simply bit shifted to the left by 30 bits. This is valid because |x| and |y| (since they represent Cos(&theta;) and Sin(&theta;)) will never be greater than 1. Theta is scaled up in the same way, but is first divided by 100 (so that it can never be more than 1).
</p>
<p style="font-size:12pt;font-family:Verdana;">
For the vectoring mode, x and y are allowed to be greater than 1. Therefore, both x and y are divided by the factor (x+y) before being scaled up to large integers. Theta is scaled up in the same way as it was for the rotational mode.
</p>
<p style="font-size:12pt;font-family:Verdana;">
Since the core logic in this code (the Cordic iterations) is to be implemented in PDP-11 assembly language, the program outputs the scaled integer values in octal, which gives something against which the PDP-11 code can be tested.
</p>
<p style="font-size:12pt;font-family:Verdana;">
Note that the 2 versions of the Javascript program given in this post both use 32 iterations to calculate Cordic. This is the correct number of iterations to use for a value whose precision is 32 bits. If any more than 32 iterations were used, it would have no effect on the final result because in the cordic equations the result of the bit shifts would be zero once i reached values of 32 and above.
</p>
<table style="margin-left:15px;margin-top:10px;" border="0" bgcolor="#eeeeee">
<tr>
<td>
<pre style="font-size:11pt;font-family:Lucida Console;">
&lt;html&gt;

&lt;head&gt;

&lt;title&gt;CORDIC&lt;/title&gt;

&lt;style type="text/css"&gt;

*
{
 font-family: "Lucida Console";

 font-size: 11pt;
}

&lt;/style&gt;

&lt;/head&gt;

&lt;script type="text/javascript"&gt;

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Calc_Rotation()
{
 // CORDIC : Rotation Mode

 // Rotate the vector (1/K,0) through theta degrees,

 // to get cos(theta) and sin(theta). 

 var theta = parseFloat(document.getElementById("angle").value);

 if(theta &gt; 90 || theta &lt; -90)
 {
  document.getElementById("txtOut").value = "Theta must be in the range: [-90, 90].";

  return;
 }

 // Scale theta:

 theta = scale_32(theta/100);

 // calc K after 32 iterations:

 var K = calc_K(32);

 // the vector (x,y):

 var x = 1/K;

 var y = 0;

 // the initial angle, 0 degrees:

 var z = 0;

 // Scale (x,y,z):

 x = scale_32(x);

 y = scale_32(y);

 z = scale_32(z/100);

 // the array of angles to add to z:

 var atan_arr = [];

 atan_arr = calcAtanArr();

 var out_str = "Input (X, Y, Theta) - 32 Bit Scaled Integers (in octal):&#092;r&#092;n&#092;r&#092;n";

 out_str += col_print_int(x) + col_print_int(y) + col_print_int(theta) + "&#092;r&#092;n&#092;r&#092;n";

 out_str += "Cordic - 32 x pseudo-rotations:&#092;r&#092;n&#092;r&#092;n";

 // perform 32 iterations (pseudo-rotations):

 for(var i=0;i&lt;32;i++)
 {
  // the direction of rotation:

  var dir = -1;

  if(z &lt; theta)
  {
   dir = 1;
  }

  z = Add_32(z,dir * atan_arr[i]);

  var x_i = x;

  var y_i = y;

  x_i = Sub_32(x_i,dir * (y &gt;&gt; i));

  y_i = Add_32(y_i,dir * (x &gt;&gt; i));

  x = x_i;

  y = y_i;

  out_str += col_print_int(x) + col_print_int(y) + col_print_int(z) + "&#092;r&#092;n";
 }

 // Unscale (x,y,z):

 x = unscale_32(x);

 y = unscale_32(y);

 z = 100*unscale_32(z);

 out_str += "&#092;r&#092;nResult - Unscaled:&#092;r&#092;n&#092;r&#092;n";

 out_str += col_print(x) + col_print(y) + col_print(z) + "&#092;r&#092;n";

 document.getElementById("txtOut").value = out_str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Calc_Vector()
{
 // CORDIC : Vectoring Mode

 // Rotate the vector (x,y) to the x-axis, to get R and theta: 

 var x = parseFloat(document.getElementById("x_input").value);

 var y = parseFloat(document.getElementById("y_input").value);

 // calc K after 32 iterations:

 var K = calc_K(32);

 // the vector (x,y):

 x = x/K; 

 y = y/K;

 // Scale (x,y):

 var max = x + y;

 var shift = 30;

 while(max &gt;= 1)
 {
  max = max/2;

  shift--;
 }

 x = (x * Math.pow(2,shift)) &amp; 0xffffffff;

 y = (y * Math.pow(2,shift)) &amp; 0xffffffff;

 var theta = 0;

 // the array of angles to add to theta:

 var atan_arr = [];

 atan_arr = calcAtanArr();

 var out_str = "Input (X, Y, Theta) - 32 Bit Scaled Integers (in octal):&#092;r&#092;n&#092;r&#092;n";

 out_str += col_print_int(x) + col_print_int(y) + col_print_int(theta) + "&#092;r&#092;n&#092;r&#092;n";

 out_str += "Cordic - 32 x pseudo-rotations:&#092;r&#092;n&#092;r&#092;n";

 // perform 32 iterations (pseudo-rotations):

 for(var i=0;i&lt;32;i++)
 {
  // the direction of rotation:

  var dir = -1;

  if(y &gt; 0)
  {
   dir = 1;
  }

  theta = Add_32(theta,dir * atan_arr[i]);

  var x_i = x;

  var y_i = y;

  x_i = Add_32(x_i,dir * (y &gt;&gt; i));

  y_i = Sub_32(y_i,dir * (x &gt;&gt; i));

  x = x_i;

  y = y_i;

  out_str += col_print_int(x) + col_print_int(y) + col_print_int(theta) + "&#092;r&#092;n";
 }

 // Unscale (x,y,theta):

 x = x/Math.pow(2,shift);

 y = y/Math.pow(2,shift);

 theta = 100*unscale_32(theta);

 out_str += "&#092;r&#092;nResult - Unscaled:&#092;r&#092;n&#092;r&#092;n";

 out_str += col_print(x) + col_print(y) + col_print(theta) + "&#092;r&#092;n";

 document.getElementById("txtOut").value = out_str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function scale_32(a)
{
 // scale up a float value to a 32-bit 2's complement integer:

 var result = a * Math.pow(2,30);

 return (result &amp; 0xffffffff);
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function unscale_32(a)
{
 // unscale a 32-bit 2's complement integer, back to a float value:

 return a/Math.pow(2,30);
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Add_32(a,b)
{
 // 32-bit two's complement addition:

 var c = (a&gt;&gt;&gt;0) + (b&gt;&gt;&gt;0);

 c &amp;= 0xffffffff;

 return c;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Sub_32(a,b)
{
 // 32-bit two's complement subtraction:

 var c = ~(b&gt;&gt;&gt;0) + 1;

 c += (a&gt;&gt;&gt;0);

 c &amp;= 0xffffffff;

 return c;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function calcAtanArr()
{
 var tmp_arr = [];

 for(var i=0;i&lt;32;i++)
 {
  tmp_arr[i] = (360/(2*Math.PI)) * Math.atan(1/Math.pow(2,i));

  tmp_arr[i] = scale_32(tmp_arr[i]/100);
 }

 return tmp_arr;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function calc_K(N)
{
 var K;

 var prev_K=1;

 for(var i=0;i&lt;N;i++)
 {
  K = 1/Math.pow(2,i);

  K *= K;

  K += 1;

  K = Math.sqrt(K);

  K *= prev_K;

  prev_K = K;
 }

 return K;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function col_print_int(val)
{
 var str = val.toString();

 // print a 32 bit integer as two 16 bit words - in octal:

 var upper = (val &gt;&gt;&gt; 16) &amp; 0xffff;

 var lower = val &amp; 0xffff;

 var tmp = upper.toString(8);

 while(tmp.length &lt; 6) tmp = " " + tmp;

 str = tmp + "  ";

 tmp = lower.toString(8);

 while(tmp.length &lt; 6) tmp = " " + tmp;

 str += tmp + "      ";

 return str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function col_print(val)
{
 // print a float value to 10 decimal places:

 var str = val.toFixed(10);

 while(str.length &lt; 20)
 {
  str += " ";
 }

 return str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Show_Atan()
{
 // print atan[i] as 32 bit octal values:

 var atan_arr = calcAtanArr();

 var i;

 var str = "";

 for(i=0;i&lt;32;i++)
 {
  str += col_print_int(atan_arr[i]) + "&#092;r&#092;n";
 }

 document.getElementById("txtOut").value = str;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Clear()
{
 document.getElementById("txtOut").value = "";
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

&lt;/script&gt;

&lt;body&gt;

&lt;input type="text" id="angle" size="10"&gt;

&lt;input type="button" value="Calc (x,y)" onclick="Calc_Rotation()"&gt;

&lt;input type="text" id="x_input" size="10"&gt;

&lt;input type="text" id="y_input" size="10"&gt;

&lt;input type="button" value="Calc (R,&amp;theta;)" onclick="Calc_Vector()"&gt;

&lt;input type="button" value="Show Atan" onclick="Show_Atan()"&gt;

&lt;input type="button" value="Clear" onclick="Clear()"&gt;

&lt;br&gt;&lt;br&gt;

&lt;textarea id="txtOut" rows="43" cols="80" spellcheck="false"&gt;&lt;/textarea&gt;

&lt;/body&gt;

&lt;/html&gt;
</pre>
</td>
</tr>
</table>
<h2>PDP-11 Implementation &#8211; 32 Bit</h2>
<p style="font-size:12pt;font-family:Verdana;">
The PDP-11 assembly language code here was written using my <a href="http://programmer209.wordpress.com/2011/08/14/pdp-11-assembly-language-simulator/">PDP-11 Assembly Language Simulator</a>.
</p>
<p style="font-size:12pt;font-family:Verdana;">
This code only implements the rotational mode of Cordic. The inputs and outputs from this code are the 32-bit fixed point integer representations of the floating point values (x, y, z) and theta. These values are scaled as described above. The PDP-11 code here does not do the actual scaling of course.
</p>
<p style="font-size:12pt;font-family:Verdana;">
Since the PDP-11 is a 16-bit machine, but we are using 32-bit integers, the code below uses double words.
</p>
<p style="font-size:12pt;font-family:Verdana;">
The value x is initialised to X_H = 23335 and X_L = 35552, which is the 32-bit octal representation of 1/K. The values y and z are initialised to zero. No matter what the input angle, (x, y, z) are always initialised to these values.
</p>
<p style="font-size:12pt;font-family:Verdana;">
For this example, theta is set to -30 degrees. In the fixed point octal representation this is: TH_H = 166314 and TH_L = 146315. This is the only part of the code that needs to be changed, if a different input angle theta is wanted.
</p>
<p style="font-size:12pt;font-family:Verdana;">
The set of angles of rotation for each i are stored as an array in the code, starting from the label ATAN_I (in the 32-bit fixed point representation of course).
</p>
<table style="margin-left:15px;margin-top:10px;" border="0" bgcolor="#eeeeee">
<tr>
<td>
<pre style="font-size:11pt;font-family:Lucida Console;">
; CORDIC - (32 bit)

; Rotational Mode - find Cos(theta) and Sin(theta)

mov #ATAN_I p_ARR

loop:

; N = 32 to 1

mov N Shift

; Shift = 0 to -31

sub #32d Shift

; dir = 1

mov #1 DIR

; is (z - theta) &lt; 0 ?

mov Z_H r0
mov Z_L r1

mov TH_H r2
mov TH_L r3

sub r3 r1
sbc r0
sub r2 r0

tst r0

bmi rotate

; dir = -1

neg DIR

rotate:

; get atan[i] and increment p_ARR

mov @p_ARR ATAN_H
add #2 p_ARR
mov @p_ARR ATAN_L
add #2 p_ARR

; which direction ?

tst DIR

bpl next_1

; negate atan[i]

com ATAN_L
com ATAN_H
add #1 ATAN_L
adc ATAN_H

next_1:

; z = z + atan[i]

add ATAN_L Z_L
adc Z_H
add ATAN_H Z_H

; x1 = x

mov X_H X1_H
mov X_L X1_L

; y1 = y

mov Y_H Y1_H
mov Y_L Y1_L

; x &gt;&gt; i

mov X_H r0
mov X_L r1
ashc Shift r0

; y &gt;&gt; i

mov Y_H r2
mov Y_L r3
ashc Shift r2

; which direction ?

tst DIR

bpl next_2

; negate (x &gt;&gt; i)

com r1
com r0
add #1 r1
adc r0

; negate (y &gt;&gt; i)

com r3
com r2
add #1 r3
adc r2

next_2:

; x1 = x - (y &gt;&gt; i)

sub r3 X1_L
sbc X1_H
sub r2 X1_H

; y1 = y + (x &gt;&gt; i)

add r1 Y1_L
adc Y1_H
add r0 Y1_H

; update x = x1

mov X1_H X_H
mov X1_L X_L

; update y = y1

mov Y1_H Y_H
mov Y1_L Y_L

dec N

bne loop

halt

; loop counter = 32 to 1

N: .word 32d

; left shift = (N - 32) = 0 to -31

Shift: .word

; direction of rotation = -1 or +1

DIR: .word

; x, y and z

X_H: .word 23335
X_L: .word 35552
Y_H: .word
Y_L: .word
Z_H: .word
Z_L: .word

; x1 and y1 = temp x and y 

X1_H: .word
X1_L: .word
Y1_H: .word
Y1_L: .word

; theta

TH_H: .word 166314
TH_L: .word 146315

; atan for the current i = (N - 32)

ATAN_H: .word
ATAN_L: .word

; pointer to atan[i]

p_ARR: .word

; atan[i] = atan(pow(2,-i)) for i = 0 to 31

ATAN_I:

.word 16314, 146314
.word 10400, 65401
.word 4373, 131270
.word 2217, 56330
.word 1111, 171125
.word 445, 41112
.word 222, 125116
.word 111, 53114
.word 44, 125512
.word 22, 52652
.word 11, 25325
.word 4, 112552
.word 2, 45265
.word 1, 22532
.word 0, 111255
.word 0, 44526
.word 0, 22253
.word 0, 11125
.word 0, 4452
.word 0, 2225
.word 0, 1112
.word 0, 445
.word 0, 222
.word 0, 111
.word 0, 44
.word 0, 22
.word 0, 11
.word 0, 4
.word 0, 2
.word 0, 1
.word 0, 0
.word 0, 0

.end 0
</pre>
</td>
</tr>
</table>
<h2>PDP-11 Implementation &#8211; 16 Bit</h2>
<p style="font-size:12pt;font-family:Verdana;">
This version uses 16-bit integers to represent the values x, y, z and theta. The floating point values are scaled up to 16-bit signed integers by multiplying by 2 to the power of 14.
</p>
<p style="font-size:12pt;font-family:Verdana;">
Here, only 16 iterations of Cordic are computed (instead of 32 iterations as for the 32-bit version above). Also, K is computed for i = 0 to 15 only, giving K = <strong>1.6467602578654548</strong>. This will make no difference however, since K for N=16 and K for N=32 only differ in the last few decimal places.
</p>
<p style="font-size:12pt;font-family:Verdana;">
In the code below, x is initialised to 23335, which is the 16-bit octal fixed point integer representation of 1/K. As before, y and z are initialised to 0. No matter what the input angle theta is, (x,y,z) are always initialised to these values.
</p>
<p style="font-size:12pt;font-family:Verdana;">
Theta is initialised to 166315 which is the scaled octal integer representation of -30 degrees. The scaled integer representation of theta is calculated by first dividing theta by 100 and then multiplying by 2 to the power of 14.
</p>
<p style="font-size:12pt;font-family:Verdana;">
Of course this version won&#8217;t be as accurate as the 32-bit version. When converted back to floating point, the output values are only accurate to about 3 or 4 decimal places.
</p>
<table style="margin-left:15px;margin-top:10px;" border="0" bgcolor="#eeeeee">
<tr>
<td>
<pre style="font-size:11pt;font-family:Lucida Console;">
; CORDIC - (16 bit)

; Rotational Mode - find Cos(theta) and Sin(theta)

mov #ATAN_I p_ARR

loop:

; N = 16 to 1

mov N Shift

; Shift = 0 to -15

sub #16d Shift

; dir = 1

mov #1 DIR

; is (z - theta) &lt; 0 ?

mov Z r0
mov THETA r1

sub r1 r0

tst r0

bmi rotate

; dir = -1

neg DIR

rotate:

; get atan[i] and increment p_ARR

mov @p_ARR ATAN
add #2 p_ARR

; which direction ?

tst DIR

bpl next_1

; negate atan[i]

neg ATAN

next_1:

; z = z + atan[i]

add ATAN Z

; x1 = x and y1 = y

mov X X1
mov Y Y1

; x &gt;&gt; i

mov X r0
ash Shift r0

; y &gt;&gt; i

mov Y r1
ash Shift r1

; which direction ?

tst DIR

bpl next_2

; negate (x &gt;&gt; i) and (y &gt;&gt; i)

neg r0
neg r1

next_2:

; x1 = x - (y &gt;&gt; i)

sub r1 X1

; y1 = y + (x &gt;&gt; i)

add r0 Y1

; update x = x1 and y = y1

mov X1 X
mov Y1 Y

dec N

bne loop

halt

; loop counter = 16 to 1

N: .word 16d

; left shift = (N - 16) = 0 to -15

Shift: .word

; direction of rotation = -1 or +1

DIR: .word

; x, y and z

X: .word 23335
Y: .word
Z: .word

; x1 and y1 = temp x and y 

X1: .word
Y1: .word

; theta

THETA: .word 166315

; atan for the current i = (N - 16)

ATAN: .word

; pointer to atan[i]

p_ARR: .word

; atan[i] = atan(pow(2,-i)) for i = 0 to 15

ATAN_I:

.word 16314
.word 10400
.word 4373
.word 2217
.word 1111
.word 445
.word 222
.word 111
.word 44
.word 22
.word 11
.word 4
.word 2
.word 1
.word 0
.word 0

.end 0
</pre>
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programmer209.wordpress.com/559/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programmer209.wordpress.com/559/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programmer209.wordpress.com/559/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programmer209.wordpress.com/559/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programmer209.wordpress.com/559/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programmer209.wordpress.com/559/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programmer209.wordpress.com/559/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programmer209.wordpress.com/559/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programmer209.wordpress.com/559/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programmer209.wordpress.com/559/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programmer209.wordpress.com/559/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programmer209.wordpress.com/559/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programmer209.wordpress.com/559/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programmer209.wordpress.com/559/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programmer209.wordpress.com&amp;blog=9397175&amp;post=559&amp;subd=programmer209&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programmer209.wordpress.com/2011/09/18/how-to-implement-cordic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/99e1879ccb0d18d1ae2681071def84c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">programmer209</media:title>
		</media:content>
	</item>
	</channel>
</rss>
