/**************************************************** * C++ Cayley-Dickson Test * Version: 1.0.7 * Author: Douglas Wilhelm Harder * Date: 2008/02/27 * * Copyright (c) 2007-8 by Douglas Wilhelm Harder. * All rights reserved. * * This test checks to ensure that all multiplications * obey the given Cayley-Dickson construction: * * * * * [a, b]*[c, d] = [a*c - d *b, d*a + b*c ] * * It does so by testing all possible products of * the various unit elements. * * For example, given the association: * * [1, 0] <-> 0 * [I, 0] <-> I * [0, 1] <-> J * [0, I] <-> K * * then we see that: * * I * J = [I, 0][0, 1] * * * * = [I*0 - 1 *0, 1*I + 0*0 ] * = [0, I] * = K * * but * * J * I = [0, 1][I, 0] * * * * = [0*I - 0 *1, 0*0 + 1*I ] * = [0, -I] * = -K * ****************************************************/ #include "Complex.h" #include "Quaternion.h" #include "Octonion.h" #include "Sedenion.h" #include "Trigintaduonion.h" #include #include using namespace std; template class Pair { private: T t0; T t1; public: /* Constructor * (a, b) => [a, b] */ Pair( T a0, T a1 ):t0(a0), t1(a1) { // empty } /* Equality testing * [a, b] == [c, d] <=> (a == c) && (b == d) */ bool operator == ( Pair q ) const { return (t0 == q.t0) && (t1 == q.t1); } /* Multiplication * * * * [a, b]*[c, d] = [a*c - d *b, d*a + b*c ] */ Pair operator * ( Pair q ) const { return Pair( t0*q.t0 - conj(q.t1)*t1, q.t1*t0 + t1*conj(q.t0) ); } /* Subtraction * -[a, b] = [-a, -b] */ Pair operator - () const { return Pair( -t0, -t1 ); } }; double conj( double x ) { return x; } void complex(); void quaternion(); void octonion(); void sedenion(); void trigintaduonion(); int main() { complex(); quaternion(); octonion(); sedenion(); trigintaduonion(); return 0; } void complex() { const int N = 2; Pair< double > pair[N] = { Pair< double >( 1, 0 ), Pair< double >( 0, 1 ), }; string psym[N] = { "[1,0]", "[0,1]" }; Complex<> cx[N] = { Complex<>::ONE, Complex<>::I }; string sym[N] = { "1", "i" }; for ( int i = 0; i < N; ++i ) { for ( int j = 0; j < N; ++j ) { Pair< double > result1 = pair[i] * pair[j]; Complex<> result2 = cx[i] * cx[j]; for ( int k = 0; k < N; ++k ) { if ( pair[k] == result1 ) { if ( cx[k] != result2 ) { cout << psym[i] << " * " << psym[j] << " == " << psym[k] << " but " << sym[i] << " * " << sym[j] << " != " << sym[k] << endl; } break; } else if ( pair[k] == -result1 ) { if ( cx[k] != -result2 ) { cout << psym[i] << " * " << psym[j] << " == -" << psym[k] << " but " << sym[i] << " * " << sym[j] << " != -" << sym[k] << endl; } break; } } } } } void quaternion() { const int N = 4; Pair< Complex<> > pair[N] = { Pair< Complex<> >( Complex<>::ONE, Complex<>::ZERO ), Pair< Complex<> >( Complex<>::I, Complex<>::ZERO ), Pair< Complex<> >( Complex<>::ZERO, Complex<>::ONE ), Pair< Complex<> >( Complex<>::ZERO, Complex<>::I ), }; string psym[N] = { "[1,0]", "[i,0]", "[0,1]", "[0,i]" }; Quaternion<> quat[N] = { Quaternion<>::ONE, Quaternion<>::I, Quaternion<>::J, Quaternion<>::K }; string sym[N] = { "1", "i", "j", "k" }; for ( int i = 0; i < N; ++i ) { for ( int j = 0; j < N; ++j ) { Pair< Complex<> > result1 = pair[i] * pair[j]; Quaternion<> result2 = quat[i] * quat[j]; for ( int k = 0; k < N; ++k ) { if ( pair[k] == result1 ) { if ( quat[k] != result2 ) { cout << psym[i] << " * " << psym[j] << " == " << psym[k] << " but " << sym[i] << " * " << sym[j] << " != " << sym[k] << endl; } break; } else if ( pair[k] == -result1 ) { if ( quat[k] != -result2 ) { cout << psym[i] << " * " << psym[j] << " == -" << psym[k] << " but " << sym[i] << " * " << sym[j] << " != -" << sym[k] << endl; } break; } } } } } void octonion() { const int N = 8; Pair< Quaternion<> > pair[N] = { Pair< Quaternion<> >( Quaternion<>::ONE, Quaternion<>::ZERO ), Pair< Quaternion<> >( Quaternion<>::I, Quaternion<>::ZERO ), Pair< Quaternion<> >( Quaternion<>::J, Quaternion<>::ZERO ), Pair< Quaternion<> >( Quaternion<>::K, Quaternion<>::ZERO ), Pair< Quaternion<> >( Quaternion<>::ZERO, Quaternion<>::ONE ), Pair< Quaternion<> >( Quaternion<>::ZERO, Quaternion<>::I ), Pair< Quaternion<> >( Quaternion<>::ZERO, Quaternion<>::J ), Pair< Quaternion<> >( Quaternion<>::ZERO, Quaternion<>::K ) }; string psym[N] = { "[1,0]", "[i,0]", "[j,0]", "[k,0]", "[0,1]", "[0,i]", "[0,j]", "[0,k]" }; Octonion<> oct[N] = { Octonion<>::ONE, Octonion<>::I, Octonion<>::J, Octonion<>::K, Octonion<>::U1, Octonion<>::I1, Octonion<>::J1, Octonion<>::K1 }; string sym[N] = { "1", "i", "j", "k", "u1", "i1", "j1", "k1" }; for ( int i = 0; i < N; ++i ) { for ( int j = 0; j < N; ++j ) { Pair< Quaternion<> > result1 = pair[i] * pair[j]; Octonion<> result2 = oct[i] * oct[j]; for ( int k = 0; k < N; ++k ) { if ( pair[k] == result1 ) { if ( oct[k] != result2 ) { cout << psym[i] << " * " << psym[j] << " == " << psym[k] << " but " << sym[i] << " * " << sym[j] << " != " << sym[k] << endl; } break; } else if ( pair[k] == -result1 ) { if ( oct[k] != -result2 ) { cout << psym[i] << " * " << psym[j] << " == -" << psym[k] << " but " << sym[i] << " * " << sym[j] << " != -" << sym[k] << endl; } break; } } } } } void sedenion() { const int N = 16; Pair< Octonion<> > pair[N] = { Pair< Octonion<> >( Octonion<>::ONE, Octonion<>::ZERO ), Pair< Octonion<> >( Octonion<>::I, Octonion<>::ZERO ), Pair< Octonion<> >( Octonion<>::J, Octonion<>::ZERO ), Pair< Octonion<> >( Octonion<>::K, Octonion<>::ZERO ), Pair< Octonion<> >( Octonion<>::U1, Octonion<>::ZERO ), Pair< Octonion<> >( Octonion<>::I1, Octonion<>::ZERO ), Pair< Octonion<> >( Octonion<>::J1, Octonion<>::ZERO ), Pair< Octonion<> >( Octonion<>::K1, Octonion<>::ZERO ), Pair< Octonion<> >( Octonion<>::ZERO, Octonion<>::ONE ), Pair< Octonion<> >( Octonion<>::ZERO, Octonion<>::I ), Pair< Octonion<> >( Octonion<>::ZERO, Octonion<>::J ), Pair< Octonion<> >( Octonion<>::ZERO, Octonion<>::K ), Pair< Octonion<> >( Octonion<>::ZERO, Octonion<>::U1 ), Pair< Octonion<> >( Octonion<>::ZERO, Octonion<>::I1 ), Pair< Octonion<> >( Octonion<>::ZERO, Octonion<>::J1 ), Pair< Octonion<> >( Octonion<>::ZERO, Octonion<>::K1 ) }; string psym[N] = { "[1,0]", "[i,0]", "[j,0]", "[k,0]", "[u1,0]", "[i1,0]", "[j1,0]", "[k1,0]", "[0, 1]", "[0, i]", "[0, j]", "[0, k]", "[0, u1]", "[0, i1]", "[0, j1]", "[0, k1]" }; Sedenion<> sed[N] = { Sedenion<>::ONE, Sedenion<>::I, Sedenion<>::J, Sedenion<>::K, Sedenion<>::U1, Sedenion<>::I1, Sedenion<>::J1, Sedenion<>::K1, Sedenion<>::U2, Sedenion<>::I2, Sedenion<>::J2, Sedenion<>::K2, Sedenion<>::U3, Sedenion<>::I3, Sedenion<>::J3, Sedenion<>::K3 }; string sym[N] = { "1", "i", "j", "k", "u1", "i1", "j1", "k1", "u2", "i2", "j2", "k2", "u3", "i3", "j3", "k3" }; for ( int i = 0; i < N; ++i ) { for ( int j = 0; j < N; ++j ) { Pair< Octonion<> > result1 = pair[i] * pair[j]; Sedenion<> result2 = sed[i] * sed[j]; for ( int k = 0; k < N; ++k ) { if ( pair[k] == result1 ) { if ( sed[k] != result2 ) { cout << psym[i] << " * " << psym[j] << " == " << psym[k] << " but " << sym[i] << " * " << sym[j] << " != " << sym[k] << endl; } break; } else if ( pair[k] == -result1 ) { if ( sed[k] != -result2 ) { cout << psym[i] << " * " << psym[j] << " == -" << psym[k] << " but " << sym[i] << " * " << sym[j] << " != -" << sym[k] << endl; } break; } } } } } void trigintaduonion() { const int N = 32; Pair< Sedenion<> > pair[N] = { Pair< Sedenion<> >( Sedenion<>::ONE, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::I, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::J, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::K, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::U1, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::I1, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::J1, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::K1, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::U2, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::I2, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::J2, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::K2, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::U3, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::I3, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::J3, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::K3, Sedenion<>::ZERO ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::ONE ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::I ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::J ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::K ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::U1 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::I1 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::J1 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::K1 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::U2 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::I2 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::J2 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::K2 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::U3 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::I3 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::J3 ), Pair< Sedenion<> >( Sedenion<>::ZERO, Sedenion<>::K3 ) }; string psym[N] = { "[1,0]", "[i,0]", "[j,0]", "[k,0]", "[u1,0]", "[i1,0]", "[j1,0]", "[k1,0]", "[u2,0]", "[i2,0]", "[j2,0]", "[k2,0]", "[u3,0]", "[i3,0]", "[j3,0]", "[k3,0]", "[0, 1]", "[0, i]", "[0, j]", "[0, k]", "[0, u1]", "[0, i1]", "[0, j1]", "[0, k1]", "[0, u2]", "[0, i2]", "[0, j2]", "[0, k2]", "[0, u3]", "[0, i3]", "[0, j3]", "[0, k3]" }; Trigintaduonion<> trig[N] = { Trigintaduonion<>::ONE, Trigintaduonion<>::I, Trigintaduonion<>::J, Trigintaduonion<>::K, Trigintaduonion<>::U1, Trigintaduonion<>::I1, Trigintaduonion<>::J1, Trigintaduonion<>::K1, Trigintaduonion<>::U2, Trigintaduonion<>::I2, Trigintaduonion<>::J2, Trigintaduonion<>::K2, Trigintaduonion<>::U3, Trigintaduonion<>::I3, Trigintaduonion<>::J3, Trigintaduonion<>::K3, Trigintaduonion<>::U4, Trigintaduonion<>::I4, Trigintaduonion<>::J4, Trigintaduonion<>::K4, Trigintaduonion<>::U5, Trigintaduonion<>::I5, Trigintaduonion<>::J5, Trigintaduonion<>::K5, Trigintaduonion<>::U6, Trigintaduonion<>::I6, Trigintaduonion<>::J6, Trigintaduonion<>::K6, Trigintaduonion<>::U7, Trigintaduonion<>::I7, Trigintaduonion<>::J7, Trigintaduonion<>::K7 }; string sym[N] = { "1", "i", "j", "k", "u1", "i1", "j1", "k1", "u2", "i2", "j2", "k2", "u3", "i3", "j3", "k3", "u4", "i4", "j4", "k4", "u5", "i5", "j5", "k5", "u6", "i6", "j6", "k6", "u7", "i7", "j7", "k7" }; for ( int i = 0; i < N; ++i ) { for ( int j = 0; j < N; ++j ) { Pair< Sedenion<> > result1 = pair[i] * pair[j]; Trigintaduonion<> result2 = trig[i] * trig[j]; for ( int k = 0; k < N; ++k ) { if ( pair[k] == result1 ) { if ( trig[k] != result2 ) { cout << psym[i] << " * " << psym[j] << " == " << psym[k] << " but " << sym[i] << " * " << sym[j] << " != " << sym[k] << endl; } break; } else if ( pair[k] == -result1 ) { if ( trig[k] != -result2 ) { cout << psym[i] << " * " << psym[j] << " == -" << psym[k] << " but " << sym[i] << " * " << sym[j] << " != -" << sym[k] << endl; } break; } } } } }