Quaternions   are an extension of the idea of   complex numbers.

A complex number has a real and complex part,   sometimes written as     a + bi,  

where     a     and     b     stand for real numbers, and     i     stands for the square root of minus 1.

An example of a complex number might be     -3 + 2i,    

where the real part,     a     is     -3.0     and the complex part,     b     is     +2.0.  

A quaternion has one real part and three imaginary parts,     i,       j,     and     k.  

A quaternion might be written as     a + bi + cj + dk.  

In the quaternion numbering system:

     i∙i = j∙j = k∙k = i∙j∙k = -1,         or more simply,
     ii  = jj  = kk  = ijk   = -1.  
The order of multiplication is important, as, in general, for two quaternions:

     q1     and     q2:         q1q2 ≠ q2q1.  
An example of a quaternion might be     1 +2i +3j +4k  

There is a list form of notation where just the numbers are shown and the imaginary multipliers    i,       j,     and     k     are assumed by position.

So the example above would be written as     (1, 2, 3, 4)  



Task

Given the three quaternions and their components: 

   q  = (1, 2, 3, 4) = (a,  b,  c,  d)
   q1 = (2, 3, 4, 5) = (a1, b1, c1, d1)
   q2 = (3, 4, 5, 6) = (a2, b2, c2, d2) 

And a wholly real number     r = 7.  



Create functions   (or classes)   to perform simple maths with quaternions including computing:

 The norm of a quaternion: 




=



a

2


+

b

2


+

c

2


+

d

2






{\displaystyle ={\sqrt {a^{2}+b^{2}+c^{2}+d^{2}}}}

 
 The negative of a quaternion: 
   = (-a, -b, -c, -d)  
 The conjugate of a quaternion: 
   = ( a, -b, -c, -d)  
 Addition of a real number     r     and a quaternion     q:  
  r + q = q + r = (a+r, b, c, d)  
 Addition of two quaternions: 
   q1 + q2 = (a1+a2, b1+b2, c1+c2, d1+d2)  
 Multiplication of a real number and a quaternion: 
   qr = rq = (ar, br, cr, dr)  
 Multiplication of two quaternions     q1     and   q2     is given by: 
   ( a1a2 − b1b2 − c1c2 − d1d2, 
   a1b2 + b1a2 + c1d2 − d1c2, 
   a1c2 − b1d2 + c1a2 + d1b2, 
   a1d2 + b1c2 − c1b2 + d1a2 )  
 Show that, for the two quaternions     q1     and     q2: 
 q1q2 ≠ q2q1  


If a language has built-in support for quaternions, then use it.



C.f.

   Vector products
   On Quaternions;   or on a new System of Imaginaries in Algebra.   By Sir William Rowan Hamilton LL.D, P.R.I.A., F.R.A.S., Hon. M. R. Soc. Ed. and Dub., Hon. or Corr. M. of the Royal or Imperial Academies of St. Petersburgh, Berlin, Turin and Paris, Member of the American Academy of Arts and Sciences, and of other Scientific Societies at Home and Abroad, Andrews' Prof. of Astronomy in the University of Dublin, and Royal Astronomer of Ireland.


# GAP has built-in support for quaternions
 
A := QuaternionAlgebra(Rationals);
# <algebra-with-one of dimension 4 over Rationals>
 
b := BasisVectors(Basis(A));
# [ e, i, j, k ]
 
q := [1, 2, 3, 4]*b;
# e+(2)*i+(3)*j+(4)*k
 
# Conjugate
ComplexConjugate(q);
# e+(-2)*i+(-3)*j+(-4)*k
 
# Division
1/q;
# (1/30)*e+(-1/15)*i+(-1/10)*j+(-2/15)*k
 
# Computing norm may be difficult, since the result would be in a quadratic field.
# Sqrt exists in GAP, but it is quite unusual: see ?E in GAP documentation, and the following example
Sqrt(5/3);
# 1/3*E(60)^7+1/3*E(60)^11-1/3*E(60)^19-1/3*E(60)^23-1/3*E(60)^31+1/3*E(60)^43-1/3*E(60)^47+1/3*E(60)^59
 
# However, the square of the norm is easy to compute
q*ComplexConjugate(q);
# (30)*e
 
q1 := [2, 3, 4, 5]*b;
# (2)*e+(3)*i+(4)*j+(5)*k
 
q2 := [3, 4, 5, 6]*b;
# (3)*e+(4)*i+(5)*j+(6)*k
 
q1*q2 - q2*q1;
# (-2)*i+(4)*j+(-2)*k
 
# Can't add directly to a rational, one must make a quaternion of it
r := 5/3*b[1];
# (5/3)*e
r + q;
# (8/3)*e+(2)*i+(3)*j+(4)*k
 
# For multiplication, no problem (we are in an algebra over rationals !)
r*q;
# (5/3)*e+(10/3)*i+(5)*j+(20/3)*k
5/3*q;
# (5/3)*e+(10/3)*i+(5)*j+(20/3)*k
 
# Negative
-q;
(-1)*e+(-2)*i+(-3)*j+(-4)*k
 
 
# While quaternions are built-in, you can define an algebra in GAP by specifying it's multiplication table.
# See tutorial, p. 60, and reference of the functions used below.
 
# A multiplication table of dimension 4.
 
T := EmptySCTable(4, 0);
SetEntrySCTable(T, 1, 1, [1, 1]);
SetEntrySCTable(T, 1, 2, [1, 2]);
SetEntrySCTable(T, 1, 3, [1, 3]);
SetEntrySCTable(T, 1, 4, [1, 4]);
SetEntrySCTable(T, 2, 1, [1, 2]);
SetEntrySCTable(T, 2, 2, [-1, 1]);
SetEntrySCTable(T, 2, 3, [1, 4]);
SetEntrySCTable(T, 2, 4, [-1, 3]);
SetEntrySCTable(T, 3, 1, [1, 3]);
SetEntrySCTable(T, 3, 2, [-1, 4]);
SetEntrySCTable(T, 3, 3, [-1, 1]);
SetEntrySCTable(T, 3, 4, [1, 2]);
SetEntrySCTable(T, 4, 1, [1, 4]);
SetEntrySCTable(T, 4, 2, [1, 3]);
SetEntrySCTable(T, 4, 3, [-1, 2]);
SetEntrySCTable(T, 4, 4, [-1, 1]);
 
A := AlgebraByStructureConstants(Rationals, T, ["e", "i", "j", "k"]);
b := GeneratorsOfAlgebra(A);
 
IsAssociative(A);
# true
 
IsCommutative(A);
# false
 
# Then, like above
 
q := [1, 2, 3, 4]*b;
# e+(2)*i+(3)*j+(4)*k
 
# However, as is, GAP does not know division or conjugate on this algebra.
# QuaternionAlgebra is useful as well for extensions of rationals,
# and this one _has_ conjugate and division, as seen previously.
 
# Try this on Q[z] where z is the square root of 5 (in GAP it's ER(5))
F := FieldByGenerators([ER(5)]);
A := QuaternionAlgebra(F);
b := GeneratorsOfAlgebra(A);
 
q := [1, 2, 3, 4]*b;
# e+(2)*i+(3)*j+(4)*k
 
# Conjugate and division
 
ComplexConjugate(q);
# e+(-2)*i+(-3)*j+(-4)*k
 
1/q;
# (1/30)*e+(-1/15)*i+(-1/10)*j+(-2/15)*k