Ask Your Question
4

radical expression for algebraic number

asked 2013-02-01 08:02:24 -0500

MvG gravatar image

updated 2013-02-01 08:27:28 -0500

What is the easiest way to turn an algebraic number (i.e. an element of QQbar) into a symbolic expression involving radicals? I know that this is only possible if the degree of the minimal polynomial does not exceed 4, but for those cases I'd have hoped to find an easy solution, but haven't found one yet.

Example of where this would be useful:

sage: M = Matrix([[1,2],[3,4]])
sage: M.parent()
Full MatrixSpace of 2 by 2 dense matrices over Integer Ring

Simply applying gram_schmidt over ZZ will fail:

sage: M.gram_schmidt(True)[0]
TypeError: QR decomposition unable to compute square roots in Rational Field

Changing to the symbolic ring won't help either:

sage: M.change_ring(SR).gram_schmidt(True)[0]
NotImplementedError: Gram-Scmidt orthogonalization not implemented
for matrices over inexact rings, except for RDF and CDF

Changing to the algebraic numbers lets me compute the matrix, but reading the result is kind of hard.

sage: N = M.change_ring(QQbar).gram_schmidt(True)[0]
sage: N
[ 0.4472135954999580?  0.8944271909999159?]
[ 0.8944271909999159? -0.4472135954999580?]

But all the numbers in there are actually simple square roots, as the minimal polynomials will show.

sage: N.apply_map(lambda x: x.minpoly())
[x^2 - 1/5 x^2 - 4/5]
[x^2 - 4/5 x^2 - 1/5]

So I wrote my own function to convert real algebraic numbers of degree two to symbolic expressions.

sage: def AA2SR(x):
....:     x = AA(x)
....:     p = x.minpoly()
....:     if p.degree() < 2:
....:         return SR(QQ(x))
....:     if p.degree() > 2:
....:         raise TypeError("Cannot handle degrees > 2")
....:     c, b, a = p.coeffs()
....:     y = (-b+sqrt(b*b-4*a*c))/(2*a)
....:     if x == AA(y):
....:         return y
....:     y = (-b-sqrt(b*b-4*a*c))/(2*a)
....:     assert x == AA(y)
....:     return y
....:
sage: M.change_ring(QQbar).gram_schmidt(True)[0].apply_map(AA2SR)
[  sqrt(1/5) 2*sqrt(1/5)]
[2*sqrt(1/5)  -sqrt(1/5)]

But pasting that code into every sage session where I might need it feels rather ugly. I would have hoped that there is some easier way to achieve what I'm doing here. Is there?

edit retag flag offensive close merge delete

Comments

Created http://trac.sagemath.org/sage_trac/ticket/14239 to request such methods.

MvG gravatar imageMvG ( 2013-03-06 09:46:27 -0500 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2013-02-22 12:57:33 -0500

lftabera gravatar image

If you want the Gram-Schmidt basis you could compute it and then normalize by hand. This is suboptimal though.

sage: M = Matrix([[1,2],[3,4]])
sage: [v.normalized() for v in M.gram_schmidt()[0].rows()]
[(1/5*sqrt(5), 2/5*sqrt(5)), (2*sqrt(1/5), -sqrt(1/5))]
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2013-02-01 08:02:24 -0500

Seen: 348 times

Last updated: Feb 22 '13