Write a named function or program that computes the quaternion product of two quaternions. Use as few bytes as possible.
Quaternions
Quaternions are an extension of the real numbers that further extends the complex numbers. Rather than a single imaginary unit i
, quaternions use three imaginary units i,j,k
that satisfy the relationships.
i*i = j*j = k*k = -1
i*j = k
j*i = -k
j*k = i
k*j = -i
k*i = j
i*k = -j
(There's also tables of these on the Wikipedia page.)
In words, each imaginary unit squares to -1
, and the product of two different imaginary units is the remaining third one with a +/-
depending on whether the cyclic order (i,j,k)
is respected (i.e., the right-hand-rule). So, the order of multiplication matters.
A general quaternion is a linear combination of a real part and the three imaginary units. So, it is described by four real numbers (a,b,c,d)
.
x = a + b*i + c*j + d*k
So, we can multiply two quaternions using the distributive property, being careful to multiply the units in the right order, and grouping like terms in the result.
(a + b*i + c*j + d*k) * (e + f*i + g*j + h*k)
= (a*e - b*f - c*g - d*h) +
(a*f + b*e + c*h - d*g)*i +
(a*g - b*h + c*e + d*f)*j +
(a*h + b*g - c*f + d*e)*k
Seen this way, quaternion multiplication can be seen as a map from a pair of 4-tuples to a single 4-tuples, which is what you're asked to implement.
Format
You should write either a program or named function. A program should take inputs from STDIN and print out the result. A function should take in function inputs and return (not print) an output.
Input and output formats are flexible. The input is eight real numbers (the coefficients for two quaternions), and the output consists of four real numbers. The input might be eight numbers, two lists of four numbers, a 2x4 matrix, etc. The input/output format don't have to be the same.The ordering of the (1,i,j,k)
coefficients is up to you.
The coefficients can be negative or non-whole. Don't worry about real precision or overflows.
Banned: Function or types specifically for quaternions or equivalents.
Test cases
These are in (1,i,j,k)
coefficient format.
[[12, 54, -2, 23], [1, 4, 6, -2]]
[-146, -32, 270, 331]
[[1, 4, 6, -2], [12, 54, -2, 23]]
[-146, 236, -130, -333]
[[3.5, 4.6, -0.24, 0], [2.1, -3, -4.3, -12]]
[20.118, 2.04, 39.646, -62.5]
Reference Implementation
In Python, as function:
#Input quaternions: [a,b,c,d], [e,f,g,h]
#Coeff order: [1,i,j,k]
def mult(a,b,c,d,e,f,g,h):
coeff_1 = a*e-b*f-c*g-d*h
coeff_i = a*f+b*e+c*h-d*g
coeff_j = a*g-b*h+c*e+d*f
coeff_k = a*h+b*g-c*f+d*e
result = [coeff_1, coeff_i, coeff_j, coeff_k]
return result