# solving for the center of the real quaternions

I'm trying out Sage on quaternions, on the problem of finding the center of the real Hamiltonian quaternions $\mathbb{H}$. So what I tried was:

Q.<i,j,k> = QuaternionAlgebra(SR, -1, -1)

a1, b1, c1, d1 = SR.var('a1, b1, c1, d1', domain = RR)
a2, b2, c2, d2 = SR.var('a2, b2, c2, d2', domain = RR)

q1 = a1 + b1*i + c1*j + d1*k
q2 = a2 + b2*i + c2*j + d2*k

solve(q1*q2 - q2*q1, a1, b1, c1, d1)


which rewarded me with:

TypeError                                 Traceback (most recent call last)
<ipython-input-6-8a6c0ff8f7d0> in <module>()
9 q2 = a2 + b2*i + c2*j + d2*k
10
---> 11 solve(q1*q2 - q2*q1, [a1, b1, c1, d1])

/home/sage/sage/local/lib/python3.7/site-packages/sage/symbolic/relation.py in solve(f, *args, **kwds)
1045
1046     if not isinstance(f, (list, tuple)):
-> 1047         raise TypeError("The first argument must be a symbolic expression or a list of symbolic expressions.")
1048
1049     # f is a list of such expressions or equations

TypeError: The first argument must be a symbolic expression or a list of symbolic expressions.


Well, OK, that's not a symbolic expression:

sage: type(q1*q2 - q2*q1)
<class 'sage.algebras.quatalg.quaternion_algebra_element.QuaternionAlgebraElement_generic'>


At least this looks right:

sage: q1*q2 - q2*q1
((c1 - d1)*(c2 + d2) - (c1 + d1)*(c2 - d2))*i + (2*b2*d1 - 2*b1*d2)*j + (-(a2 + b2)*(c1 + d1) + (a2 - b2)*(c1 + d1) + (a1 + b1)*(c2 + d2) - (a1 - b1)*(c2 + d2) + 2*b2*d1 - 2*b1*d2)*k


I can figure out the answer from the last line, but was hoping for something like $b_1 = c_1 = d_1 = 0$. Not sure how this works.

update: Updated to Sage 9.1.

edit retag close merge delete

1

Which version of sage ? Latest develop 9.4.beta1 says

sage: q1*q2 - q2*q1 == 0
(c1 - d1)*(c2 + d2) - (c1 + d1)*(c2 - d2) == 0

( 2021-06-09 08:34:26 +0200 )edit

@FrédéricC: Sage 8.6. Looks like I should upgrade by running the Docker image.

OK, yeah, I get that response now with the 9.1 image. Updated the question. 👍

( 2021-06-10 05:18:03 +0200 )edit

Sort by » oldest newest most voted

I do not know well the quaternion algebra implementation, so I may miss a better answer ; hence a workaround :

sage: Q.<i,j,k> = QuaternionAlgebra(SR, -1, -1)
sage: a1, b1, c1, d1 = SR.var('a1, b1, c1, d1', domain = "real") # Note : RR is a numerical approximation ring...
sage: a2, b2, c2, d2 = SR.var('a2, b2, c2, d2', domain = "real")
sage: q1 = a1 + b1*i + c1*j + d1*k
sage: q2 = a2 + b2*i + c2*j + d2*k
sage: solve((q1*q2-q2*q1).coefficient_tuple(), [a1, b1, c1, d1])
[[a1 == r3, b1 == r3*r4/b2, c1 == r4, d1 == c2*r4/b2]]


This answer can be obtained in a form slightly easier to use :

sage: Sol2 = solve((q1*q2-q2*q1).coefficient_tuple(), [a1, b1, c1, d1], algorithm="sympy") ; Sol2
[{b1: b2*d1/d2, c1: c2*d1/d2}]


(which do not involve new arbitrary variables.) or, shorter :

sage: solve((q1*q2-q2*q1).coefficient_tuple(), [a1, b1, c1, d1], algorithm="sympy")
[{b1: b2*d1/d2, c1: c2*d1/d2}]


HTH,

more

OK. I still feel like I'm missing how to express that I'm not interested in an answer based on specific a2, b2, c2, d2, but rather for any values of these.

But once again, I can easily finish the calculation with that stipulation.

Wondering why we need to convert to the coefficient tuple. 😕

( 2021-06-10 08:52:20 +0200 )edit

You can use polynomial rings over polynomial rings:

A.<a1,b1,c1,d1> = PolynomialRing(QQ, order='lex')
B.<a2,b2,c2,d2> = PolynomialRing(A)
Q.<i,j,k> = QuaternionAlgebra(B.fraction_field(), -1, -1)
q1 = a1 + b1*i + c1*j + d1*k
q2 = a2 + b2*i + c2*j + d2*k
I = A.ideal(sum([B(f).coefficients() for f in (q1*q2 - q2*q1).coefficient_tuple()], []))
I.groebner_basis()


Output:

[b1, c1, d1]


meaning $b_1=c_1=d_1=0$ needs to hold for $a_1 + b_1i + c_1j + d_1k$ to be in the center, so the center is $\mathbb{R}$.

more