Here are some simple tools to test ideas about the series of division algebras: reals, complex, quaternions, octonions, etc. There is nothing new here mathematically. The computer language below is Scheme. This may provide enough Scheme to read the program. You can also watch a parallel version in ocaml.

We define below a function G that takes a division algebra and returns another. G(reals) = complex. G(complex) = quaternions. G(quaternions) = octonions. A division algebra is coded here as a list of field tools such as documented in this field package, but prepended with a conjugate operator and a sample generator. This code is inspired by Bob Andersen’s presentation of Division Algebras which introduces the Cayley-Dickson construction. Some zero divisors. See DivisionAlgebra and k4ZerDiv here.

We build on the ideas described in the field matrix package. Considering that a*b* = (ba)* for our algebras, and that * is an automorphism, the theorem a(b+c)=ab+ac follows from the theorem (a+b)c=ac+bc.

Here are some comments on the following code. Include the definitions of Do and grc4.

(define (G f) 
(apply (lambda (conj sg zer zer? one + - * inv) (list
  (lambda (x) (cons (conj (car x)) (- zer (cdr x)))) ; new conjugate
  (lambda () (cons (sg) (sg))) ; new sample generator
  (cons zer zer) ; new zero
  (lambda (a) (and (zer? (car a)) (zer? (cdr a)))) ; new zero test
  (cons one zer) ; new multiplicative unit
  (lambda (a b) (cons (+ (car a)(car b))(+ (cdr a)(cdr b)))) ; new add
  (lambda (a b) (cons (- (car a)(car b))(- (cdr a)(cdr b)))) ; new subtract
  (lambda (a b) (cons (- (* (car a)(car b))(* (conj (cdr b))(cdr a))) ; new multiply
                      (+ (* (cdr b)(car a))(* (cdr a)(conj (car b))))))
  (lambda (x) (let ((d (inv   ; new inverse
      (+ (* (car x)(conj (car x))) (* (cdr x)(conj (cdr x)))))))
          (cons (* d (conj (car x)))(- zer (* d (cdr x)))))))) f))

(define rr (let ((ig (grc4 "fliser"))) (lambda ()(/ (ig 1)(+ 1 (ig 1))))))

(define reals (list
   (lambda (x) x) rr
   0 zero? 1 + - *
   (lambda (x) (/ x))))
grnd is a 0 parameter function that returns a (real) floating random normal deviate which might stand in for rr in reals for some purposes.

There is a trick that bears on finding multiplicative inverses in each of these algebras. Understanding the trick may be germane to understanding why the octonions are the end of the road. The original trick was to notice that the reciprocal of 6+√5 could be found by noting that (6+√5)(6−√5) = 36−5 = 31 and thus 1/(6+√5) = (6−√5)/31. The same trick takes on new meaning for finding the reciprocal of z = a + ib. Taking z* = a − ib we note that zz* = a2 + b2 is real. The magnitude of zz* is manifest so we seek 1/z as z*/(zz*). These tricks work as long as zz* is real and enough familiar algebra rules remain. For quaternions z* comes from inverting the sign of the vector component of z. That xy + yx = 0 for pure vectors x and y makes zz* real for quaternions just as for the complex numbers.

We have already produced the reals as reals.

(define (testAlg name alg)
(apply (lambda (conj sg zer zer? one + - * inv) (let*
  ((a (sg))(b (sg))(c (sg))(ai (inv a))
    (ta (lambda (val prop) (string-append (if (zer? val) "" "dont ") prop))))
(list name
(ta (- (+ a (+ b c))(+ (+ a b) c)) "+ associate") 
(ta (- (* (conj a) (conj b)) (conj (* b a))) "conjugate")
(ta (- (* a (+ b c))(+ (* a b)(* a c))) "left distribute")
(ta (- (* (+ a b) c)(+ (* a c)(* b c))) "right distribute")
(ta (- (* (* b a) ai) b) "undo multiply")
(ta (- one (* ai a)) "have * inverse")
(ta (- (* a (* b c))(* (* a b) c)) "* associate")
(ta (- (* a b)(* b a)) "* commute")
(ta (- (* (* a a) b)(* a (* a b))) "left alternate")
(ta (- (* (* a b) b)(* a (* b b))) "right alternate")
(ta (- (* a (* ai b)) b) "solve")
))) alg))

(let tst ((a reals)(names
   (list "reals" "complexes" "quaternions" "octonions" "sedenions" "32nions")))
(if (null? names) '() (cons (testAlg (car names) a) (tst (G a) (cdr names)))))

The octonions are also called Cayley numbers. The sedenions are also called hexadecanions or sometimes hexadeconions. This yields on my Mac:

(("reals" "+ associate" "conjugate" "left distribute" "right distribute" "undo multiply" "have * inverse" "* associate" "* commute" "left alternate" "right alternate" "solve")
("complexes" "+ associate" "conjugate" "left distribute" "right distribute" "undo multiply" "have * inverse" "* associate" "* commute" "left alternate" "right alternate" "solve")
("quaternions" "+ associate" "conjugate" "left distribute" "right distribute" "undo multiply" "have * inverse" "* associate" "dont * commute" "left alternate" "right alternate" "solve")
("octonions" "+ associate" "conjugate" "left distribute" "right distribute" "undo multiply" "have * inverse" "dont * associate" "dont * commute" "left alternate" "right alternate" "solve")
("sedenions" "+ associate" "conjugate" "left distribute" "right distribute" "dont undo multiply" "have * inverse" "dont * associate" "dont * commute" "dont left alternate" "dont right alternate" "dont solve")
("32nions" "+ associate" "conjugate" "left distribute" "right distribute" "dont undo multiply" "have * inverse" "dont * associate" "dont * commute" "dont left alternate" "dont right alternate" "dont solve"))

We test these equations with this definition of testAlg.
Here (a, b) = ab - ba and (a, b, c) = (ab)c - a(bc).
We get:

("reals" "* associate" "assoc" "L skew" "R skew" "propA" "xsx" "Mouf1" "Mouf2" "Mouf3a" "Mouf3b" "L1" "L3" "L4" "L5" "L6" "L7")
("complexes" "* associate" "assoc" "L skew" "R skew" "propA" "xsx" "Mouf1" "Mouf2" "Mouf3a" "Mouf3b" "L1" "L3" "L4" "L5" "L6" "L7")
("quaternions" "* associate" "assoc" "L skew" "R skew" "propA" "xsx" "Mouf1" "Mouf2" "Mouf3a" "Mouf3b" "L1" "L3" "L4" "L5" "L6" "L7")
("octonions" "dont * associate" "dont assoc" "L skew" "R skew" "propA" "dont xsx" "Mouf1" "Mouf2" "Mouf3a" "Mouf3b" "L1" "dont L3" "dont L4" "L5" "L6" "L7")
("sedenions" "dont * associate" "dont assoc" "dont L skew" "dont R skew" "dont propA" "dont xsx" "dont Mouf1" "dont Mouf2" "dont Mouf3a" "dont Mouf3b" "dont L1" "dont L3" "dont L4" "L5" "L6" "L7")
("32nions" "dont * associate" "dont assoc" "dont L skew" "dont R skew" "dont propA" "dont xsx" "dont Mouf1" "dont Mouf2" "dont Mouf3a" "dont Mouf3b" "dont L1" "dont L3" "dont L4" "L5" "L6" "L7")

Debugging Tools:

(define p (G (G (G reals))))
(define Hconj (car p))
(define Hsg (cadr p))
(define Hzer (caddr p))
(define Hzer? (cadddr p))
(define Hrst (cddddr p))
(define Hone (car Hrst))
(define H+ (cadr Hrst))
(define H- (caddr Hrst))
(define H* (cadddr Hrst))
(define Hinv (car (cddddr Hrst)))

(define (tz z)
(apply (lambda (conj sg zer zer? one + - * inv)
(write (list z (conj z) (* z (conj z)) (* (conj z) z)
  (inv z) (* z (inv z))(* (inv z) z))))
(G (G (G reals)))))

(define (o? x) (and (pair? x) (pair? (car x)) (pair? (caar x))))
(define (rx a b) (begin (if(o? b) (write (list a b))) b))
We coördinate notation with other web sites on division algebras. Clifford algebras are an alternative generalization of complex numbers.

Here are the empirical results of attempting to change the multiplication formula for the hypercomplex towards that of the Clifford algebras:

(cons (- (* (car a)(car b))(* (cdr a)(conj (cdr b))))
      (+ (* (cdr b)(car a))(* (cdr a)(conj (car b)))))
Octonions neither alternate nor undo multiply.
(cons (- (* (car a)(car b))(* (cdr a)(conj (cdr b))))
      (+ (* (car a)(cdr b))(* (cdr a)(conj (car b)))))
Octonions are good: Sedenions don't conjugate and don't have inverse!!
(cons (- (* (car a)(car b))(* (conj (cdr b))(cdr a)))
      (+ (* (car a)(cdr b))(* (cdr a)(conj (car b)))))
Like above.
(cons (- (* (car a)(car b))(* (cdr a)(conj (cdr b))))
      (+ (* (car a)(cdr b))(* (cdr a)(conj (car b)))))
Octonions and sedenions both fail as described above.

a Slightly irreverent romp thru this territory.