Constructing Quaternionic Groupings

For 7 imaginary unit elements, there are 7*6*5/3! = 35 possible triplets of distinct elements (disregarding order of the elements within the triplet). By convention elements will be listed in ascending index order, and triplets listed in ascending lexical order. An array of triplets of this nature is created by the following C code snippet:
// create lexically ordered list of triplets of distinct elements
	for(i=1, n=0; i<=N; i++) {
		for(j=i+1; j<=N; j++) {
			for(k=j+1;k<=N;k++) {	
				triplets[n][0] = i;
				triplets[n][1] = j;
				triplets[n++][2] = k;
			}
		}
	}

Multiplication Table Triads

A triplet (ei, ej, ek) i < j < k in the list above is a "triad" in a multiplication table iff
eiej = ±ek and ejek = ±ei and ekei = ±ej.
If all elements appear in the multiplication table in this manner, then adding real multiplicative identity e0 (if not already present), setting ei2 = -e0 for i > 0, and assigning signs to products in a cyclic manner ("handedness") makes every subalgebra generated by 2 imaginary elements isomorphic to the quaternions. Ignoring the + and -, how can subsets of the triplets be chosen to form such "quaternionic groupings" in such a "pure triad multiplication table"?

Program in C to Find Pure Triad Multiplication Tables

The following C program (with variants for other dimensional systems) will (eventually) construct all quaternionic groupings by trial and error. For low dimensions (e.g. octonions of dim 8, Steiner 9-dimensional system) it runs pretty rapidly on a standard laptop or desktop and gives useful and interesting results. A more efficient approach is definitely needed for sedenions, or Steiner dim 19.

The #define's are set for [twisted] octonions (N=8, etc.); other systems can be studied with appropriate modifications to N, T, P, Q.

The Program:

#include <stdio.h>

#define N 8	// dimension of the algebra; N-1 imaginary units plus 1 real axis
#define T 35	// number of ordered triplets (not necessarily triads) of imaginary elements, = (N-1)(N-2)(N-3)/3!
#define P (N-1)*(N-2)/2	// number of pairs of imaginary elements
#define Q 7	// number of quaternionic triads = ((N-1)(N-1) - (N-1))/6 from inspection of multiplication table

void markG(int, int);
int   G[P][3], M[T][3], triads[Q]; // G records usage of pairs of imaginaries in the mult table; M records triplets
long count = 0L;
FILE *fp;

main() {
	int  depth, t, i, j, k; // T different triplets of elements, not all triads; this lists 'em
// first, fill in the list of ordered triplets
	t = 0;
	for(i=1; i< N; i++) {
		for(j=i+1; j

The Output

The program above produces a list of 30 sets of 7 indices into the list of triplets for 7 imaginaries, as follows:
0 9 14 20 23 27 28 
0 9 14 21 22 26 29 
0 10 13 19 24 27 28 
0 10 13 21 22 25 30 
0 11 12 19 24 26 29 
0 11 12 20 23 25 30 
1 6 14 17 23 27 31 
1 6 14 18 22 26 32 
1 7 13 16 24 27 31 
1 7 13 18 22 25 33 
1 8 12 16 24 26 32 
1 8 12 17 23 25 33 
2 5 14 17 21 29 31 
2 5 14 18 20 28 32 
2 7 11 15 24 29 31 
2 7 11 18 20 25 34 
2 8 10 15 24 28 32 
2 8 10 17 21 25 34 
3 5 13 16 21 30 31 
3 5 13 18 19 28 33 
3 6 11 15 23 30 31 
3 6 11 18 19 26 34 
3 8 9 15 23 28 33 
3 8 9 16 21 26 34 
4 5 12 16 20 30 32 
4 5 12 17 19 29 33 
4 6 10 15 22 30 32 
4 6 10 17 19 27 34 
4 7 9 15 22 29 33 
4 7 9 16 20 27 34