# FromQuaternion and QuaternionQ not working symbolically?

How can I get Mathematica to work with quaternions symbolically? I want to do some quaternion math without defining the actual coefficients, and then extract the coefficients from the resulting quaternion. For some reason, however, FromQuaternion only seems to work when values rather than symbols are the coefficients. The following simple examples illustrate the problem.

If I run the following:

QuaternionQ[Quaternion[1, 2, 3, 4]]
FromQuaternion[Quaternion[1, 2, 3, 4]]


The output is as expected:

True
3J + 4K + (1 + 2I)

However, if I run the following (with A0-A3 undefined):

QuaternionQ[Quaternion[A0, A1, A2, A3]]
FromQuaternion[Quaternion[A0, A1, A2, A3]]


I get

False
FromQuaternion(Quaternion(A0, A1, A2, A3))

I was expecting

True
A0 + A1 I + A2 J + A3 K


However, Mathematica seems to be perfectly happy to perform functions like:

Quaternion[A0, A1, A2, A3] ** Quaternion[B0, B1, B2, B3]


With the following result

Quaternion[A0 B0 - A1 B1 - A2 B2 - A3 B3,
A0 B1 + A1 B0 + A2 B3 - A3 B2,
A0 B2 - A1 B3 + A2 B0 + A3 B1,
A0 B3 + A1 B2 - A2 B1 + A3 B0]

but there seems to be no way to extract the components.

Finally, is there a function for just extracting one of the components. For instance, say Q = Quaternion[a, b, c ,d]. I would like a function like I[q] which returns b, J[q] which returns c, etc.

-
Ok, hadn't ever really looked carefully at patterns in MM. Figured out that if Q is a quaternion, then I can simply use something like Q /. Quaternion[q0_, q1_, q2_, q3_] -> q0 to extract various components. This is fine, but I still want to know why QuaternionQ and FromQuaternion don't work. –  jcb Mar 28 '13 at 20:46
You can also use Q[[1]] to get the first part, Q[[2]] for the second etc... –  Ajasja Mar 28 '13 at 21:20

A look at how QuaternionQ[] is defined in the package reveals the trouble: it is dependent on the private function ScalarQ[] for checking its individual components. ScalarQ[] is defined this way:

ScalarQ[x_]:= (NumericQ[x] && Head[x] =!= Complex)


It is clear that none of the components of Quaternion[A0, A1, A2, A3] will pass ScalarQ[], and thus QuaternionQ[] returns False. Relatedly, FromQuaternion[] also depends on QuaternionQ[] (and thus ScalarQ[]), which is why it also doesn't work for your symbolic quaternion.

Thus, when testing for not necessarily numeric quaternions, you might want to do something like MatchQ[Quaternion[A0, A1, A2, A3], _Quaternion], and use {1, I, J, K}.(List @@ expr) for conversion to an explicit form.

Finally, for extracting components of symbolic quaternions, look up Part[] or Extract[].

-