## “Visualizing Quaternions” by Andrew J. HansonJuly 10th, 2009 Patrick Stein

Sunday night, I finished reading Visualizing Quaternions by Andrew J. Hanson. Unfortunately, the events of the week have kept me from writing this summary sooner. I feel like it would have been longer had I written it Monday. Alas, let’s play the cards in front of me.

This is a wonderful book. In addition to having gobs and gobs of useful content, it is a fine specimen of book design. The layout and illustrations are tremendous.

It tends to go from well-written, conversational passages that explain things in great detail to terse passages that mean nothing if you’re not a tensor-analysis whiz. But, even if you skim the parts that assume you know things you don’t, there’s still lots of book here to read.

There is even a nice appendix about Clifford algebras which folds in nicely with the complex number, quaternions, Clifford algebra posts that I’ve made here recently. If you do three-dimensional simulations or you like a good mathematical read, you should give this book a look.

## TC Lispers Meeting — July 14th, 2009July 7th, 2009 Patrick Stein

The second TC Lispers Meeting will be July 14th from 6:00pm to 8:00pm. It will be at the Common Roots Cafe on 26th and Lyndale.

Please check out the agenda at tclispers.org, and fill out the Are You Coming? poll over there, too.

## Clifford Algebras for Rotating, Scaling, and Translating SpaceJuly 6th, 2009 Patrick Stein

In (very much) earlier articles, I described:

Today, it is time to tackle rotating, translating, and scaling three-dimensional space using Clifford algebras.

### Three dimensions now instead of two

Back when we used Clifford algebras to rotate, translate, and scale the plane, we were using the two-dimesional Clifford algebra. With the two-dimensional Clifford algebra, we represented two-dimensional coordinates $(x,y)$ as $xe_1 + ye_2$. It shouldn’t surprise you then to find we’re going to represent three-dimensional coordinates $(x,y,z)$ as $xe_1 + ye_2 + ze_3$.

As before, we will have $e_1e_1 = 1$ and $e_2e_2 = 1$. Similarly, we will have $e_3e_3 = 1$. In the two-dimesional case, we showed that $e_1e_2 = -e_2e_1$. By the same logic as the two-dimensional case, we also find that $e_1e_3 = -e_3e_1$ and $e_2e_3 = - e_3e_2$. We could potentially also end up multiplying $e_1$, $e_2$, and $e_3$ all together. This isn’t going to be equal to any combination of the other things we’ve seen so we’ll just leave it written $e_1e_2e_3$.

## Why Not Return A Function?July 2nd, 2009 Patrick Stein

This morning, I was catching up on the RSS feeds I follow. I noticed an interesting snippet of code in the Abstract Heresies journal for the Discrete-time Fourier Transform. Here is his snippet of code:

(define (dtft samples)
(lambda (omega)
(sum 0 (vector-length samples)
(lambda (n)
(* (vector-ref samples n)
(make-polar 1.0 (* omega n)))))))

My first thought was That’s way too short. Then, I started reading through it. My next thought was, maybe I don’t understand scheme at all. Then, my next thought was, I do understand this code, it just didn’t do things the way I expected.

Here, I believe is a decent translation of the above into Common Lisp:

(defun dtft (samples)
#'(lambda (omega)
(loop for nn from 0 below (length samples)
summing (let ((angle (* omega nn)))
(* (aref samples nn)
(complex (cos angle) (sin angle)))))))

Now, what I find most interesting here is that most implementations you’ll find for the DTFT (Discrete-Time Fourier Transform) take an array of samples and a wavelength, and returns a result. This, instead, returns a function which you can call with a wavelength omega. It returns an evaluator. This is an interesting pattern that I will have to try to keep in mind. I have used it in some places before. But, I am sure there are other places that I should have used it, and missed. This is one where I would have missed.

Usage for the above would go something like:

(let ((dd (dtft samples)))
(dd angle1)
(dd angle2)
...)

For those not into Lisp either (who are you?), here is a rough translation into C++.

#include <cmath>
#include <complex>

class DTFT {
unsigned int len;
double* samples;

public:
DTFT( double* _samples, unsigned int _len ) {
this->len = _len;
this->samples = new double[ this->len ];
for ( unsigned int ii=0; ii < this->len; ++ii ) {
this->samples[ ii ] = _samples[ ii ];
}
}

~DTFT( void ) {
delete[] this->samples;
}

std::complex< double > operator () ( double omega ) const {
std::complex< double > sum( 0.0, 0.0 );
for ( unsigned int ii=0; ii < this->len; ++ii ) {
sum += this->samples[ ii ] * std::polar( 1.0, omega );
}
return sum;
}
};

With usage like:

DTFT dd( samples, 1024 );
dd( angle1 );
dd( angle2 );
...

So, six lines of Scheme or Lisp. Twenty-five lines of C++ including explicit definition of a class to act as a pseudo-closure, explicit copying and management of the samples buffer, etc. I suppose, a more direct translation would have used a std::vector to hold the samples and would have just kept a pointer to the buffer. That would have shaved off six or seven lines and the whole len and _len variables.