Radicalized integer quaternions.
Version of Saturday 30 April 2016.
Dave Barber's other pages.

§ 1a. A quaternion is an ordered quadruple, typically with real numbers as components, interpreted and manipulated according to specific rules.

Notations vary, but in this report we write the four components of a quaternion as a comma-separated list between shallow angle brackets. Examples:

⟨ +1.3, −2.8, +3.14159, +17 ⟩
⟨ 0, 0, 0, 0 ⟩
x, y + z, w, −x

The components of quaternion q can be distinguished by subscripts as in the notational identity: q = ⟨ qh, qi, qj, qk ⟩. Of these, qh is the real part, while qi, qj, and qk are the imaginary parts. Define four particles:

h = ⟨ 1, 0, 0, 0 ⟩
i = ⟨ 0, 1, 0, 0 ⟩
j = ⟨ 0, 0, 1, 0 ⟩
k = ⟨ 0, 0, 0, 1 ⟩

Then:

q = qh · h + qi · i + qj · j + qk · k

These are the usual i, j, and k of quaternion algebra, while h = 1 is introduced to effect a symmetry of notation. We write the negative and conjugate as:

q = − qh · hqi · iqj · jqk · k
~q = + qh · hqi · iqj · jqk · k

§ 1b. Addition and subtraction are component by component:

p + q = ⟨ ph + qh, pi + qi, pj + qj, pk + qk
pq = ⟨ phqh, piqi, pjqj, pkqk

The essence of quaternions is captured in multiplying them; in formulas that may be surprising to the novice, the four components of p · q are:

(p · q)h= ph · qhpi · qipj · qjpk · qk
(p · q)i= ph · qi+ pi · qh+ pj · qkpk · qj
(p · q)j= ph · qjpi · qk+ pj · qh+ pk · qi
(p · q)k= ph · qk+ pi · qjpj · qi+ pk · qh

Although associative, multiplication is not commutative, as illustrated by i · j = +kj · i = −k.

§ 1c. We frequently employ this norm:

|| q || = q · ~q = (qh)2 + (qi)2 + (qj)2 + (qk)2

Important is that the norm is preserved under multiplication: || p · q || = || p || · || q ||.

§ 1d. There are two well-known ways to define integer quaternions. The more obvious is according to the Lipschitz criterion, which says simply that each of the four components must be an ordinary real integer. However, a greater amount of study has been devoted to quaternions satisfying the Hurwitz criterion, which dictates that all four components be half of even numbers, or all four components be half of odd numbers — no mixing allowed. The Lipschitz quaternions are a subset of the Hurwitz quaternions. Examples:

Hurwitz & LipschitzHurwitz onlyneither
⟨ +14, −6, 0, +3 ⟩
⟨ 0, 0, 0, 0 ⟩
⟨ +27/2, −11/2, +1/2, +7/2 ⟩
⟨ +1/2, −1/2, +1/2, +5/2 ⟩
⟨ +14, −11/2, 0, +5/2 ⟩
⟨ 0, 0, 0, −1/2 ⟩

Few if any researchers regard items in the "neither" column as integer quaternions for any purpose.

Easy to see is that the set of Lipschitz quaternions is closed under addition, subtraction and multiplication; for the Hurwitz quaternions, this same is true but less obvious. Each Hurwitz has, in a special sense, an essentially unique prime factorization, while a Lipschitz might have several prime factorizations that are not particularly related.


§ 2a. The main point of this report is to introduce a variant of the integer quaternion.

Let a, b, and c be positive real integers, termed gubernatrices (of which the singular is gubernatrix). Then a radicalized integer quaternion (RIQ) is a quaternion whose components conform to the researcher's choice of either the Lipschitz criterion (RIQ-L) or the Hurwitz criterion (RIQ-H) — but with a modification: in evaluating the RIQ, the three imaginary components are multiplied by certain positive real numbers which are typically irrational:

q = qh · h + qi · i · √(b · c) + qj · j · √(c · a) + qk · k · √(a · b)

which is more concisely written by placing the gubernatrices in a hash triple:

q = ⟨ qh, qi, qj, qk ⟩ # [a, b, c]

The norm, a nonnegative real number, is:

|| q || = (qh)2 + (qi)2 · b · c + (qj)2 · c · a + (qk)2 · a · b

The norm of any RIQ-L is necessarily a real integer; but that is not true for a RIQ-H.

§ 2b. The set of RIQ-Ls is closed under addition, subtraction, and multiplication; and constitutes a ring. Although ordinary quaternions form a division algebra, RIQ-Ls fail to do so because most RIQ-Ls lack a reciprocal. The same properties apply to RIQ-Hs.

With q as above and with p = ⟨ ph, pi, pj, qk ⟩ # [a, b, c], the components of the product p · q are:

(p · q)h = ( ph · qhb · c · pi · qic · a · pj · qja · b · pk · qk )
(p · q)i = ( ph · qi+ pi · qh+ a · pj · qka · pk · qj )
(p · q)j = ( ph · qjb · pi · qk+ pj · qh+ b · pk · qi )
(p · q)k = ( ph · qk+ c · pi · qjc · pj · qi+ pk · qh )

An example:

p= ⟨ +7/2,+3/2,−9/2,+1/2 ⟩ # [5, 7, 3]
q= ⟨ +3/2,−5/2,+1/2,−5/2 ⟩ # [5, 7, 3]
p · q= ⟨ +323/2,+97/2,+25/2,−79/2 ⟩ # [5, 7, 3]

The same thing in non-RIQ notation is:

p= ⟨ +7/2,+3/2 · √21, −9/2 · √15,+1/2 · √35 ⟩
q= ⟨ +3/2,−5/2 · √21, +1/2 · √15,−5/2 · √35 ⟩
p · q= ⟨ +323/2,+97/2 · √21, +25/2 · √15,−79/2 · √35 ⟩

The sum or product of two RIQ-Hs will sometimes qualify as a RIQ-L:

p= ⟨ +1/2,+9/2,+7/2,−1/2 ⟩ # [5, 7, 3]
q= ⟨ +5/2,−3/2,−1/2,+9/2 ⟩ # [5, 7, 3]
p + q= ⟨ +3,+3,+3,+4 ⟩ # [5, 7, 3]
p · q= ⟨ +248,+88−128,+10 ⟩ # [5, 7, 3]

For addition, subtraction, or multiplication to perform as intended, all the operands must be using the same gubernatrices in the same positions. For instance, if p is being evaluated with # [3, 5, 7] but q is using # [7, 3, 5], then for most values of p and q, their product will not be a RIQ.

Note that √(b · c) and the other square roots need not be re-evaluated for every calculation; instead they can be extracted only once, when the gubernatrices are selected.

With # [1, 1, 1], ordinary quaternion operations result. If any gubernatrices are zero, an uninteresting degeneracy ensues, so we exclude that case.

§ 2c. In general, division of RIQs will not work. Still, we can salvage a few results by defining the following:

p / q = (p · ~q) ÷ || q ||
q \ p = (~q · p) ÷ || q ||

These exist whenver the four components of the result quaternion conform to the Lipschitz or Hurwitz criterion as appropriate. The four components of the result, although rational numbers, usually turn out to be neither wholes nor halves.

§ 2d. A RIQ can be cycled. Recall:

q = ⟨ qh, qi, qj, qk ⟩ # [a, b, c]

and form q′ by substituting ijki, and abca:

q′ = ⟨ qh, qj, qk, qi ⟩ # [b, c, a]

If such cycling is performed on all the RIQs in an equation, the equation will remain true. There is no obvious way for the real part to participate in any sort of cycling.

§ 2e. An example will show why we have not chosen to attach a radical to the real part of a RIQ. With w as a positive real integer, consider a quaternion whose imaginary parts are all zero, for instance 5 · √w. Squared, it becomes 25 · w, which cannot be written in the form n · √w for real integer n, unless w is a perfect square; and in that case the effect of having a radical is lost. A further consideration is that if the real part of a RIQ had a radical, there would no longer be a multiplicative identity, namely ⟨ 1, 0, 0, 0 ⟩.

Since the Hurwitz criterion allows a divisor of two, the question arises whether other divisors, particularly small primes, might give interesting results. For that matter, the hash triple could conceivably contain fractions. However, our experiments with these generalizations did not yield anything fruitful.


§ 3. Let hash triple #[1, 1, 1] be selected, yielding ordinary Lipschitz quaternions. Then for any nonnegative real integer n there exists a RIQ-L q such that || q || = n; this is established by a famous theorem. We consequently say that every nonnegative real integer is attainable as a norm using #[1, 1, 1].

Using any other gubernatrices, there may (and probably will) be some norms that are unattainable; we need look no further than #[1, 1, 4]. Substituting a = b = 1 and c = 4 into q:

|| q || = (qh)2 + (qi)2 · 4 + (qj)2 · 4 + (qk)2 · 1

In modulo 4, this simplifies to

|| q || = (qh)2 + (qk)2

which in modulo 4 can never equal 3. Hence q can never have a norm in the sequence 3, 7, 11, 15 … .

For many hash triples, the set of unattainable norms is difficult to characterize, although in most cases it thins out for larger norms. For instance, with #[3, 5, 7] there are 118 norms unattainable with RIQ-Ls in the thousand-integer range 0 to 999, as in the table below. These results come from a brute-force search. An open question is whether there is a maximum unattainable norm with #[3, 5, 7].

some norms unattainable
with hash triple #[3,5,7]
under the Lipschitz criterion
rangecountexamples   rangecountexamples
0 - 999118 2, 154, 539 10000 - 10999 110682
1000 - 1999 23 1043, 1421, 1666 11000 - 11999 111074
2000 - 2999 12 2009, 2352, 2758 12000 - 12999 312005, 12103, 12691
3000 - 3999 10 3038, 3577, 3822 13000 - 13999 213034, 13181
4000 - 4999 8 4067, 4487, 4949 14000 - 14999 314063, 14406, 14749
5000 - 5999 6 5390, 5782, 5978 15000 - 15999 515043, 15778, 15974
6000 - 6999 4 6174, 6321, 6874 16000 - 16999 116807
7000 - 7999 4 7154, 7203, 7742 17000 - 17999 317003, 17150, 17738
8000 - 8999 6 8134, 8575, 8722 18000 - 18999 0 
9000 - 9999 2 9163, 9947 19000 - 19999 219208, 19894

Some norms unattainable with RIQ-Ls become possible with RIQ-Hs. If #[3, 5, 7] is reconsidered using RIQ-Hs, there are only 81 unattainable norms in the range 0-999.


§ 4. If || p || > 1, || q || > 1, and r = p · q, then we say that r has the factorization p · q. Recall that norms are preserved under quaternion multiplication, so that if || s || is a real prime number, s cannot have a factorization, and we call s a weak prime. If s fails to have a factorization even when || s || is non-prime, then s is a strong prime.

The existence of a factorization depends on the gubernatrices. For instance, s below has a norm of 13, which is a real prime, so s itself must be prime. This is true even though s has the same four components as p · q, which is patently factorizable.

p= ⟨ +1,0,−1,+1 ⟩ # [1, 1, 1] || p || = 3
q= ⟨ +1,−1,+1,0 ⟩ # [1, 1, 1] || q || = 3
p · q= ⟨ +2,−2,−1,0 ⟩ # [1, 1, 1] || p · q || = 9
s= ⟨ +2,−2,−1,0 ⟩ # [1, 2, 1] || s || = 13


§ 5. RIQs can be generalized. The seven numbers qh, qi, qj, qk, a, b, c in the following expression:

q = ⟨ qh, qi, qj, qk ⟩ # [a, b, c]

need not be limited to the reals. Instead, they can be complex integers, yielding a subset of the biquaternions. A RIQ with complex components we call a RIBQ.

Separate from the imaginary units of quaternions (i, j, and k) is the imaginary unit of complex numbers (here written g for Gauss). For greater clarity, we write f for the real unit of complex numbers, even though it can be identified with h. In our style of notation, a complex number written as a real-imaginary ordered pair appears thus:

d = ⟨ df, dg

Although the complex number and the quaternion both use shallow angle brackets, they are distinguished by the number of components. As an example of the notation, the standard multiplication rule for complex numbers looks like this:

(d · e)f = df · efdg · eg
(d · e)g = df · eg + dg · ef

By postulate, g commutes in multiplication with i, j, and k; but the product cannot be simplified.

The researcher when handling expressions such as the following (which appears above for real numbers, where it works fine) must exercise care with the square root function, which is bivalued:

q = qh · h + qi · i · √(b · c) + qj · j · √(c · a) + qk · k · √(a · b)

In interpreting √(b · c) with complex numbers, it must be remembered that some square root of b times some square root of c merely equals some square root of b · c. Complex numbers differ from the reals in that calculations relying on "principal" square roots are error-prone. A safer approach is to settle on a particular square root for each of a, b, and c, and write separate radicals instead:

q= qh · h
+ qi · i · √b · √c
+ qj · j · √c · √a
+ qk · k · √a · √b

Here is an example of RIBQ-L multiplication with the hash triple # [⟨ +1, −1 ⟩, ⟨ −1, +2 ⟩, ⟨ +2, −3 ⟩]:

p= ⟨ −4, +2 ⟩,
+3, −1 ⟩· √⟨ −1, +2 ⟩· √⟨ +2, −3 ⟩,
+3, −1 ⟩· √⟨ −1, +2 ⟩· √⟨ +2, −3 ⟩,
+2, −3 ⟩· √⟨ −1, +2 ⟩· √⟨ +2, −3 ⟩
 
q= ⟨ +2, −3 ⟩,
+1, 0 ⟩· √⟨ +2, −3 ⟩· √⟨ +1, −1 ⟩,
0, −2 ⟩· √⟨ +2, −3 ⟩· √⟨ +1, −1 ⟩,
−1, +1 ⟩· √⟨ +2, −3 ⟩· √⟨ +1, −1 ⟩
 
p · q= ⟨ +21,−25 ⟩,
+11, −5 ⟩· √⟨ +1, −1 ⟩· √⟨ −1, +2 ⟩,
+17, +12 ⟩· √⟨ +1, −1 ⟩· √⟨ −1, +2 ⟩,
−28,−13 ⟩· √⟨ +1, −1 ⟩· √⟨ −1, +2 ⟩

An open question is how to meaningfully define RIBQ-Hs.


§ 6a. Octonions are another way to generalize quaternions, and are themselves susceptible to integer radicalization.

A brief introduction to octonions is helpful here. An octonion is an ordered octuple, typically with real numbers as components, interpreted and manipulated according to rules resembling those of quaternions. We write the eight components of a quaternion as a comma-separated list between shallow angle brackets. Examples:

⟨ +1.3, −2.8, +3.14159, +17, +99, −6, 0, +1.414 ⟩
⟨ 0, 0, 0, 0, 0, 0, 0, 0 ⟩

The components of octonion q can be distinguished by subscripts: q = ⟨ qh, qi, qj, qk, ql, qm, qn, qo ⟩. Of these, qh is the real part, while the other seven are the imaginary parts. Define eight particles:

h = ⟨ 1, 0, 0, 0, 0, 0, 0, 0 ⟩
i = ⟨ 0, 1, 0, 0, 0, 0, 0, 0 ⟩
j = ⟨ 0, 0, 1, 0, 0, 0, 0, 0 ⟩
k = ⟨ 0, 0, 0, 1, 0, 0, 0, 0 ⟩
l = ⟨ 0, 0, 0, 0, 1, 0, 0, 0 ⟩
m = ⟨ 0, 0, 0, 0, 0, 1, 0, 0 ⟩
n = ⟨ 0, 0, 0, 0, 0, 0, 1, 0 ⟩
o = ⟨ 0, 0, 0, 0, 0, 0, 0, 1 ⟩

Then:

q = qh · h + qi · i + qj · j + qk · k + ql · l + qm · m + qn · n + qo · o

The negative and conjugate are:

q = − qh · hqi · iqj · jqk · kql · lqm · mqn · nqo · o
~q = + qh · hqi · iqj · jqk · kql · lqm · mqn · nqo · o

§ 6b. There are 480 ways to multiply two octonions, but they are all related through notational changes, and they all boil down to essentially the same thing. Arbitrarily chosen for this report is the variety numbered as 406 from another report, with the following correspondence of notation:

other report e0e1e2e3 e4e5e6e7
this report hijklmno

Then p · q expands according to this lengthy formula:

(p · q)h = ph · qhpi · qi pj · qjpk · qk pl · qlpm · qm pn · qnpo · qo
(p · q)i = (ph · qi + pi · qh) + (pj · ql pl · qj) + (pm · qn pn · qm) + (pk · qo po · qk)
(p · q)j = (ph · qj + pj · qh) + (pk · qm pm · qk) + (pn · qo po · qn) + (pl · qi pi · ql)
(p · q)k = (ph · qk + pk · qh) + (pl · qn pn · ql) + (po · qi pi · qo) + (pm · qj pj · qm)
(p · q)l = (ph · ql + pl · qh) + (pm · qo po · qm) + (pi · qj pj · qi) + (pn · qk pk · qn)
(p · q)m = (ph · qm + pm · qh) + (pn · qi pi · qn) + (pj · qk pk · qj) + (po · ql pl · qo)
(p · q)n = (ph · qn + pn · qh) + (po · qj pj · qo) + (pk · ql pl · qk) + (pi · qm pm · qi)
(p · q)o = (ph · qo + po · qh) + (pi · qk pk · qi) + (pl · qm pm · ql) + (pj · qn pn · qj)

Multiplication is neither associative nor commutative.

§ 6c. Here is the norm:

|| q || = q · ~q = (qh)2 + (qi)2 + (qj)2 + (qk)2 + (ql)2 + (qm)2 + (qn)2 + (qo)2

As with quaternions, norms are preserved under multiplication: || p · q || = || p || · || q ||.

§ 6d. Radicalized integer octonions (RIOs) can now be developed. For simplicity, we confine ourselves to Lipschitz-style octonions (RIO-Ls), where every component is a real integer. Extending this to Hurwitz-style octonions (RIO-Hs), where a component might be sometimes half of an odd integer, is certainly possible but not covered here.

Needed as gubernatrices are seven positive real integers, namely a, b, c, d, e, f, and g. Then a RIO-L is an octonion whose components are real integers — but with a modification similar to that for RIQs: when the RIO is evaluated, the seven imaginary components are multiplied by certain real numbers which are typically irrational:

q = qh· h
+ qi· i· √ ( b · c · d · f )
+ qj· j· √ ( c · d · e · g )
+ qk· k· √ ( d · e · f · a )
+ ql· l· √ ( e · f · g · b )
+ qm· m· √ ( f · g · a · c )
+ qn· n· √ ( g · a · b · d )
+ qo· o· √ ( a · b · c · e )

which, much as before, is more concisely written with a hash septuple:

q = ⟨ qh, qi, qj, qk, ql, qm, qn, qo ⟩ # [ a, b, c, d, e, f, g ]

The norm, still a real number, looks like this:

|| q || = (qh)2
+ (qi)2· b · c · d · f
+ (qj)2· c · d · e · g
+ (qk)2· d · e · f · a
+ (ql)2· e · f · g · b
+ (qm)2· f · g · a · c
+ (qn)2· g · a · b · d
+ (qo)2· a · b · c · e

The norm of any RIO-L is inevitably a real integer; but this might not be true for a RIO-H.

§ 6e. The set of RIO-Ls is closed under addition, subtraction, and multiplication. Note that octonions are not classified as rings due to the lack of multiplicative associativity.

With q as above and with p defined analogously to q, the eight components of product p · q are:

(p · q)h = ph · qh b · c · d · f · pi · qi c · d · e · g · pj · qj d · e · f · a · pk · qk
e · f · g · b · pl · ql f · g · a · c · pm · qm g · a · b · d · pn · qn a · b · c · e · po · qo
(p · q)i = (ph · qi+ pi · qh) + e · g · (pj · qlpl · qj) + g · a · (pm · qnpn · qm) + a · e · (pk · qopo · qk)
(p · q)j = (ph · qj+ pj · qh) + f · a · (pk · qmpm · qk) + a · b · (pn · qopo · qn) + b · f · (pl · qipi · ql)
(p · q)k = (ph · qk+ pk · qh) + g · b · (pl · qnpn · ql) + b · c · (po · qipi · qo) + c · g · (pm · qjpj · qm)
(p · q)l = (ph · ql+ pl · qh) + a · c · (pm · qopo · qm) + c · d · (pi · qjpj · qi) + d · a · (pn · qkpk · qn)
(p · q)m = (ph · qm+ pm · qh) + b · d · (pn · qipi · qn) + d · e · (pj · qkpk · qj) + e · b · (po · qlpl · qo)
(p · q)n = (ph · qn+ pn · qh) + c · e · (po · qjpj · qo) + e · f · (pk · qlpl · qk) + f · c · (pi · qmpm · qi)
(p · q)o = (ph · qo+ po · qh) + d · f · (pi · qkpk · qi) + f · g · (pl · qmpm · ql) + g · d · (pj · qnpn · qj)

Taking (p · q)m as an example of an imaginary component of p · q, it is figured employing three of the gubernatrices (namely b, d, e). When the eight components are combined to evaluate the product in full, this m component is then multiplied by the square root of the product of the other four gubernatrices (namely f, g, a, c). The table below summarizes this for all eight parts:

partconstants used
in multiplication
constants used
in evaluation
hallnone
ie, g, ab, c, d, f
jf, a, bc, d, e, g
kg, b, cd, e, f, a
la, c, de, f, g, b
mb, d, ef, g, a, c
nc, e, fg, a, b, d
od, f, ga, b, c, e

The same principle applies in the quaternion case, but it is not as obvious. The patterns gives a clue how integer radicalization might be extended to other kinds of numbers. Another observation is that the letters a through g and i through o frequently appear in alphabetical order, so that the numbers they represent might instead be stored in an array whose subscripts are managed with modular arithmetic.

Recall the usual requirement that all seven of the gubernatrices be positive. If that constraint is relaxed, and exactly one of them is zero, then four of the imaginary components vanish, and the consequent behavior becomes isomorphic to that of RIQs. If exactly two gubernatrices are zero, then RIO behavior becomes that of radicalized integer complex numbers.

§ 6f. Provided is source code for a C++11 program to demonstrate RIO-Ls. Anyone may download, use, modify, and redistribute it.

§ 6f1. Here are some excerpts of the class declaration:

    template < big_int a, big_int b, big_int c, big_int d,
               big_int e, big_int f, big_int g >
    struct rad_int_oct {
        big_int h, i, j, k, l, m, n, o;

        // general-purpose constructor:
        rad_int_oct (
            big_int const ph, big_int const pi,
            big_int const pj, big_int const pk,
            big_int const pl, big_int const pm,
            big_int const pn, big_int const po
        ) :
            h {ph}, i {pi}, j {pj}, k {pk},
            l {pl}, m {pm}, n {pn}, o {po}
        { }

        // real-number constructor:
        rad_int_oct (big_int const ph) :
            h {ph}, i {0}, j {0}, k {0},
            l { 0}, m {0}, n {0}, o {0}
        { }

        rad_int_oct operator+ () const; // positive
        rad_int_oct operator~ () const; // conjugate
        rad_int_oct operator- () const; // negative

        rad_int_oct operator+ (rad_int_oct const & y) const;
        rad_int_oct operator- (rad_int_oct const & y) const;

        rad_int_oct operator* (rad_int_oct const &) const;
        rad_int_oct mult_comm (rad_int_oct const &) const;
        rad_int_oct mult_anti (rad_int_oct const &) const;

        big_int squ_mag () const;
        double mag () const;

        bool lexico_EQ (rad_int_oct const & y) const;
        bool lexico_LT (rad_int_oct const & y) const;

        void view (ostream &, int const) const;
    };

Notes:

⇒ The template parameters are the gubernatrices.

big_int should be at least a 64-bit signed integer, or an extended-precision integer of the user's choice. A 32-bit integer is likely to exhibit overflow in even the simplest of examples.

h, i, j, k, l, m, n, o are public because they can be any combination of big_int values; there is no invariant to enforce.

operator* is ordinary multiplication, which can be split into a commutative part (mult_comm) and an anti-commutative part (mult_anti). For all octonions x and y:

However, there is no simple relationship between x * y and y * x.

squ_mag is this program's name for the norm. Its square root is mag, which is the Euclidean magnitude. Both of these figures take the gubernatrices into account.

⇒ Two functions are based on lexicographical comparison. For this, the two rad_int_octs must have the same gubernatrices:

view displays the rad_int_oct to the indicated ostream. The integer parameter selects the level of verbosity, with minimum 1 and maximum 4.

§ 6f2. Here are some more excerpts of the class declaration, namely the rotation functions:

    template < big_int a, big_int b, big_int c, big_int d,
               big_int e, big_int f, big_int g >
    struct rad_int_oct {
        static constexpr int mod7 (int const num);

        template <int dist>
        typename std::enable_if <
            mod7 (dist) == 0, rad_int_oct<a,b,c,d,e,f,g>
        >::type rotate () const {
            return rad_int_oct<a,b,c,d,e,f,g> { h, i, j, k, l, m, n, o };
        }

        template <int dist>
        typename std::enable_if <
            mod7 (dist) == 1, rad_int_oct<g,a,b,c,d,e,f>
        >::type rotate () const {
            return rad_int_oct<g,a,b,c,d,e,f> { h, o, i, j, k, l, m, n };
        }

        template <int dist>
        typename std::enable_if <
            mod7 (dist) == 2, rad_int_oct<f,g,a,b,c,d,e>
        >::type rotate () const {
            return rad_int_oct<f,g,a,b,c,d,e> { h, n, o, i, j, k, l, m };
        }

        template <int dist>
        typename std::enable_if <
            mod7 (dist) == 3, rad_int_oct<e,f,g,a,b,c,d>
        >::type rotate () const {
            return rad_int_oct<e,f,g,a,b,c,d> { h, m, n, o, i, j, k, l };
        }

        template <int dist>
        typename std::enable_if <
            mod7 (dist) == 4, rad_int_oct<d,e,f,g,a,b,c>
        >::type rotate () const {
            return rad_int_oct<d,e,f,g,a,b,c> { h, l, m, n, o, i, j, k };
        }

        template <int dist>
        typename std::enable_if <
            mod7 (dist) == 5, rad_int_oct<c,d,e,f,g,a,b>
        >::type rotate () const {
            return rad_int_oct<c,d,e,f,g,a,b> { h, k, l, m, n, o, i, j };
        }

        template <int dist>
        typename std::enable_if <
            mod7 (dist) == 6, rad_int_oct<b,c,d,e,f,g,a>
        >::type rotate () const {
            return rad_int_oct<b,c,d,e,f,g,a> { h, j, k, l, m, n, o, i };
        }
    };

Because the gubernatrices are template paramaters, thus compile-time constants, rotation requires a type conversion because the gubernatrices get rearranged. Given this declaration:

    rad_int_oct<3,4,5,6,7,8,9> const x { −3, +6, −9, +2, −5, +8, −1, +4 };
and this operation:
    auto const y (x.rotate<1>);
then y is the same as the following z:
    rad_int_oct<3,9,4,5,6,7,8> const z { −3, +4, +6, −9, +2, −5, +8, −1 };
As always, the real part does not participate in rotation.

The parameter may be any integer. For instance, rotate<2> has the same effect as two successive invocations of rotate<1>, and rotate<−1> will undo rotate<1>. Meanwhile, rotate<0> and rotate<7> do nothing.

§ 6f3. Several non-member functions exist for testing:

test_squ_mag verifies that the squ_mag of the product of two rad_int_octs equals the product of the individual squ_mags.

test_alt_assoc verifies that the alternate associativity of octonions is preserved.

test_split_mult verifies that mult_comm and mult_anti work as described above.

test_distrib verifies that multiplication distributes over addition.

test_rotate verifies that rotation works.

test_rotate_mult verifies that the unrotated product of two rotated rad_int_octs equals the rotated product of the unrotated rad_int_octs.


§ 7a. Integer radicalization can also be applied to the cross product of vectors. In fact, if the quaternion arithmetic mentioned above is modified so that zero is substituted for the real part of every quaternion, no matter what its value might otherwise have been, then quaternion multiplication becomes isomorphic to the widely-used cross product of two three-dimensional vectors — for brevity we call that operation the 2-in-3. Similarly, forcing the real part of octonions in multiplication to zero gives the 2-in-7. In the radicalized case, the procedure of forcing the real part to zero still works in because, among other reasons, no radical is attached to the real part of a RIQ or RIO.

The cross product can be extended to n vectors in n + 1 dimensions; in this report we elaborate the 3-vectors-in-4-dimensions case (the "3-in-4") to show that integer radicalization can work with a multiplication that uses three factors rather than two. Perhaps surprisingly, we still have square roots and not cube roots.

Let W = { W0, W1, W2Wn−1 } be an orthonormal basis of an n-dimensional vector space over the real numbers. Then there is a widely recognized definition of the cross product of n − 1 factors, and it is most succinctly defined as the determinant of a formal matrix. The 3-in-4 for vectors p, q, r follows; note the use of an HTML table to draw the matrix:

p × q × r = det
p0p1p2p3
q0q1q2q3
r0r1r2r3
W0W1W2W3

The extension to other numbers of dimensions is obvious. For comparison, the 2-in-3 looks like this:

p × q = det
p0p1p2
q0q1q2
W0W1W2

Returning to the 3-in-4, define these numbers:

s0 = + p1 · q2 · r3p1 · q3 · r2 + p2 · q3 · r1p2 · q1 · r3 + p3 · q1 · r2p3 · q2 · r1
s1 = + p2 · q3 · r0p2 · q0 · r3 + p3 · q0 · r2p3 · q2 · r0 + p0 · q2 · r3p0 · q3 · r2
s2 = + p3 · q0 · r1p3 · q1 · r0 + p0 · q1 · r3p0 · q3 · r1 + p1 · q3 · r0p1 · q0 · r3
s3 = + p0 · q1 · r2p0 · q2 · r1 + p1 · q2 · r0p1 · q0 · r2 + p2 · q0 · r1p2 · q1 · r0

Then p × q × r = − s0 + s1s2 + s3.

§ 7b. Now radicals can be introduced; six gubernatrices (a, b, c, d, e, f ) are required. Vector p is evaluated as:

p = [p0 · √ (a · b · d),
p1 · √ (a · c · e),
p2 · √ (b · c · f ),
p3 · √ (d · e · f ) ]

This could have been written with a hash sextuple:

p = [ p0, p1, p2, p3 ] # [ a, b, c, d, e, f ]

Component by component, the 3-in-4 with radicals becomes:

(p × q × r)0 = − s0 · c · e · f
(p × q × r)1 = + s1 · b · d · f
(p × q × r)2 = − s2 · a · d · e
(p × q × r)3 = + s3 · a · b · c

This radicalized 3-in-4 fulfills the two requirements usually expected of anything called a cross product. In the descriptions below, the centered dot represents the inner product:

§ 7c. To illustrate how radicalization of the 3-in-4 extends to the n-in-n+1, rename the gubernatrices a = g0, b = g1, et cetera. The scheme of color-coding will become clear later:

p = [ p0 · √ ( a · b · d),
p1 · √ ( a · c · e),
p2 · √ ( b · c · f ),
p3 · √ ( d · e · f ) ]
becomes
p = [ p0 · √ ( g0 · g1 · g3 ),
p1 · √ ( g0 · g2 · g4 ),
p2 · √ ( g1 · g2 · g5 ),
p3 · √ ( g3 · g4 · g5 ) ]

Here is the 4-in-5:

q = [ q0 · √ ( g0 · g1 · g3 · g6 ),
q1 · √ ( g0 · g2 · g4 · g7 ),
q2 · √ ( g1 · g2 · g5 · g8 ),
q3 · √ ( g3 · g4 · g5 · g9 ),
q4 · √ ( g6 · g7 · g8 · g9 ) ]

and the 5-in-6:

r = [ r0 · √ ( g0 · g1 · g3 · g6 · g10 ),
r1 · √ ( g0 · g2 · g4 · g7 · g11 ),
r2 · √ ( g1 · g2 · g5 · g8 · g12 ),
r3 · √ ( g3 · g4 · g5 · g9 · g13 ),
r4 · √ ( g6 · g7 · g8 · g9 · g14 ),
r5 · √ ( g10 · g11 · g12 · g13 · g14 ) ]

This pattern for arranging the subscripts of g is recapped in the table below, and readily extended to higher dimensionalities:

  1-in-2 2-in-3 3-in-4 4-in-5 5-in-6 6-in-7
g0 g1 g3 g6 g10 g15
1-in-2 g0 g2 g4 g7 g11 g16
2-in-3 g1 g2 g5 g8 g12 g17
3-in-4 g3 g4 g5 g9 g13 g18
4-in-5 g6 g7 g8 g9 g14 g19
5-in-6 g10 g11 g12 g13 g14 g20
6-in-7 g15 g16 g17 g18 g19 g20

The 0-in-1, as the degenerate case, would have zero gubernatrices.