Using Computers to Compute: Calculating Sine and Cosine Using CORDIC

I gave this presentation at a Bellingham.Codes meeting on July 26th, 2018:

Using Computers to Compute: Calculating Sine and Cosine using CORDIC

Update [2023-04-04 Tue]

Unfortunately, the animations in the PDF only work in Adobe Acrobat. Evince and Sumatra PDF both show blank slides where there should be an animation of CORDIC calculating it's output. So I'm now including the contents of the presentation as HTML here. I also fixed a few minor math mistakes (but left the slides alone).

Summary

How do computers evaluate mathematical functions? In this talk I describe the CORDIC algorithm for calculating trigonometric functions on simple computers, for example a pocket calculator's microprocessor.

Introduction

Overview

I will talk briefly about the following topics:

  • What are sine and cosine?
  • How do humans do math?
  • How do simple computers do math?
  • What is CORDIC?
  • How does CORDIC work?
    • Including graphic examples

Why?

  • It's fun
  • Tau Day (6/28). Last month's meeting was a social, so this talk is late
  • History of computing
  • Math! Who doesn't like learning how to do math calculations?
    • Or at least having a computer spare us the work?

Tau Manifesto Plug

  • If you haven't read Michael Hartl's Tau Manifesto, you should.
  • tauday.com
  • Makes understanding trigonometry much easier

Sine and Cosine

Sine and Cosine

  • What are they?
  • Trigonometry. Supposedly about Triangles.
  • It's really about circles.

Sine and Cosine Illustrated

Unit Circle:
Circle of radius 1, centered at the origin, (0,0)
Theta (θ):
Angle pointing to point on a circle
Sine:
Vertical coordinate of point
Cosine:
Horizontal coordinate of point

Unit Circle showing components of a unit vector

Figure 1: Unit Circle (Credit: Wikipedia)

Why are these functions important?

  • Fundamental math
  • Used in very many engineering calculations
  • Astronomy, Surveying, Navigation, Mechanics, Radio Engineering, Signal Processing
  • Converting from rectangular to polar coordinates
  • I won't even try to list all the uses

Computing without computers

Computing before digital computers

Mathematics done on paper with reference books and a broken pencil

Tools of the Trade

  • Table books (printed spreadsheet)
  • Slide rule (fancy lookup table)
  • Pencil, paper
  • Maybe even a protractor (for minimum accuracy)
  • Did you spot the error in the previous slide?
    • \(sin \theta\) should have been 0.97029. Oops, I copied the wrong table value.

How are the tables made?

  • By hand, with Taylor series like this: \[sin x = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \frac{x^9}{9!} - \dots \] \[cos x = 1 - \frac{x^2}{2!} + \frac{x^4}{4!} - \frac{x^6}{6!} + \frac{x^8}{8!} - \dots \]
    • That's a lot of multiplications!
      • Even after clever optimizations
      • We'll get back to that in a minute

There has to be a better way!

Calculator with finger pointing towards SIN button

As Seen on TV logo

Quick side-note for the unlucky

  • If you are stuck working with pencil and paper, this book has you covered.

Front cover of the book "How to Sharpen Pencils"

Calculators

  • Okay, so we have calculators.
  • But how do they work?

Computer Math

Digital logic for math

  • Digital circuits exist to quickly calculate basic arithmetic operations
  • Addition, subtraction, bitshift, etc.
  • Bitshift is multiplication and division by powers of two only
  • Arithmetic Logic Unit (ALU)

Digital logic for math

  • Simple computers have no multiplication or division operators
  • Why? Multiplication takes multiple steps (more time) and more transistors
  • Division takes even more

A simple ALU

Schematic for the 74181 ALU IC

Figure 2: Credit: Wikipedia

  • 4-bit ALU schematic, simplified
  • Look at this thing
  • You don't want to make this even more complicated by building a multiplier too, do you?

CORDIC

Sine and cosine without multiply

  • Traditional methods of calculating sine and cosine require slow and expensive multiply circuits
  • Can we calculate sine and cosine without multiply circuits?

CORDIC

  • COordinate Rotation DIgital Computer
  • Jack E. Volder, The CORDIC Trigonometric Computing Technique, IRE Transactions on Electronic Computers, September 1959.

Photo of Jack Volder

Figure 3: Credit: Journal of VLSI Signal Processing

The CORDIC I Computer

  • Special purpose computer to demonstrate algorithm
  • 96.5773 kHz clock frequency
  • Built in 1960
  • Led to CORDIC II built for the Air Force and B-58 bomber
  • Replaced analog computers

Photo of the CORDIC I computer

Figure 4: Credit: Journal of VLSI Signal Processing

The CORDIC benefits

  • Uses only:
    • Addition
    • Subtraction
    • Bitshift
    • A small table look up
  • No multiplications!
  • Can be built with the simple ALU circuits

How was it discovered?

  • Trigonometric identities:
    • Collections of mathematical facts collected over thousands of years
  • Not obviously useful at first look, until you see one used well
  • This is an example
  • "Necessity is the mother of invention." –Jack Volder

An apology

  • I'm sorry, but I didn't have time to create images for the following slides.
  • We will all have to use our imaginations, or study this part later.
  • There are animated examples at the end.

Sneak peek

CORDIC_one.gif

Quick derivation of CORDIC 1

  • Suppose you already know the coordinates of one point on the circle with angle \(\alpha\)
    • \(sin(\alpha)\) and \(cos(\alpha)\)
  • What about another point a small angle away?
    • \(sin(\alpha+\theta)\) and \(cos(\alpha+\theta)\)

\[ sin(\alpha+\theta) = cos(\alpha) cos(\theta) - sin(\alpha) sin(\theta) \] \[ cos(\alpha+\theta) = sin(\alpha) cos(\theta) + cos(\alpha) sin(\theta) \]

  • These equations rotate a known point around the circle

Quick derivation of CORDIC 2

Coordinate Rotation:

\[ sin(\alpha+\theta) = cos(\alpha) cos(\theta) - sin(\alpha) sin(\theta) \] \[ cos(\alpha+\theta) = sin(\alpha) cos(\theta) + cos(\alpha) sin(\theta) \]

Or:

\[ x_{next} = x_{in} cos(\theta) - y_{in} sin(\theta) \] \[ y_{next} = y_{in} cos(\theta) + x_{in} sin(\theta) \]

In code:

x_next = x_in * cos(theta) - y_in * sin(theta)
y_next = y_in * cos(theta) + x_in * sin(theta)

Matrix notation

  • Graphics programmers might recognize this as an image rotation matrix

\[ P_{next} = \begin{bmatrix} x_{next} \\ y_{next} \end{bmatrix} = A P_{in}^T = \begin{bmatrix} cos \theta & -sin \theta \\ sin \theta & cos \theta \end{bmatrix} \begin{bmatrix} x_{in} \\ y_{in} \end{bmatrix}\]

Quick derivation of CORDIC 3

Math trick: divide both sides of the equation by \(cos(\theta)\).

\[ \frac{x_{next}}{cos(\theta)} = x_{in} - y_{in} tan(\theta) \] \[ \frac{y_{next}}{cos(\theta)} = y_{in} + x_{in} tan(\theta) \]

In code:

x_next = x_in - y_in * tan(theta)
y_next = y_in + x_in * tan(theta)

x_next and y_next grow each time we do this (since \(cos(x)<1\)), but we can fix that later.

Where does this get us?

  • So now we can easily add a fixed angle to any sine/cosine result and get a new point
    • If we know the arctangent of that angle
  • We can move to any angle/point by repeatedly adding a small angle (say, one degree) to a starting point, until we have the angle we want
  • Or, we can be smart about our increments: start big, and get smaller as we zero in on the answer

Binary search for angles

  • Idea: start with a quarter rotation, then an eighth, a sixteenth, etc.
  • Binary search!
  • Need to be able to rotate both forward and backwards (we can)
  • So, when our angle sum is higher than our target angle, rotate clockwise.

Final trick

  • Choose the angle of our successive jumps so that \(tan(\theta)\) is always a power of two

\[ \frac{x_{next}}{cos(\theta)} = x_{in} - y_{in} 2^{-i} \] \[ \frac{y_{next}}{cos(\theta)} = y_{in} + x_{in} 2^{-i} \]

In code:

x_next = x_in - (y_in >> i)
y_next = y_in + (x_in >> i)

Cleanup

  • Our point's distance from the origin grows each iteration
  • Start with a point inside the unit circle (K, 0)
  • It will end up on the unit circle at the end
  • I won't show the math for calculating K, but it isn't complicated

8-bit CORDIC code

/* 8-bit CORDIC algorithm for angles in first quadrant. */

const uint8_t arctan_8[8] = {
  32, 19, 10, 5, 3, 1, 1, 0
};

const int8_t K_8 = 78 - 1;

int8_point_t do_cordic_8 (uint8_t binangle) {
  /* Calculate sin, cos using CORDIC */
  /* Initialize values */
  int8_t x = K_8;
  int8_t y = 0;
  int8_t z = binangle; /* Error term */

  for (int i = 0; i < 8; i++) {
    int8_t next_x, next_y, next_z;
    if (z >= 0) {
      next_x = x - (y >> i);
      next_y = y + (x >> i);
      next_z = z - arctan_8[i];
    }
    else {
      next_x = x + (y >> i);
      next_y = y - (x >> i);
      next_z = z + arctan_8[i];
    }

    x = next_x;
    y = next_y;
    z = next_z;
  }

  int8_point_t result;
  result.x = x;
  result.y = y;

  return result;
}

Examples

  • The following examples show the CORDIC algorithm seeking the correct result
  • In eight steps it gains eight bits of precision towards the correct answer (0.4% max error)
  • Created with Dr. Geo geometry software
    • Uses Smalltalk language for scripting geometric figures

One radian

Animation of CORDIC calculations for one radian

One half radian

Animation of CORDIC calculations for half a radian

Two radians

Animation of CORDIC calculations for two radians

Zero radians

Animation of CORDIC calculations for zero radians

90 degrees

Animation of CORDIC calculations for ninety degrees

Conclusion

Any Questions?

  • Want to know more?

Bonus images

I made these after the original presentation. They show how the domain of the CORDIC calculations covers slightly more than half the unit circle. Input angles outside that domain need to be rotated before and after CORDIC.

Depth-first search space

Animation of CORDIC's search space shown depth-first

Breadth-first search space

Animation of CORDIC's search space shown breadth-first

© Copyright 2023, Remington Furman

blog@remcycles.net

@remcycles@subdued.social