Algebraic numbers#
This module implements the algebraic numbers (the complex
numbers which are the zero of a polynomial in \(\ZZ[x]\); in other
words, the algebraic closure of \(\QQ\), with an embedding into \(\CC\)).
All computations are exact. We also include an implementation of the
algebraic reals (the intersection of the algebraic numbers with
\(\RR\)). The field of algebraic numbers \(\QQbar\) is available with
abbreviation QQbar
; the field of algebraic reals has abbreviation
AA
.
As with many other implementations of the algebraic numbers, we try hard to avoid computing a number field and working in the number field; instead, we use floating-point interval arithmetic whenever possible (basically whenever we need to prove non-equalities), and resort to symbolic computation only as needed (basically to prove equalities).
Algebraic numbers exist in one of the following forms:
a rational number
the sum, difference, product, or quotient of algebraic numbers
the negation, inverse, absolute value, norm, real part, imaginary part, or complex conjugate of an algebraic number
a particular root of a polynomial, given as a polynomial with algebraic coefficients together with an isolating interval (given as a
RealIntervalFieldElement
) which encloses exactly one root, and the multiplicity of the roota polynomial in one generator, where the generator is an algebraic number given as the root of an irreducible polynomial with integral coefficients and the polynomial is given as a
NumberFieldElement
.
An algebraic number can be coerced into ComplexIntervalField
(or
RealIntervalField
, for algebraic reals); every algebraic number has a
cached interval of the highest precision yet calculated.
In most cases, computations that need to compare two algebraic numbers compute them with 128-bit precision intervals; if this does not suffice to prove that the numbers are different, then we fall back on exact computation.
Note that division involves an implicit comparison of the divisor against zero, and may thus trigger exact computation.
Also, using an algebraic number in the leading coefficient of a polynomial also involves an implicit comparison against zero, which again may trigger exact computation.
Note that we work fairly hard to avoid computing new number fields; to help, we keep a lattice of already-computed number fields and their inclusions.
EXAMPLES:
sage: sqrt(AA(2)) > 0
True
sage: (sqrt(5 + 2*sqrt(QQbar(6))) - sqrt(QQbar(3)))^2 == 2
True
sage: AA((sqrt(5 + 2*sqrt(6)) - sqrt(3))^2) == 2 # needs sage.symbolic
True
>>> from sage.all import *
>>> sqrt(AA(Integer(2))) > Integer(0)
True
>>> (sqrt(Integer(5) + Integer(2)*sqrt(QQbar(Integer(6)))) - sqrt(QQbar(Integer(3))))**Integer(2) == Integer(2)
True
>>> AA((sqrt(Integer(5) + Integer(2)*sqrt(Integer(6))) - sqrt(Integer(3)))**Integer(2)) == Integer(2) # needs sage.symbolic
True
For a monic cubic polynomial \(x^3 + bx^2 + cx + d\) with roots \(s1\), \(s2\), \(s3\), the discriminant is defined as \((s1-s2)^2(s1-s3)^2(s2-s3)^2\) and can be computed as \(b^2c^2 - 4b^3d - 4c^3 + 18bcd - 27d^2\). We can test that these definitions do give the same result:
sage: def disc1(b, c, d):
....: return b^2*c^2 - 4*b^3*d - 4*c^3 + 18*b*c*d - 27*d^2
sage: def disc2(s1, s2, s3):
....: return ((s1-s2)*(s1-s3)*(s2-s3))^2
sage: x = polygen(AA)
sage: p = x*(x-2)*(x-4)
sage: cp = AA.common_polynomial(p)
sage: d, c, b, _ = p.list()
sage: s1 = AA.polynomial_root(cp, RIF(-1, 1))
sage: s2 = AA.polynomial_root(cp, RIF(1, 3))
sage: s3 = AA.polynomial_root(cp, RIF(3, 5))
sage: disc1(b, c, d) == disc2(s1, s2, s3)
True
sage: p = p + 1
sage: cp = AA.common_polynomial(p)
sage: d, c, b, _ = p.list()
sage: s1 = AA.polynomial_root(cp, RIF(-1, 1))
sage: s2 = AA.polynomial_root(cp, RIF(1, 3))
sage: s3 = AA.polynomial_root(cp, RIF(3, 5))
sage: disc1(b, c, d) == disc2(s1, s2, s3)
True
sage: p = (x-sqrt(AA(2)))*(x-AA(2).nth_root(3))*(x-sqrt(AA(3)))
sage: cp = AA.common_polynomial(p)
sage: d, c, b, _ = p.list()
sage: s1 = AA.polynomial_root(cp, RIF(1.4, 1.5))
sage: s2 = AA.polynomial_root(cp, RIF(1.7, 1.8))
sage: s3 = AA.polynomial_root(cp, RIF(1.2, 1.3))
sage: disc1(b, c, d) == disc2(s1, s2, s3)
True
>>> from sage.all import *
>>> def disc1(b, c, d):
... return b**Integer(2)*c**Integer(2) - Integer(4)*b**Integer(3)*d - Integer(4)*c**Integer(3) + Integer(18)*b*c*d - Integer(27)*d**Integer(2)
>>> def disc2(s1, s2, s3):
... return ((s1-s2)*(s1-s3)*(s2-s3))**Integer(2)
>>> x = polygen(AA)
>>> p = x*(x-Integer(2))*(x-Integer(4))
>>> cp = AA.common_polynomial(p)
>>> d, c, b, _ = p.list()
>>> s1 = AA.polynomial_root(cp, RIF(-Integer(1), Integer(1)))
>>> s2 = AA.polynomial_root(cp, RIF(Integer(1), Integer(3)))
>>> s3 = AA.polynomial_root(cp, RIF(Integer(3), Integer(5)))
>>> disc1(b, c, d) == disc2(s1, s2, s3)
True
>>> p = p + Integer(1)
>>> cp = AA.common_polynomial(p)
>>> d, c, b, _ = p.list()
>>> s1 = AA.polynomial_root(cp, RIF(-Integer(1), Integer(1)))
>>> s2 = AA.polynomial_root(cp, RIF(Integer(1), Integer(3)))
>>> s3 = AA.polynomial_root(cp, RIF(Integer(3), Integer(5)))
>>> disc1(b, c, d) == disc2(s1, s2, s3)
True
>>> p = (x-sqrt(AA(Integer(2))))*(x-AA(Integer(2)).nth_root(Integer(3)))*(x-sqrt(AA(Integer(3))))
>>> cp = AA.common_polynomial(p)
>>> d, c, b, _ = p.list()
>>> s1 = AA.polynomial_root(cp, RIF(RealNumber('1.4'), RealNumber('1.5')))
>>> s2 = AA.polynomial_root(cp, RIF(RealNumber('1.7'), RealNumber('1.8')))
>>> s3 = AA.polynomial_root(cp, RIF(RealNumber('1.2'), RealNumber('1.3')))
>>> disc1(b, c, d) == disc2(s1, s2, s3)
True
We can convert from symbolic expressions:
sage: # needs sage.symbolic
sage: QQbar(sqrt(-5))
2.236067977499790?*I
sage: AA(sqrt(2) + sqrt(3))
3.146264369941973?
sage: QQbar(I)
I
sage: QQbar(I * golden_ratio)
1.618033988749895?*I
sage: AA(golden_ratio)^2 - AA(golden_ratio)
1
sage: QQbar((-8)^(1/3))
1.000000000000000? + 1.732050807568878?*I
sage: AA((-8)^(1/3))
-2
sage: QQbar((-4)^(1/4))
1 + 1*I
sage: AA((-4)^(1/4))
Traceback (most recent call last):
...
ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real
>>> from sage.all import *
>>> # needs sage.symbolic
>>> QQbar(sqrt(-Integer(5)))
2.236067977499790?*I
>>> AA(sqrt(Integer(2)) + sqrt(Integer(3)))
3.146264369941973?
>>> QQbar(I)
I
>>> QQbar(I * golden_ratio)
1.618033988749895?*I
>>> AA(golden_ratio)**Integer(2) - AA(golden_ratio)
1
>>> QQbar((-Integer(8))**(Integer(1)/Integer(3)))
1.000000000000000? + 1.732050807568878?*I
>>> AA((-Integer(8))**(Integer(1)/Integer(3)))
-2
>>> QQbar((-Integer(4))**(Integer(1)/Integer(4)))
1 + 1*I
>>> AA((-Integer(4))**(Integer(1)/Integer(4)))
Traceback (most recent call last):
...
ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real
The coercion, however, goes in the other direction, since not all symbolic expressions are algebraic numbers:
sage: QQbar(sqrt(2)) + sqrt(3) # needs sage.symbolic
sqrt(3) + 1.414213562373095?
sage: QQbar(sqrt(2) + QQbar(sqrt(3))) # needs sage.symbolic
3.146264369941973?
>>> from sage.all import *
>>> QQbar(sqrt(Integer(2))) + sqrt(Integer(3)) # needs sage.symbolic
sqrt(3) + 1.414213562373095?
>>> QQbar(sqrt(Integer(2)) + QQbar(sqrt(Integer(3)))) # needs sage.symbolic
3.146264369941973?
Note the different behavior in taking roots: for AA
we prefer real
roots if they exist, but for QQbar
we take the principal root:
sage: AA(-1)^(1/3)
-1
sage: QQbar(-1)^(1/3)
0.500000000000000? + 0.866025403784439?*I
>>> from sage.all import *
>>> AA(-Integer(1))**(Integer(1)/Integer(3))
-1
>>> QQbar(-Integer(1))**(Integer(1)/Integer(3))
0.500000000000000? + 0.866025403784439?*I
However, implicit coercion from \(\QQ[I]\) is only allowed when it is equipped with a complex embedding:
sage: i.parent()
Number Field in I with defining polynomial x^2 + 1 with I = 1*I
sage: QQbar(1) + i
I + 1
sage: K.<im> = QuadraticField(-1, embedding=None)
sage: QQbar(1) + im
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for +: 'Algebraic Field' and
'Number Field in im with defining polynomial x^2 + 1'
>>> from sage.all import *
>>> i.parent()
Number Field in I with defining polynomial x^2 + 1 with I = 1*I
>>> QQbar(Integer(1)) + i
I + 1
>>> K = QuadraticField(-Integer(1), embedding=None, names=('im',)); (im,) = K._first_ngens(1)
>>> QQbar(Integer(1)) + im
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for +: 'Algebraic Field' and
'Number Field in im with defining polynomial x^2 + 1'
However, we can explicitly coerce from the abstract number field \(\QQ[I]\). (Technically, this is not quite kosher, since we do not know whether the field generator is supposed to map to \(+I\) or \(-I\). We assume that for any quadratic field with polynomial \(x^2+1\), the generator maps to \(+I\).):
sage: pythag = QQbar(3/5 + 4*im/5); pythag
4/5*I + 3/5
sage: pythag.abs() == 1
True
>>> from sage.all import *
>>> pythag = QQbar(Integer(3)/Integer(5) + Integer(4)*im/Integer(5)); pythag
4/5*I + 3/5
>>> pythag.abs() == Integer(1)
True
We can implicitly coerce from algebraic reals to algebraic numbers:
sage: a = QQbar(1); a, a.parent()
(1, Algebraic Field)
sage: b = AA(1); b, b.parent()
(1, Algebraic Real Field)
sage: c = a + b; c, c.parent()
(2, Algebraic Field)
>>> from sage.all import *
>>> a = QQbar(Integer(1)); a, a.parent()
(1, Algebraic Field)
>>> b = AA(Integer(1)); b, b.parent()
(1, Algebraic Real Field)
>>> c = a + b; c, c.parent()
(2, Algebraic Field)
Some computation with radicals:
sage: phi = (1 + sqrt(AA(5))) / 2
sage: phi^2 == phi + 1
True
sage: tau = (1 - sqrt(AA(5))) / 2
sage: tau^2 == tau + 1
True
sage: phi + tau == 1
True
sage: tau < 0
True
sage: rt23 = sqrt(AA(2/3))
sage: rt35 = sqrt(AA(3/5))
sage: rt25 = sqrt(AA(2/5))
sage: rt23 * rt35 == rt25
True
>>> from sage.all import *
>>> phi = (Integer(1) + sqrt(AA(Integer(5)))) / Integer(2)
>>> phi**Integer(2) == phi + Integer(1)
True
>>> tau = (Integer(1) - sqrt(AA(Integer(5)))) / Integer(2)
>>> tau**Integer(2) == tau + Integer(1)
True
>>> phi + tau == Integer(1)
True
>>> tau < Integer(0)
True
>>> rt23 = sqrt(AA(Integer(2)/Integer(3)))
>>> rt35 = sqrt(AA(Integer(3)/Integer(5)))
>>> rt25 = sqrt(AA(Integer(2)/Integer(5)))
>>> rt23 * rt35 == rt25
True
The Sage rings AA
and QQbar
can decide equalities between radical
expressions (over the reals and complex numbers respectively):
sage: a = AA((2/(3*sqrt(3)) + 10/27)^(1/3) # needs sage.symbolic
....: - 2/(9*(2/(3*sqrt(3)) + 10/27)^(1/3)) + 1/3)
sage: a # needs sage.symbolic
1.000000000000000?
sage: a == 1 # needs sage.symbolic
True
>>> from sage.all import *
>>> a = AA((Integer(2)/(Integer(3)*sqrt(Integer(3))) + Integer(10)/Integer(27))**(Integer(1)/Integer(3)) # needs sage.symbolic
... - Integer(2)/(Integer(9)*(Integer(2)/(Integer(3)*sqrt(Integer(3))) + Integer(10)/Integer(27))**(Integer(1)/Integer(3))) + Integer(1)/Integer(3))
>>> a # needs sage.symbolic
1.000000000000000?
>>> a == Integer(1) # needs sage.symbolic
True
Algebraic numbers which are known to be rational print as rationals; otherwise they print as intervals (with 53-bit precision):
sage: AA(2)/3
2/3
sage: QQbar(5/7)
5/7
sage: QQbar(1/3 - 1/4*I)
-1/4*I + 1/3
sage: two = QQbar(4).nth_root(4)^2; two
2.000000000000000?
sage: two == 2; two
True
2
sage: phi
1.618033988749895?
>>> from sage.all import *
>>> AA(Integer(2))/Integer(3)
2/3
>>> QQbar(Integer(5)/Integer(7))
5/7
>>> QQbar(Integer(1)/Integer(3) - Integer(1)/Integer(4)*I)
-1/4*I + 1/3
>>> two = QQbar(Integer(4)).nth_root(Integer(4))**Integer(2); two
2.000000000000000?
>>> two == Integer(2); two
True
2
>>> phi
1.618033988749895?
We can find the real and imaginary parts of an algebraic number (exactly):
sage: r = QQbar.polynomial_root(x^5 - x - 1, CIF(RIF(0.1, 0.2), RIF(1.0, 1.1))); r
0.1812324444698754? + 1.083954101317711?*I
sage: r.real()
0.1812324444698754?
sage: r.imag()
1.083954101317711?
sage: r.minpoly()
x^5 - x - 1
sage: r.real().minpoly()
x^10 + 3/16*x^6 + 11/32*x^5 - 1/64*x^2 + 1/128*x - 1/1024
sage: r.imag().minpoly() # long time (10s on sage.math, 2013)
x^20 - 5/8*x^16 - 95/256*x^12 - 625/1024*x^10 - 5/512*x^8 - 1875/8192*x^6 + 25/4096*x^4 - 625/32768*x^2 + 2869/1048576
>>> from sage.all import *
>>> r = QQbar.polynomial_root(x**Integer(5) - x - Integer(1), CIF(RIF(RealNumber('0.1'), RealNumber('0.2')), RIF(RealNumber('1.0'), RealNumber('1.1')))); r
0.1812324444698754? + 1.083954101317711?*I
>>> r.real()
0.1812324444698754?
>>> r.imag()
1.083954101317711?
>>> r.minpoly()
x^5 - x - 1
>>> r.real().minpoly()
x^10 + 3/16*x^6 + 11/32*x^5 - 1/64*x^2 + 1/128*x - 1/1024
>>> r.imag().minpoly() # long time (10s on sage.math, 2013)
x^20 - 5/8*x^16 - 95/256*x^12 - 625/1024*x^10 - 5/512*x^8 - 1875/8192*x^6 + 25/4096*x^4 - 625/32768*x^2 + 2869/1048576
We can find the absolute value and norm of an algebraic number exactly.
(Note that we define the norm as the product of a number and its
complex conjugate; this is the algebraic definition of norm, if we
view QQbar
as AA[I]
.):
sage: R.<x> = QQ[]
sage: r = (x^3 + 8).roots(QQbar, multiplicities=False)[2]; r
1.000000000000000? + 1.732050807568878?*I
sage: r.abs() == 2
True
sage: r.norm() == 4
True
sage: (r+QQbar(I)).norm().minpoly()
x^2 - 10*x + 13
sage: r = AA.polynomial_root(x^2 - x - 1, RIF(-1, 0)); r
-0.618033988749895?
sage: r.abs().minpoly()
x^2 + x - 1
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> r = (x**Integer(3) + Integer(8)).roots(QQbar, multiplicities=False)[Integer(2)]; r
1.000000000000000? + 1.732050807568878?*I
>>> r.abs() == Integer(2)
True
>>> r.norm() == Integer(4)
True
>>> (r+QQbar(I)).norm().minpoly()
x^2 - 10*x + 13
>>> r = AA.polynomial_root(x**Integer(2) - x - Integer(1), RIF(-Integer(1), Integer(0))); r
-0.618033988749895?
>>> r.abs().minpoly()
x^2 + x - 1
We can compute the multiplicative order of an algebraic number:
sage: QQbar(-1/2 + I*sqrt(3)/2).multiplicative_order() # needs sage.symbolic
3
sage: QQbar(-sqrt(3)/2 + I/2).multiplicative_order() # needs sage.symbolic
12
sage: (QQbar.zeta(23)**5).multiplicative_order()
23
>>> from sage.all import *
>>> QQbar(-Integer(1)/Integer(2) + I*sqrt(Integer(3))/Integer(2)).multiplicative_order() # needs sage.symbolic
3
>>> QQbar(-sqrt(Integer(3))/Integer(2) + I/Integer(2)).multiplicative_order() # needs sage.symbolic
12
>>> (QQbar.zeta(Integer(23))**Integer(5)).multiplicative_order()
23
The paper “ARPREC: An Arbitrary Precision Computation Package” by Bailey, Yozo, Li and Thompson discusses this result. Evidently it is difficult to find, but we can easily verify it.
sage: alpha = QQbar.polynomial_root(x^10 + x^9 - x^7 - x^6
....: - x^5 - x^4 - x^3 + x + 1, RIF(1, 1.2))
sage: lhs = alpha^630 - 1
sage: rhs_num = (alpha^315 - 1) * (alpha^210 - 1) * (alpha^126 - 1)^2 * (alpha^90 - 1) * (alpha^3 - 1)^3 * (alpha^2 - 1)^5 * (alpha - 1)^3
sage: rhs_den = (alpha^35 - 1) * (alpha^15 - 1)^2 * (alpha^14 - 1)^2 * (alpha^5 - 1)^6 * alpha^68
sage: rhs = rhs_num / rhs_den
sage: lhs
2.642040335819351?e44
sage: rhs
2.642040335819351?e44
sage: lhs - rhs
0.?e29
sage: lhs == rhs
True
sage: lhs - rhs
0
sage: lhs._exact_value()
-10648699402510886229334132989629606002223831*a^9 + 23174560249100286133718183712802529035435800*a^8 - 27259790692625442252605558473646959458901265*a^7 + 21416469499004652376912957054411004410158065*a^6 - 14543082864016871805545108986578337637140321*a^5 + 6458050008796664339372667222902512216589785*a^4 + 3052219053800078449122081871454923124998263*a^3 - 14238966128623353681821644902045640915516176*a^2 + 16749022728952328254673732618939204392161001*a - 9052854758155114957837247156588012516273410 where a^10 - a^9 + a^7 - a^6 + a^5 - a^4 + a^3 - a + 1 = 0 and a in -1.176280818259918?
>>> from sage.all import *
>>> alpha = QQbar.polynomial_root(x**Integer(10) + x**Integer(9) - x**Integer(7) - x**Integer(6)
... - x**Integer(5) - x**Integer(4) - x**Integer(3) + x + Integer(1), RIF(Integer(1), RealNumber('1.2')))
>>> lhs = alpha**Integer(630) - Integer(1)
>>> rhs_num = (alpha**Integer(315) - Integer(1)) * (alpha**Integer(210) - Integer(1)) * (alpha**Integer(126) - Integer(1))**Integer(2) * (alpha**Integer(90) - Integer(1)) * (alpha**Integer(3) - Integer(1))**Integer(3) * (alpha**Integer(2) - Integer(1))**Integer(5) * (alpha - Integer(1))**Integer(3)
>>> rhs_den = (alpha**Integer(35) - Integer(1)) * (alpha**Integer(15) - Integer(1))**Integer(2) * (alpha**Integer(14) - Integer(1))**Integer(2) * (alpha**Integer(5) - Integer(1))**Integer(6) * alpha**Integer(68)
>>> rhs = rhs_num / rhs_den
>>> lhs
2.642040335819351?e44
>>> rhs
2.642040335819351?e44
>>> lhs - rhs
0.?e29
>>> lhs == rhs
True
>>> lhs - rhs
0
>>> lhs._exact_value()
-10648699402510886229334132989629606002223831*a^9 + 23174560249100286133718183712802529035435800*a^8 - 27259790692625442252605558473646959458901265*a^7 + 21416469499004652376912957054411004410158065*a^6 - 14543082864016871805545108986578337637140321*a^5 + 6458050008796664339372667222902512216589785*a^4 + 3052219053800078449122081871454923124998263*a^3 - 14238966128623353681821644902045640915516176*a^2 + 16749022728952328254673732618939204392161001*a - 9052854758155114957837247156588012516273410 where a^10 - a^9 + a^7 - a^6 + a^5 - a^4 + a^3 - a + 1 = 0 and a in -1.176280818259918?
Given an algebraic number, we can produce a string that will reproduce that algebraic number if you type the string into Sage. We can see that until exact computation is triggered, an algebraic number keeps track of the computation steps used to produce that number:
sage: rt2 = AA(sqrt(2))
sage: rt3 = AA(sqrt(3))
sage: n = (rt2 + rt3)^5; n
308.3018001722975?
sage: sage_input(n)
R.<x> = AA[]
v1 = AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) + AA.polynomial_root(AA.common_polynomial(x^2 - 3), RIF(RR(1.7320508075688772), RR(1.7320508075688774)))
v2 = v1*v1
v2*v2*v1
>>> from sage.all import *
>>> rt2 = AA(sqrt(Integer(2)))
>>> rt3 = AA(sqrt(Integer(3)))
>>> n = (rt2 + rt3)**Integer(5); n
308.3018001722975?
>>> sage_input(n)
R.<x> = AA[]
v1 = AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) + AA.polynomial_root(AA.common_polynomial(x^2 - 3), RIF(RR(1.7320508075688772), RR(1.7320508075688774)))
v2 = v1*v1
v2*v2*v1
But once exact computation is triggered, the computation tree is discarded, and we get a way to produce the number directly:
sage: n == 109*rt2 + 89*rt3
True
sage: sage_input(n)
R.<y> = QQ[]
v = AA.polynomial_root(AA.common_polynomial(y^4 - 4*y^2 + 1), RIF(-RR(1.9318516525781366), -RR(1.9318516525781364)))
-109*v^3 + 89*v^2 + 327*v - 178
>>> from sage.all import *
>>> n == Integer(109)*rt2 + Integer(89)*rt3
True
>>> sage_input(n)
R.<y> = QQ[]
v = AA.polynomial_root(AA.common_polynomial(y^4 - 4*y^2 + 1), RIF(-RR(1.9318516525781366), -RR(1.9318516525781364)))
-109*v^3 + 89*v^2 + 327*v - 178
We can also see that some computations (basically, those which are easy to perform exactly) are performed directly, instead of storing the computation tree:
sage: z3_3 = QQbar.zeta(3) * 3
sage: z4_4 = QQbar.zeta(4) * 4
sage: z5_5 = QQbar.zeta(5) * 5
sage: sage_input(z3_3 * z4_4 * z5_5)
R.<y> = QQ[]
3*QQbar.polynomial_root(AA.common_polynomial(y^2 + y + 1), CIF(RIF(-RR(0.50000000000000011), -RR(0.49999999999999994)), RIF(RR(0.8660254037844386), RR(0.86602540378443871))))*QQbar(4*I)*(5*QQbar.polynomial_root(AA.common_polynomial(y^4 + y^3 + y^2 + y + 1), CIF(RIF(RR(0.3090169943749474), RR(0.30901699437494745)), RIF(RR(0.95105651629515353), RR(0.95105651629515364)))))
>>> from sage.all import *
>>> z3_3 = QQbar.zeta(Integer(3)) * Integer(3)
>>> z4_4 = QQbar.zeta(Integer(4)) * Integer(4)
>>> z5_5 = QQbar.zeta(Integer(5)) * Integer(5)
>>> sage_input(z3_3 * z4_4 * z5_5)
R.<y> = QQ[]
3*QQbar.polynomial_root(AA.common_polynomial(y^2 + y + 1), CIF(RIF(-RR(0.50000000000000011), -RR(0.49999999999999994)), RIF(RR(0.8660254037844386), RR(0.86602540378443871))))*QQbar(4*I)*(5*QQbar.polynomial_root(AA.common_polynomial(y^4 + y^3 + y^2 + y + 1), CIF(RIF(RR(0.3090169943749474), RR(0.30901699437494745)), RIF(RR(0.95105651629515353), RR(0.95105651629515364)))))
Note that the verify=True
argument to sage_input
will always trigger
exact computation, so running sage_input
twice in a row on the same number
will actually give different answers. In the following, running sage_input
on n
will also trigger exact computation on rt2
, as you can see by the
fact that the third output is different than the first:
sage: # needs sage.symbolic
sage: rt2 = AA(sqrt(2))
sage: n = rt2^2
sage: sage_input(n, verify=True)
# Verified
R.<x> = AA[]
v = AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951)))
v*v
sage: sage_input(n, verify=True)
# Verified
AA(2)
sage: n = rt2^2
sage: sage_input(n, verify=True)
# Verified
AA(2)
>>> from sage.all import *
>>> # needs sage.symbolic
>>> rt2 = AA(sqrt(Integer(2)))
>>> n = rt2**Integer(2)
>>> sage_input(n, verify=True)
# Verified
R.<x> = AA[]
v = AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951)))
v*v
>>> sage_input(n, verify=True)
# Verified
AA(2)
>>> n = rt2**Integer(2)
>>> sage_input(n, verify=True)
# Verified
AA(2)
Just for fun, let’s try sage_input
on a very complicated expression. The
output of this example changed with the rewriting of polynomial multiplication
algorithms in Issue #10255:
sage: rt2 = sqrt(AA(2))
sage: rt3 = sqrt(QQbar(3))
sage: x = polygen(QQbar)
sage: nrt3 = AA.polynomial_root((x-rt2)*(x+rt3), RIF(-2, -1))
sage: one = AA.polynomial_root((x-rt2)*(x-rt3)*(x-nrt3)*(x-1-rt3-nrt3), RIF(0.9, 1.1))
sage: one
1.000000000000000?
sage: sage_input(one, verify=True)
# Verified
R1.<x> = QQbar[]
R2.<y> = QQ[]
v = AA.polynomial_root(AA.common_polynomial(y^4 - 4*y^2 + 1), RIF(-RR(1.9318516525781366), -RR(1.9318516525781364)))
AA.polynomial_root(AA.common_polynomial(x^4 + QQbar(v^3 - 3*v - 1)*x^3 + QQbar(-v^3 + 3*v - 3)*x^2 + QQbar(-3*v^3 + 9*v + 3)*x + QQbar(3*v^3 - 9*v)), RIF(RR(0.99999999999999989), RR(1.0000000000000002)))
sage: one
1
>>> from sage.all import *
>>> rt2 = sqrt(AA(Integer(2)))
>>> rt3 = sqrt(QQbar(Integer(3)))
>>> x = polygen(QQbar)
>>> nrt3 = AA.polynomial_root((x-rt2)*(x+rt3), RIF(-Integer(2), -Integer(1)))
>>> one = AA.polynomial_root((x-rt2)*(x-rt3)*(x-nrt3)*(x-Integer(1)-rt3-nrt3), RIF(RealNumber('0.9'), RealNumber('1.1')))
>>> one
1.000000000000000?
>>> sage_input(one, verify=True)
# Verified
R1.<x> = QQbar[]
R2.<y> = QQ[]
v = AA.polynomial_root(AA.common_polynomial(y^4 - 4*y^2 + 1), RIF(-RR(1.9318516525781366), -RR(1.9318516525781364)))
AA.polynomial_root(AA.common_polynomial(x^4 + QQbar(v^3 - 3*v - 1)*x^3 + QQbar(-v^3 + 3*v - 3)*x^2 + QQbar(-3*v^3 + 9*v + 3)*x + QQbar(3*v^3 - 9*v)), RIF(RR(0.99999999999999989), RR(1.0000000000000002)))
>>> one
1
We can pickle and unpickle algebraic fields (and they are globally unique):
sage: loads(dumps(AlgebraicField())) is AlgebraicField()
True
sage: loads(dumps(AlgebraicRealField())) is AlgebraicRealField()
True
>>> from sage.all import *
>>> loads(dumps(AlgebraicField())) is AlgebraicField()
True
>>> loads(dumps(AlgebraicRealField())) is AlgebraicRealField()
True
We can pickle and unpickle algebraic numbers:
sage: loads(dumps(QQbar(10))) == QQbar(10)
True
sage: loads(dumps(QQbar(5/2))) == QQbar(5/2)
True
sage: loads(dumps(QQbar.zeta(5))) == QQbar.zeta(5)
True
sage: # needs sage.symbolic
sage: t = QQbar(sqrt(2)); type(t._descr)
<class 'sage.rings.qqbar.ANRoot'>
sage: loads(dumps(t)) == QQbar(sqrt(2))
True
sage: t.exactify(); type(t._descr)
<class 'sage.rings.qqbar.ANExtensionElement'>
sage: loads(dumps(t)) == QQbar(sqrt(2))
True
sage: t = ~QQbar(sqrt(2)); type(t._descr)
<class 'sage.rings.qqbar.ANUnaryExpr'>
sage: loads(dumps(t)) == 1/QQbar(sqrt(2))
True
sage: t = QQbar(sqrt(2)) + QQbar(sqrt(3)); type(t._descr)
<class 'sage.rings.qqbar.ANBinaryExpr'>
sage: loads(dumps(t)) == QQbar(sqrt(2)) + QQbar(sqrt(3))
True
>>> from sage.all import *
>>> loads(dumps(QQbar(Integer(10)))) == QQbar(Integer(10))
True
>>> loads(dumps(QQbar(Integer(5)/Integer(2)))) == QQbar(Integer(5)/Integer(2))
True
>>> loads(dumps(QQbar.zeta(Integer(5)))) == QQbar.zeta(Integer(5))
True
>>> # needs sage.symbolic
>>> t = QQbar(sqrt(Integer(2))); type(t._descr)
<class 'sage.rings.qqbar.ANRoot'>
>>> loads(dumps(t)) == QQbar(sqrt(Integer(2)))
True
>>> t.exactify(); type(t._descr)
<class 'sage.rings.qqbar.ANExtensionElement'>
>>> loads(dumps(t)) == QQbar(sqrt(Integer(2)))
True
>>> t = ~QQbar(sqrt(Integer(2))); type(t._descr)
<class 'sage.rings.qqbar.ANUnaryExpr'>
>>> loads(dumps(t)) == Integer(1)/QQbar(sqrt(Integer(2)))
True
>>> t = QQbar(sqrt(Integer(2))) + QQbar(sqrt(Integer(3))); type(t._descr)
<class 'sage.rings.qqbar.ANBinaryExpr'>
>>> loads(dumps(t)) == QQbar(sqrt(Integer(2))) + QQbar(sqrt(Integer(3)))
True
We can convert elements of QQbar
and AA
into the following
types: float
, complex
, RDF
, CDF
, RR
, CC
,
RIF
, CIF
, ZZ
, and QQ
, with a few exceptions. (For the
arbitrary-precision types, RR
, CC
, RIF
, and CIF
, it
can convert into a field of arbitrary precision.)
Converting from QQbar
to a real type (float
, RDF
, RR
,
RIF
, ZZ
, or QQ
) succeeds only if the QQbar
is actually
real (has an imaginary component of exactly zero). Converting from
either AA
or QQbar
to ZZ
or QQ
succeeds only if the
number actually is an integer or rational. If conversion fails, a
ValueError will be raised.
Here are examples of all of these conversions:
sage: # needs sage.symbolic
sage: all_vals = [AA(42), AA(22/7), AA(golden_ratio),
....: QQbar(-13), QQbar(89/55), QQbar(-sqrt(7)), QQbar.zeta(5)]
sage: def convert_test_all(ty):
....: def convert_test(v):
....: try:
....: return ty(v)
....: except (TypeError, ValueError):
....: return None
....: return [convert_test(_) for _ in all_vals]
sage: convert_test_all(float)
[42.0, 3.1428571428571432, 1.618033988749895, -13.0, 1.6181818181818182, -2.6457513110645907, None]
sage: convert_test_all(complex)
[(42+0j), (3.1428571428571432+0j), (1.618033988749895+0j), (-13+0j), (1.6181818181818182+0j), (-2.6457513110645907+0j), (0.30901699437494745+0.9510565162951536j)]
sage: convert_test_all(RDF)
[42.0, 3.1428571428571432, 1.618033988749895, -13.0, 1.6181818181818182, -2.6457513110645907, None]
sage: convert_test_all(CDF)
[42.0, 3.1428571428571432, 1.618033988749895, -13.0, 1.6181818181818182, -2.6457513110645907, 0.30901699437494745 + 0.9510565162951536*I]
sage: convert_test_all(RR)
[42.0000000000000, 3.14285714285714, 1.61803398874989, -13.0000000000000, 1.61818181818182, -2.64575131106459, None]
sage: convert_test_all(CC)
[42.0000000000000, 3.14285714285714, 1.61803398874989, -13.0000000000000, 1.61818181818182, -2.64575131106459, 0.309016994374947 + 0.951056516295154*I]
sage: convert_test_all(RIF)
[42, 3.142857142857143?, 1.618033988749895?, -13, 1.618181818181819?, -2.645751311064591?, None]
sage: convert_test_all(CIF)
[42, 3.142857142857143?, 1.618033988749895?, -13, 1.618181818181819?, -2.645751311064591?, 0.3090169943749474? + 0.9510565162951536?*I]
sage: convert_test_all(ZZ)
[42, None, None, -13, None, None, None]
sage: convert_test_all(QQ)
[42, 22/7, None, -13, 89/55, None, None]
>>> from sage.all import *
>>> # needs sage.symbolic
>>> all_vals = [AA(Integer(42)), AA(Integer(22)/Integer(7)), AA(golden_ratio),
... QQbar(-Integer(13)), QQbar(Integer(89)/Integer(55)), QQbar(-sqrt(Integer(7))), QQbar.zeta(Integer(5))]
>>> def convert_test_all(ty):
... def convert_test(v):
... try:
... return ty(v)
... except (TypeError, ValueError):
... return None
... return [convert_test(_) for _ in all_vals]
>>> convert_test_all(float)
[42.0, 3.1428571428571432, 1.618033988749895, -13.0, 1.6181818181818182, -2.6457513110645907, None]
>>> convert_test_all(complex)
[(42+0j), (3.1428571428571432+0j), (1.618033988749895+0j), (-13+0j), (1.6181818181818182+0j), (-2.6457513110645907+0j), (0.30901699437494745+0.9510565162951536j)]
>>> convert_test_all(RDF)
[42.0, 3.1428571428571432, 1.618033988749895, -13.0, 1.6181818181818182, -2.6457513110645907, None]
>>> convert_test_all(CDF)
[42.0, 3.1428571428571432, 1.618033988749895, -13.0, 1.6181818181818182, -2.6457513110645907, 0.30901699437494745 + 0.9510565162951536*I]
>>> convert_test_all(RR)
[42.0000000000000, 3.14285714285714, 1.61803398874989, -13.0000000000000, 1.61818181818182, -2.64575131106459, None]
>>> convert_test_all(CC)
[42.0000000000000, 3.14285714285714, 1.61803398874989, -13.0000000000000, 1.61818181818182, -2.64575131106459, 0.309016994374947 + 0.951056516295154*I]
>>> convert_test_all(RIF)
[42, 3.142857142857143?, 1.618033988749895?, -13, 1.618181818181819?, -2.645751311064591?, None]
>>> convert_test_all(CIF)
[42, 3.142857142857143?, 1.618033988749895?, -13, 1.618181818181819?, -2.645751311064591?, 0.3090169943749474? + 0.9510565162951536?*I]
>>> convert_test_all(ZZ)
[42, None, None, -13, None, None, None]
>>> convert_test_all(QQ)
[42, 22/7, None, -13, 89/55, None, None]
Compute the exact coordinates of a 34-gon (the formulas used are from Weisstein, Eric W. “Trigonometry Angles–Pi/17.” and can be found at http://mathworld.wolfram.com/TrigonometryAnglesPi17.html):
sage: rt17 = AA(17).sqrt()
sage: rt2 = AA(2).sqrt()
sage: eps = (17 + rt17).sqrt()
sage: epss = (17 - rt17).sqrt()
sage: delta = rt17 - 1
sage: alpha = (34 + 6*rt17 + rt2*delta*epss - 8*rt2*eps).sqrt()
sage: beta = 2*(17 + 3*rt17 - 2*rt2*eps - rt2*epss).sqrt()
sage: x = rt2*(15 + rt17 + rt2*(alpha + epss)).sqrt()/8
sage: y = rt2*(epss**2 - rt2*(alpha + epss)).sqrt()/8
sage: cx, cy = 1, 0
sage: for i in range(34):
....: cx, cy = x*cx-y*cy, x*cy+y*cx
sage: cx
1.000000000000000?
sage: cy
0.?e-15
sage: ax = polygen(AA)
sage: x2 = AA.polynomial_root(256*ax**8 - 128*ax**7 - 448*ax**6 + 192*ax**5
....: + 240*ax**4 - 80*ax**3 - 40*ax**2 + 8*ax + 1,
....: RIF(0.9829, 0.983))
sage: y2 = (1 - x2**2).sqrt()
sage: x - x2
0.?e-18
sage: y - y2
0.?e-17
>>> from sage.all import *
>>> rt17 = AA(Integer(17)).sqrt()
>>> rt2 = AA(Integer(2)).sqrt()
>>> eps = (Integer(17) + rt17).sqrt()
>>> epss = (Integer(17) - rt17).sqrt()
>>> delta = rt17 - Integer(1)
>>> alpha = (Integer(34) + Integer(6)*rt17 + rt2*delta*epss - Integer(8)*rt2*eps).sqrt()
>>> beta = Integer(2)*(Integer(17) + Integer(3)*rt17 - Integer(2)*rt2*eps - rt2*epss).sqrt()
>>> x = rt2*(Integer(15) + rt17 + rt2*(alpha + epss)).sqrt()/Integer(8)
>>> y = rt2*(epss**Integer(2) - rt2*(alpha + epss)).sqrt()/Integer(8)
>>> cx, cy = Integer(1), Integer(0)
>>> for i in range(Integer(34)):
... cx, cy = x*cx-y*cy, x*cy+y*cx
>>> cx
1.000000000000000?
>>> cy
0.?e-15
>>> ax = polygen(AA)
>>> x2 = AA.polynomial_root(Integer(256)*ax**Integer(8) - Integer(128)*ax**Integer(7) - Integer(448)*ax**Integer(6) + Integer(192)*ax**Integer(5)
... + Integer(240)*ax**Integer(4) - Integer(80)*ax**Integer(3) - Integer(40)*ax**Integer(2) + Integer(8)*ax + Integer(1),
... RIF(RealNumber('0.9829'), RealNumber('0.983')))
>>> y2 = (Integer(1) - x2**Integer(2)).sqrt()
>>> x - x2
0.?e-18
>>> y - y2
0.?e-17
Ideally, in the above example we should be able to test x == x2
and y ==
y2
but this is currently infinitely long.
AUTHOR:
Carl Witty (2007-01-27): initial version
Carl Witty (2007-10-29): massive rewrite to support complex as well as real numbers
- class sage.rings.qqbar.ANBinaryExpr(left, right, op)[source]#
Bases:
ANDescr
Initialize this ANBinaryExpr.
EXAMPLES:
sage: t = QQbar(sqrt(2)) + QQbar(sqrt(3)); type(t._descr) # indirect doctest # needs sage.symbolic <class 'sage.rings.qqbar.ANBinaryExpr'>
>>> from sage.all import * >>> t = QQbar(sqrt(Integer(2))) + QQbar(sqrt(Integer(3))); type(t._descr) # indirect doctest # needs sage.symbolic <class 'sage.rings.qqbar.ANBinaryExpr'>
- handle_sage_input(sib, coerce, is_qqbar)[source]#
Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always
True
forANBinaryExpr
).EXAMPLES:
sage: sage_input(2 + sqrt(AA(2)), verify=True) # Verified R.<x> = AA[] 2 + AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) sage: sage_input(sqrt(AA(2)) + 2, verify=True) # Verified R.<x> = AA[] AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) + 2 sage: sage_input(2 - sqrt(AA(2)), verify=True) # Verified R.<x> = AA[] 2 - AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) sage: sage_input(2 / sqrt(AA(2)), verify=True) # Verified R.<x> = AA[] 2/AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) sage: sage_input(2 + (-1*sqrt(AA(2))), verify=True) # Verified R.<x> = AA[] 2 - AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) sage: sage_input(2*sqrt(AA(2)), verify=True) # Verified R.<x> = AA[] 2*AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) sage: rt2 = sqrt(AA(2)) sage: one = rt2/rt2 sage: n = one+3 sage: sage_input(n) R.<x> = AA[] v = AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) v/v + 3 sage: one == 1 True sage: sage_input(n) 1 + AA(3) sage: rt3 = QQbar(sqrt(3)) # needs sage.symbolic sage: one = rt3/rt3 # needs sage.symbolic sage: n = sqrt(AA(2)) + one sage: one == 1 # needs sage.symbolic True sage: sage_input(n) R.<x> = AA[] QQbar.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) + 1 sage: from sage.rings.qqbar import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() sage: binexp = ANBinaryExpr(AA(3), AA(5), operator.mul) sage: binexp.handle_sage_input(sib, False, False) ({binop:* {atomic:3} {call: {atomic:AA}({atomic:5})}}, True) sage: binexp.handle_sage_input(sib, False, True) ({call: {atomic:QQbar}({binop:* {atomic:3} {call: {atomic:AA}({atomic:5})}})}, True)
>>> from sage.all import * >>> sage_input(Integer(2) + sqrt(AA(Integer(2))), verify=True) # Verified R.<x> = AA[] 2 + AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) >>> sage_input(sqrt(AA(Integer(2))) + Integer(2), verify=True) # Verified R.<x> = AA[] AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) + 2 >>> sage_input(Integer(2) - sqrt(AA(Integer(2))), verify=True) # Verified R.<x> = AA[] 2 - AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) >>> sage_input(Integer(2) / sqrt(AA(Integer(2))), verify=True) # Verified R.<x> = AA[] 2/AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) >>> sage_input(Integer(2) + (-Integer(1)*sqrt(AA(Integer(2)))), verify=True) # Verified R.<x> = AA[] 2 - AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) >>> sage_input(Integer(2)*sqrt(AA(Integer(2))), verify=True) # Verified R.<x> = AA[] 2*AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) >>> rt2 = sqrt(AA(Integer(2))) >>> one = rt2/rt2 >>> n = one+Integer(3) >>> sage_input(n) R.<x> = AA[] v = AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) v/v + 3 >>> one == Integer(1) True >>> sage_input(n) 1 + AA(3) >>> rt3 = QQbar(sqrt(Integer(3))) # needs sage.symbolic >>> one = rt3/rt3 # needs sage.symbolic >>> n = sqrt(AA(Integer(2))) + one >>> one == Integer(1) # needs sage.symbolic True >>> sage_input(n) R.<x> = AA[] QQbar.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) + 1 >>> from sage.rings.qqbar import * >>> from sage.misc.sage_input import SageInputBuilder >>> sib = SageInputBuilder() >>> binexp = ANBinaryExpr(AA(Integer(3)), AA(Integer(5)), operator.mul) >>> binexp.handle_sage_input(sib, False, False) ({binop:* {atomic:3} {call: {atomic:AA}({atomic:5})}}, True) >>> binexp.handle_sage_input(sib, False, True) ({call: {atomic:QQbar}({binop:* {atomic:3} {call: {atomic:AA}({atomic:5})}})}, True)
- is_complex()[source]#
Whether this element is complex. Does not trigger exact computation, so may return
True
even if the element is real.EXAMPLES:
sage: x = (QQbar(sqrt(-2)) / QQbar(sqrt(-5)))._descr # needs sage.symbolic sage: x.is_complex() # needs sage.symbolic True
>>> from sage.all import * >>> x = (QQbar(sqrt(-Integer(2))) / QQbar(sqrt(-Integer(5))))._descr # needs sage.symbolic >>> x.is_complex() # needs sage.symbolic True
- class sage.rings.qqbar.ANDescr[source]#
Bases:
SageObject
An
AlgebraicNumber
orAlgebraicReal
is a wrapper around anANDescr
object.ANDescr
is an abstract base class, which should never be directly instantiated; its concrete subclasses areANRational
,ANBinaryExpr
,ANUnaryExpr
,ANRoot
, andANExtensionElement
.ANDescr
and all of its subclasses are for internal use, and should not be used directly.- abs(n)[source]#
Absolute value of self.
EXAMPLES:
sage: a = QQbar(sqrt(2)) # needs sage.symbolic sage: b = a._descr # needs sage.symbolic sage: b.abs(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
>>> from sage.all import * >>> a = QQbar(sqrt(Integer(2))) # needs sage.symbolic >>> b = a._descr # needs sage.symbolic >>> b.abs(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
- conjugate(n)[source]#
Complex conjugate of self.
EXAMPLES:
sage: a = QQbar(sqrt(-7)) # needs sage.symbolic sage: b = a._descr # needs sage.symbolic sage: b.conjugate(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
>>> from sage.all import * >>> a = QQbar(sqrt(-Integer(7))) # needs sage.symbolic >>> b = a._descr # needs sage.symbolic >>> b.conjugate(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
- imag(n)[source]#
Imaginary part of self.
EXAMPLES:
sage: a = QQbar(sqrt(-7)) # needs sage.symbolic sage: b = a._descr # needs sage.symbolic sage: b.imag(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
>>> from sage.all import * >>> a = QQbar(sqrt(-Integer(7))) # needs sage.symbolic >>> b = a._descr # needs sage.symbolic >>> b.imag(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
- invert(n)[source]#
1/self.
EXAMPLES:
sage: a = QQbar(sqrt(2)) # needs sage.symbolic sage: b = a._descr # needs sage.symbolic sage: b.invert(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
>>> from sage.all import * >>> a = QQbar(sqrt(Integer(2))) # needs sage.symbolic >>> b = a._descr # needs sage.symbolic >>> b.invert(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
- is_simple()[source]#
Check whether this descriptor represents a value with the same algebraic degree as the number field associated with the descriptor.
This returns
True
if self is anANRational
, or a minimalANExtensionElement
.EXAMPLES:
sage: from sage.rings.qqbar import ANRational sage: ANRational(1/2).is_simple() True sage: # needs sage.symbolic sage: rt2 = AA(sqrt(2)) sage: rt3 = AA(sqrt(3)) sage: rt2b = rt3 + rt2 - rt3 sage: rt2.exactify() sage: rt2._descr.is_simple() True sage: rt2b.exactify() sage: rt2b._descr.is_simple() False sage: rt2b.simplify() sage: rt2b._descr.is_simple() True
>>> from sage.all import * >>> from sage.rings.qqbar import ANRational >>> ANRational(Integer(1)/Integer(2)).is_simple() True >>> # needs sage.symbolic >>> rt2 = AA(sqrt(Integer(2))) >>> rt3 = AA(sqrt(Integer(3))) >>> rt2b = rt3 + rt2 - rt3 >>> rt2.exactify() >>> rt2._descr.is_simple() True >>> rt2b.exactify() >>> rt2b._descr.is_simple() False >>> rt2b.simplify() >>> rt2b._descr.is_simple() True
- neg(n)[source]#
Negation of self.
EXAMPLES:
sage: a = QQbar(sqrt(2)) # needs sage.symbolic sage: b = a._descr # needs sage.symbolic sage: b.neg(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
>>> from sage.all import * >>> a = QQbar(sqrt(Integer(2))) # needs sage.symbolic >>> b = a._descr # needs sage.symbolic >>> b.neg(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
- norm(n)[source]#
Field norm of self from \(\overline{\QQ}\) to its real subfield \(\mathbf{A}\), i.e.~the square of the usual complex absolute value.
EXAMPLES:
sage: a = QQbar(sqrt(-7)) # needs sage.symbolic sage: b = a._descr # needs sage.symbolic sage: b.norm(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
>>> from sage.all import * >>> a = QQbar(sqrt(-Integer(7))) # needs sage.symbolic >>> b = a._descr # needs sage.symbolic >>> b.norm(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
- real(n)[source]#
Real part of self.
EXAMPLES:
sage: a = QQbar(sqrt(-7)) # needs sage.symbolic sage: b = a._descr # needs sage.symbolic sage: b.real(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
>>> from sage.all import * >>> a = QQbar(sqrt(-Integer(7))) # needs sage.symbolic >>> b = a._descr # needs sage.symbolic >>> b.real(a) # needs sage.symbolic <sage.rings.qqbar.ANUnaryExpr object at ...>
- class sage.rings.qqbar.ANExtensionElement(generator, value)[source]#
Bases:
ANDescr
The subclass of
ANDescr
that represents a number field element in terms of a specific generator. Consists of a polynomial with rational coefficients in terms of the generator, and the generator itself, anAlgebraicGenerator
.- abs(n)[source]#
Return the absolute value of
self
(square root of the norm).EXAMPLES:
sage: # needs sage.symbolic sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) sage: a.exactify() sage: b = a._descr sage: type(b) <class 'sage.rings.qqbar.ANExtensionElement'> sage: b.abs(a) Root 3.146264369941972342? of x^2 - 9.89897948556636?
>>> from sage.all import * >>> # needs sage.symbolic >>> a = QQbar(sqrt(-Integer(2))) + QQbar(sqrt(-Integer(3))) >>> a.exactify() >>> b = a._descr >>> type(b) <class 'sage.rings.qqbar.ANExtensionElement'> >>> b.abs(a) Root 3.146264369941972342? of x^2 - 9.89897948556636?
- conjugate(n)[source]#
Complex conjugate of
self
.EXAMPLES:
sage: # needs sage.symbolic sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) sage: a.exactify() sage: b = a._descr sage: type(b) <class 'sage.rings.qqbar.ANExtensionElement'> sage: c = b.conjugate(None); c # random (not uniquely represented) 1/3*a^3 - 1/3*a^2 + a + 1 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? - 1.573132184970987?*I
>>> from sage.all import * >>> # needs sage.symbolic >>> a = QQbar(sqrt(-Integer(2))) + QQbar(sqrt(-Integer(3))) >>> a.exactify() >>> b = a._descr >>> type(b) <class 'sage.rings.qqbar.ANExtensionElement'> >>> c = b.conjugate(None); c # random (not uniquely represented) 1/3*a^3 - 1/3*a^2 + a + 1 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? - 1.573132184970987?*I
Internally, complex conjugation is implemented by taking the same abstract field element but conjugating the complex embedding of the field:
sage: c.generator() == b.generator().conjugate() # needs sage.symbolic True sage: c.field_element_value() == b.field_element_value() # needs sage.symbolic True
>>> from sage.all import * >>> c.generator() == b.generator().conjugate() # needs sage.symbolic True >>> c.field_element_value() == b.field_element_value() # needs sage.symbolic True
The parameter is ignored:
sage: (b.conjugate("random").generator() == c.generator() # needs sage.symbolic ....: and b.conjugate("random").field_element_value() == c.field_element_value()) True
>>> from sage.all import * >>> (b.conjugate("random").generator() == c.generator() # needs sage.symbolic ... and b.conjugate("random").field_element_value() == c.field_element_value()) True
- exactify()[source]#
Return an exact representation of
self
.Since
self
is already exact, just returnself
.EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: v = (x^2 - x - 1).roots(ring=AA, multiplicities=False)[1]._descr.exactify() sage: type(v) <class 'sage.rings.qqbar.ANExtensionElement'> sage: v.exactify() is v True
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> v = (x**Integer(2) - x - Integer(1)).roots(ring=AA, multiplicities=False)[Integer(1)]._descr.exactify() >>> type(v) <class 'sage.rings.qqbar.ANExtensionElement'> >>> v.exactify() is v True
- field_element_value()[source]#
Return the underlying number field element.
EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: v = (x^2 - x - 1).roots(ring=AA, multiplicities=False)[1]._descr.exactify() sage: v.field_element_value() a
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> v = (x**Integer(2) - x - Integer(1)).roots(ring=AA, multiplicities=False)[Integer(1)]._descr.exactify() >>> v.field_element_value() a
- generator()[source]#
Return the
AlgebraicGenerator
object corresponding toself
.EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: v = (x^2 - x - 1).roots(ring=AA, multiplicities=False)[1]._descr.exactify() sage: v.generator() Number Field in a with defining polynomial y^2 - y - 1 with a in 1.618033988749895?
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> v = (x**Integer(2) - x - Integer(1)).roots(ring=AA, multiplicities=False)[Integer(1)]._descr.exactify() >>> v.generator() Number Field in a with defining polynomial y^2 - y - 1 with a in 1.618033988749895?
- handle_sage_input(sib, coerce, is_qqbar)[source]#
Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always
True
forANExtensionElement
).EXAMPLES:
sage: I = QQbar(I) sage: sage_input(3+4*I, verify=True) # Verified QQbar(3 + 4*I) sage: v = QQbar.zeta(3) + QQbar.zeta(5) sage: v - v == 0 True sage: sage_input(vector(QQbar, (4-3*I, QQbar.zeta(7))), verify=True) # Verified R.<y> = QQ[] vector(QQbar, [4 - 3*I, QQbar.polynomial_root(AA.common_polynomial(y^6 + y^5 + y^4 + y^3 + y^2 + y + 1), CIF(RIF(RR(0.62348980185873348), RR(0.62348980185873359)), RIF(RR(0.7818314824680298), RR(0.78183148246802991))))]) sage: sage_input(v, verify=True) # Verified R.<y> = QQ[] v = QQbar.polynomial_root(AA.common_polynomial(y^8 - y^7 + y^5 - y^4 + y^3 - y + 1), CIF(RIF(RR(0.91354545764260087), RR(0.91354545764260098)), RIF(RR(0.40673664307580015), RR(0.40673664307580021)))) v^5 + v^3 sage: v = QQbar(sqrt(AA(2))) sage: v.exactify() sage: sage_input(v, verify=True) # Verified R.<y> = QQ[] QQbar(AA.polynomial_root(AA.common_polynomial(y^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951)))) sage: from sage.rings.qqbar import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() sage: extel = ANExtensionElement(QQbar_I_generator, QQbar_I_generator.field().gen() + 1) sage: extel.handle_sage_input(sib, False, True) ({call: {atomic:QQbar}({binop:+ {atomic:1} {atomic:I}})}, True)
>>> from sage.all import * >>> I = QQbar(I) >>> sage_input(Integer(3)+Integer(4)*I, verify=True) # Verified QQbar(3 + 4*I) >>> v = QQbar.zeta(Integer(3)) + QQbar.zeta(Integer(5)) >>> v - v == Integer(0) True >>> sage_input(vector(QQbar, (Integer(4)-Integer(3)*I, QQbar.zeta(Integer(7)))), verify=True) # Verified R.<y> = QQ[] vector(QQbar, [4 - 3*I, QQbar.polynomial_root(AA.common_polynomial(y^6 + y^5 + y^4 + y^3 + y^2 + y + 1), CIF(RIF(RR(0.62348980185873348), RR(0.62348980185873359)), RIF(RR(0.7818314824680298), RR(0.78183148246802991))))]) >>> sage_input(v, verify=True) # Verified R.<y> = QQ[] v = QQbar.polynomial_root(AA.common_polynomial(y^8 - y^7 + y^5 - y^4 + y^3 - y + 1), CIF(RIF(RR(0.91354545764260087), RR(0.91354545764260098)), RIF(RR(0.40673664307580015), RR(0.40673664307580021)))) v^5 + v^3 >>> v = QQbar(sqrt(AA(Integer(2)))) >>> v.exactify() >>> sage_input(v, verify=True) # Verified R.<y> = QQ[] QQbar(AA.polynomial_root(AA.common_polynomial(y^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951)))) >>> from sage.rings.qqbar import * >>> from sage.misc.sage_input import SageInputBuilder >>> sib = SageInputBuilder() >>> extel = ANExtensionElement(QQbar_I_generator, QQbar_I_generator.field().gen() + Integer(1)) >>> extel.handle_sage_input(sib, False, True) ({call: {atomic:QQbar}({binop:+ {atomic:1} {atomic:I}})}, True)
- invert(n)[source]#
Reciprocal of
self
.EXAMPLES:
sage: # needs sage.symbolic sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) sage: a.exactify() sage: b = a._descr sage: type(b) <class 'sage.rings.qqbar.ANExtensionElement'> sage: c = b.invert(None); c # random (not uniquely represented) -7/3*a^3 + 19/3*a^2 - 7*a - 9 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? + 1.573132184970987?*I sage: (c.generator() == b.generator() ....: and c.field_element_value() * b.field_element_value() == 1) True
>>> from sage.all import * >>> # needs sage.symbolic >>> a = QQbar(sqrt(-Integer(2))) + QQbar(sqrt(-Integer(3))) >>> a.exactify() >>> b = a._descr >>> type(b) <class 'sage.rings.qqbar.ANExtensionElement'> >>> c = b.invert(None); c # random (not uniquely represented) -7/3*a^3 + 19/3*a^2 - 7*a - 9 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? + 1.573132184970987?*I >>> (c.generator() == b.generator() ... and c.field_element_value() * b.field_element_value() == Integer(1)) True
The parameter is ignored:
sage: (b.invert("random").generator() == c.generator() # needs sage.symbolic ....: and b.invert("random").field_element_value() == c.field_element_value()) True
>>> from sage.all import * >>> (b.invert("random").generator() == c.generator() # needs sage.symbolic ... and b.invert("random").field_element_value() == c.field_element_value()) True
- is_complex()[source]#
Return
True
if the number field that defines this element is not real.This does not imply that the element itself is definitely non-real, as in the example below.
EXAMPLES:
sage: # needs sage.symbolic sage: rt2 = QQbar(sqrt(2)) sage: rtm3 = QQbar(sqrt(-3)) sage: x = rtm3 + rt2 - rtm3 sage: x.exactify() sage: y = x._descr sage: type(y) <class 'sage.rings.qqbar.ANExtensionElement'> sage: y.is_complex() True sage: x.imag() == 0 True
>>> from sage.all import * >>> # needs sage.symbolic >>> rt2 = QQbar(sqrt(Integer(2))) >>> rtm3 = QQbar(sqrt(-Integer(3))) >>> x = rtm3 + rt2 - rtm3 >>> x.exactify() >>> y = x._descr >>> type(y) <class 'sage.rings.qqbar.ANExtensionElement'> >>> y.is_complex() True >>> x.imag() == Integer(0) True
- is_simple()[source]#
Check whether this descriptor represents a value with the same algebraic degree as the number field associated with the descriptor.
For
ANExtensionElement
elements, we check this by comparing the degree of the minimal polynomial to the degree of the field.EXAMPLES:
sage: # needs sage.symbolic sage: rt2 = AA(sqrt(2)) sage: rt3 = AA(sqrt(3)) sage: rt2b = rt3 + rt2 - rt3 sage: rt2.exactify() sage: rt2._descr a where a^2 - 2 = 0 and a in 1.414213562373095? sage: rt2._descr.is_simple() True sage: rt2b.exactify() # needs sage.symbolic sage: rt2b._descr # needs sage.symbolic a^3 - 3*a where a^4 - 4*a^2 + 1 = 0 and a in -0.5176380902050415? sage: rt2b._descr.is_simple() # needs sage.symbolic False
>>> from sage.all import * >>> # needs sage.symbolic >>> rt2 = AA(sqrt(Integer(2))) >>> rt3 = AA(sqrt(Integer(3))) >>> rt2b = rt3 + rt2 - rt3 >>> rt2.exactify() >>> rt2._descr a where a^2 - 2 = 0 and a in 1.414213562373095? >>> rt2._descr.is_simple() True >>> rt2b.exactify() # needs sage.symbolic >>> rt2b._descr # needs sage.symbolic a^3 - 3*a where a^4 - 4*a^2 + 1 = 0 and a in -0.5176380902050415? >>> rt2b._descr.is_simple() # needs sage.symbolic False
- minpoly()[source]#
Compute the minimal polynomial of this algebraic number.
EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: v = (x^2 - x - 1).roots(ring=AA, multiplicities=False)[1]._descr.exactify() sage: type(v) <class 'sage.rings.qqbar.ANExtensionElement'> sage: v.minpoly() x^2 - x - 1
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> v = (x**Integer(2) - x - Integer(1)).roots(ring=AA, multiplicities=False)[Integer(1)]._descr.exactify() >>> type(v) <class 'sage.rings.qqbar.ANExtensionElement'> >>> v.minpoly() x^2 - x - 1
- neg(n)[source]#
Negation of
self
.EXAMPLES:
sage: # needs sage.symbolic sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) sage: a.exactify() sage: b = a._descr sage: type(b) <class 'sage.rings.qqbar.ANExtensionElement'> sage: c = b.neg(None); c # random (not uniquely represented) -1/3*a^3 + 1/3*a^2 - a - 1 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? + 1.573132184970987?*I sage: (c.generator() == b.generator() ....: and c.field_element_value() + b.field_element_value() == 0) True
>>> from sage.all import * >>> # needs sage.symbolic >>> a = QQbar(sqrt(-Integer(2))) + QQbar(sqrt(-Integer(3))) >>> a.exactify() >>> b = a._descr >>> type(b) <class 'sage.rings.qqbar.ANExtensionElement'> >>> c = b.neg(None); c # random (not uniquely represented) -1/3*a^3 + 1/3*a^2 - a - 1 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? + 1.573132184970987?*I >>> (c.generator() == b.generator() ... and c.field_element_value() + b.field_element_value() == Integer(0)) True
The parameter is ignored:
sage: (b.neg("random").generator() == c.generator() # needs sage.symbolic ....: and b.neg("random").field_element_value() == c.field_element_value()) True
>>> from sage.all import * >>> (b.neg("random").generator() == c.generator() # needs sage.symbolic ... and b.neg("random").field_element_value() == c.field_element_value()) True
- norm(n)[source]#
Norm of
self
(square of complex absolute value)EXAMPLES:
sage: # needs sage.symbolic sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) sage: a.exactify() sage: b = a._descr sage: type(b) <class 'sage.rings.qqbar.ANExtensionElement'> sage: b.norm(a) <sage.rings.qqbar.ANUnaryExpr object at ...>
>>> from sage.all import * >>> # needs sage.symbolic >>> a = QQbar(sqrt(-Integer(2))) + QQbar(sqrt(-Integer(3))) >>> a.exactify() >>> b = a._descr >>> type(b) <class 'sage.rings.qqbar.ANExtensionElement'> >>> b.norm(a) <sage.rings.qqbar.ANUnaryExpr object at ...>
- rational_argument(n)[source]#
If the argument of
self
is \(2\pi\) times some rational number in \([1/2, -1/2)\), return that rational; otherwise, returnNone
.EXAMPLES:
sage: # needs sage.symbolic sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(3)) sage: a.exactify() sage: b = a._descr sage: type(b) <class 'sage.rings.qqbar.ANExtensionElement'> sage: b.rational_argument(a) is None True sage: x = polygen(QQ) sage: a = (x^4 + 1).roots(QQbar, multiplicities=False)[0] sage: a.exactify() sage: b = a._descr sage: b.rational_argument(a) -3/8
>>> from sage.all import * >>> # needs sage.symbolic >>> a = QQbar(sqrt(-Integer(2))) + QQbar(sqrt(Integer(3))) >>> a.exactify() >>> b = a._descr >>> type(b) <class 'sage.rings.qqbar.ANExtensionElement'> >>> b.rational_argument(a) is None True >>> x = polygen(QQ) >>> a = (x**Integer(4) + Integer(1)).roots(QQbar, multiplicities=False)[Integer(0)] >>> a.exactify() >>> b = a._descr >>> b.rational_argument(a) -3/8
- simplify(n)[source]#
Compute an exact representation for this descriptor, in the smallest possible number field.
INPUT:
n
– The element ofAA
orQQbar
corresponding to this descriptor.
EXAMPLES:
sage: # needs sage.symbolic sage: rt2 = AA(sqrt(2)) sage: rt3 = AA(sqrt(3)) sage: rt2b = rt3 + rt2 - rt3 sage: rt2b.exactify() sage: rt2b._descr a^3 - 3*a where a^4 - 4*a^2 + 1 = 0 and a in -0.5176380902050415? sage: rt2b._descr.simplify(rt2b) a where a^2 - 2 = 0 and a in 1.414213562373095?
>>> from sage.all import * >>> # needs sage.symbolic >>> rt2 = AA(sqrt(Integer(2))) >>> rt3 = AA(sqrt(Integer(3))) >>> rt2b = rt3 + rt2 - rt3 >>> rt2b.exactify() >>> rt2b._descr a^3 - 3*a where a^4 - 4*a^2 + 1 = 0 and a in -0.5176380902050415? >>> rt2b._descr.simplify(rt2b) a where a^2 - 2 = 0 and a in 1.414213562373095?
- class sage.rings.qqbar.ANRational(x)[source]#
Bases:
ANDescr
The subclass of
ANDescr
that represents an arbitrary rational. This class is private, and should not be used directly.- abs(n)[source]#
Absolute value of
self
.EXAMPLES:
sage: a = QQbar(3) sage: b = a._descr sage: b.abs(a) 3
>>> from sage.all import * >>> a = QQbar(Integer(3)) >>> b = a._descr >>> b.abs(a) 3
- angle()[source]#
Return a rational number \(q \in (-1/2, 1/2]\) such that
self
is a rational multiple of \(e^{2\pi i q}\). Always returns 0, since this element is rational.EXAMPLES:
sage: QQbar(3)._descr.angle() 0 sage: QQbar(-3)._descr.angle() 0 sage: QQbar(0)._descr.angle() 0
>>> from sage.all import * >>> QQbar(Integer(3))._descr.angle() 0 >>> QQbar(-Integer(3))._descr.angle() 0 >>> QQbar(Integer(0))._descr.angle() 0
- exactify()[source]#
Calculate
self
exactly. Sinceself
is a rational number, returnself
.EXAMPLES:
sage: a = QQbar(1/3)._descr sage: a.exactify() is a True
>>> from sage.all import * >>> a = QQbar(Integer(1)/Integer(3))._descr >>> a.exactify() is a True
- generator()[source]#
Return an
AlgebraicGenerator
object associated to this element. Returns the trivial generator, sinceself
is rational.EXAMPLES:
sage: QQbar(0)._descr.generator() Trivial generator
>>> from sage.all import * >>> QQbar(Integer(0))._descr.generator() Trivial generator
- handle_sage_input(sib, coerce, is_qqbar)[source]#
Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always False, for rationals).
EXAMPLES:
sage: sage_input(QQbar(22/7), verify=True) # Verified QQbar(22/7) sage: sage_input(-AA(3)/5, verify=True) # Verified AA(-3/5) sage: sage_input(vector(AA, (0, 1/2, 1/3)), verify=True) # Verified vector(AA, [0, 1/2, 1/3]) sage: from sage.rings.qqbar import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() sage: rat = ANRational(9/10) sage: rat.handle_sage_input(sib, False, True) ({call: {atomic:QQbar}({binop:/ {atomic:9} {atomic:10}})}, False)
>>> from sage.all import * >>> sage_input(QQbar(Integer(22)/Integer(7)), verify=True) # Verified QQbar(22/7) >>> sage_input(-AA(Integer(3))/Integer(5), verify=True) # Verified AA(-3/5) >>> sage_input(vector(AA, (Integer(0), Integer(1)/Integer(2), Integer(1)/Integer(3))), verify=True) # Verified vector(AA, [0, 1/2, 1/3]) >>> from sage.rings.qqbar import * >>> from sage.misc.sage_input import SageInputBuilder >>> sib = SageInputBuilder() >>> rat = ANRational(Integer(9)/Integer(10)) >>> rat.handle_sage_input(sib, False, True) ({call: {atomic:QQbar}({binop:/ {atomic:9} {atomic:10}})}, False)
- invert(n)[source]#
1/
self
.EXAMPLES:
sage: a = QQbar(3) sage: b = a._descr sage: b.invert(a) 1/3
>>> from sage.all import * >>> a = QQbar(Integer(3)) >>> b = a._descr >>> b.invert(a) 1/3
- is_complex()[source]#
Return
False
, since rational numbers are realEXAMPLES:
sage: QQbar(1/7)._descr.is_complex() False
>>> from sage.all import * >>> QQbar(Integer(1)/Integer(7))._descr.is_complex() False
- is_simple()[source]#
Checks whether this descriptor represents a value with the same algebraic degree as the number field associated with the descriptor.
This is always true for rational numbers.
EXAMPLES:
sage: AA(1/2)._descr.is_simple() True
>>> from sage.all import * >>> AA(Integer(1)/Integer(2))._descr.is_simple() True
- minpoly()[source]#
Return the min poly of
self
over \(\QQ\).EXAMPLES:
sage: QQbar(7)._descr.minpoly() x - 7
>>> from sage.all import * >>> QQbar(Integer(7))._descr.minpoly() x - 7
- neg(n)[source]#
Negation of
self
.EXAMPLES:
sage: a = QQbar(3) sage: b = a._descr sage: type(b) <class 'sage.rings.qqbar.ANRational'> sage: b.neg(a) -3
>>> from sage.all import * >>> a = QQbar(Integer(3)) >>> b = a._descr >>> type(b) <class 'sage.rings.qqbar.ANRational'> >>> b.neg(a) -3
- rational_argument(n)[source]#
Return the argument of self divided by \(2 \pi\), or
None
if this element is 0.EXAMPLES:
sage: QQbar(3)._descr.rational_argument(None) 0 sage: QQbar(-3)._descr.rational_argument(None) 1/2 sage: QQbar(0)._descr.rational_argument(None) is None True
>>> from sage.all import * >>> QQbar(Integer(3))._descr.rational_argument(None) 0 >>> QQbar(-Integer(3))._descr.rational_argument(None) 1/2 >>> QQbar(Integer(0))._descr.rational_argument(None) is None True
- class sage.rings.qqbar.ANRoot(poly, interval, multiplicity=1)[source]#
Bases:
ANDescr
The subclass of
ANDescr
that represents a particular root of a polynomial with algebraic coefficients. This class is private, and should not be used directly.- conjugate(n)[source]#
Complex conjugate of this
ANRoot
object.EXAMPLES:
sage: # needs sage.symbolic sage: a = (x^2 + 23).roots(ring=QQbar, multiplicities=False)[0] sage: b = a._descr sage: type(b) <class 'sage.rings.qqbar.ANRoot'> sage: c = b.conjugate(a); c <sage.rings.qqbar.ANUnaryExpr object at ...> sage: c.exactify() -2*a + 1 where a^2 - a + 6 = 0 and a in 0.50000000000000000? - 2.397915761656360?*I
>>> from sage.all import * >>> # needs sage.symbolic >>> a = (x**Integer(2) + Integer(23)).roots(ring=QQbar, multiplicities=False)[Integer(0)] >>> b = a._descr >>> type(b) <class 'sage.rings.qqbar.ANRoot'> >>> c = b.conjugate(a); c <sage.rings.qqbar.ANUnaryExpr object at ...> >>> c.exactify() -2*a + 1 where a^2 - a + 6 = 0 and a in 0.50000000000000000? - 2.397915761656360?*I
- exactify()[source]#
Return either an
ANRational
or anANExtensionElement
with the same value as this number.EXAMPLES:
sage: from sage.rings.qqbar import ANRoot sage: x = polygen(QQbar) sage: two = ANRoot((x-2)*(x-sqrt(QQbar(2))), RIF(1.9, 2.1)) sage: two.exactify() 2 sage: strange = ANRoot(x^2 + sqrt(QQbar(3))*x - sqrt(QQbar(2)), RIF(-0, 1)) sage: strange.exactify() a where a^8 - 6*a^6 + 5*a^4 - 12*a^2 + 4 = 0 and a in 0.6051012265139511?
>>> from sage.all import * >>> from sage.rings.qqbar import ANRoot >>> x = polygen(QQbar) >>> two = ANRoot((x-Integer(2))*(x-sqrt(QQbar(Integer(2)))), RIF(RealNumber('1.9'), RealNumber('2.1'))) >>> two.exactify() 2 >>> strange = ANRoot(x**Integer(2) + sqrt(QQbar(Integer(3)))*x - sqrt(QQbar(Integer(2))), RIF(-Integer(0), Integer(1))) >>> strange.exactify() a where a^8 - 6*a^6 + 5*a^4 - 12*a^2 + 4 = 0 and a in 0.6051012265139511?
- handle_sage_input(sib, coerce, is_qqbar)[source]#
Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always
True
forANRoot
).EXAMPLES:
sage: sage_input((AA(3)^(1/2))^(1/3), verify=True) # Verified R.<x> = AA[] AA.polynomial_root(AA.common_polynomial(x^3 - AA.polynomial_root(AA.common_polynomial(x^2 - 3), RIF(RR(1.7320508075688772), RR(1.7320508075688774)))), RIF(RR(1.2009369551760025), RR(1.2009369551760027)))
>>> from sage.all import * >>> sage_input((AA(Integer(3))**(Integer(1)/Integer(2)))**(Integer(1)/Integer(3)), verify=True) # Verified R.<x> = AA[] AA.polynomial_root(AA.common_polynomial(x^3 - AA.polynomial_root(AA.common_polynomial(x^2 - 3), RIF(RR(1.7320508075688772), RR(1.7320508075688774)))), RIF(RR(1.2009369551760025), RR(1.2009369551760027)))
These two examples are too big to verify quickly. (Verification would create a field of degree 28.):
sage: sage_input((sqrt(AA(3))^(5/7))^(9/4)) R.<x> = AA[] v1 = AA.polynomial_root(AA.common_polynomial(x^2 - 3), RIF(RR(1.7320508075688772), RR(1.7320508075688774))) v2 = v1*v1 v3 = AA.polynomial_root(AA.common_polynomial(x^7 - v2*v2*v1), RIF(RR(1.4804728524798112), RR(1.4804728524798114))) v4 = v3*v3 v5 = v4*v4 AA.polynomial_root(AA.common_polynomial(x^4 - v5*v5*v3), RIF(RR(2.4176921938267877), RR(2.4176921938267881))) sage: sage_input((sqrt(QQbar(-7))^(5/7))^(9/4)) R.<x> = QQbar[] v1 = QQbar.polynomial_root(AA.common_polynomial(x^2 + 7), CIF(RIF(RR(0)), RIF(RR(2.6457513110645903), RR(2.6457513110645907)))) v2 = v1*v1 v3 = QQbar.polynomial_root(AA.common_polynomial(x^7 - v2*v2*v1), CIF(RIF(RR(0.8693488875796217), RR(0.86934888757962181)), RIF(RR(1.8052215661454434), RR(1.8052215661454436)))) v4 = v3*v3 v5 = v4*v4 QQbar.polynomial_root(AA.common_polynomial(x^4 - v5*v5*v3), CIF(RIF(-RR(3.8954086044650791), -RR(3.8954086044650786)), RIF(RR(2.7639398015408925), RR(2.7639398015408929)))) sage: x = polygen(QQ) sage: sage_input(AA.polynomial_root(x^2-x-1, RIF(1, 2)), verify=True) # Verified R.<y> = QQ[] AA.polynomial_root(AA.common_polynomial(y^2 - y - 1), RIF(RR(1.6180339887498947), RR(1.6180339887498949))) sage: sage_input(QQbar.polynomial_root(x^3-5, CIF(RIF(-3, 0), RIF(0, 3))), verify=True) # Verified R.<y> = QQ[] QQbar.polynomial_root(AA.common_polynomial(y^3 - 5), CIF(RIF(-RR(0.85498797333834853), -RR(0.85498797333834842)), RIF(RR(1.4808826096823642), RR(1.4808826096823644)))) sage: from sage.rings.qqbar import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() sage: rt = ANRoot(x^3 - 2, RIF(0, 4)) sage: rt.handle_sage_input(sib, False, True) ({call: {getattr: {atomic:QQbar}.polynomial_root}({call: {getattr: {atomic:AA}.common_polynomial}({binop:- {binop:** {gen:y {constr_parent: {subscr: {atomic:QQ}[{atomic:'y'}]} with gens: ('y',)}} {atomic:3}} {atomic:2}})}, {call: {atomic:RIF}({call: {atomic:RR}({atomic:1.259921049894873})}, {call: {atomic:RR}({atomic:1.2599210498948732})})})}, True)
>>> from sage.all import * >>> sage_input((sqrt(AA(Integer(3)))**(Integer(5)/Integer(7)))**(Integer(9)/Integer(4))) R.<x> = AA[] v1 = AA.polynomial_root(AA.common_polynomial(x^2 - 3), RIF(RR(1.7320508075688772), RR(1.7320508075688774))) v2 = v1*v1 v3 = AA.polynomial_root(AA.common_polynomial(x^7 - v2*v2*v1), RIF(RR(1.4804728524798112), RR(1.4804728524798114))) v4 = v3*v3 v5 = v4*v4 AA.polynomial_root(AA.common_polynomial(x^4 - v5*v5*v3), RIF(RR(2.4176921938267877), RR(2.4176921938267881))) >>> sage_input((sqrt(QQbar(-Integer(7)))**(Integer(5)/Integer(7)))**(Integer(9)/Integer(4))) R.<x> = QQbar[] v1 = QQbar.polynomial_root(AA.common_polynomial(x^2 + 7), CIF(RIF(RR(0)), RIF(RR(2.6457513110645903), RR(2.6457513110645907)))) v2 = v1*v1 v3 = QQbar.polynomial_root(AA.common_polynomial(x^7 - v2*v2*v1), CIF(RIF(RR(0.8693488875796217), RR(0.86934888757962181)), RIF(RR(1.8052215661454434), RR(1.8052215661454436)))) v4 = v3*v3 v5 = v4*v4 QQbar.polynomial_root(AA.common_polynomial(x^4 - v5*v5*v3), CIF(RIF(-RR(3.8954086044650791), -RR(3.8954086044650786)), RIF(RR(2.7639398015408925), RR(2.7639398015408929)))) >>> x = polygen(QQ) >>> sage_input(AA.polynomial_root(x**Integer(2)-x-Integer(1), RIF(Integer(1), Integer(2))), verify=True) # Verified R.<y> = QQ[] AA.polynomial_root(AA.common_polynomial(y^2 - y - 1), RIF(RR(1.6180339887498947), RR(1.6180339887498949))) >>> sage_input(QQbar.polynomial_root(x**Integer(3)-Integer(5), CIF(RIF(-Integer(3), Integer(0)), RIF(Integer(0), Integer(3)))), verify=True) # Verified R.<y> = QQ[] QQbar.polynomial_root(AA.common_polynomial(y^3 - 5), CIF(RIF(-RR(0.85498797333834853), -RR(0.85498797333834842)), RIF(RR(1.4808826096823642), RR(1.4808826096823644)))) >>> from sage.rings.qqbar import * >>> from sage.misc.sage_input import SageInputBuilder >>> sib = SageInputBuilder() >>> rt = ANRoot(x**Integer(3) - Integer(2), RIF(Integer(0), Integer(4))) >>> rt.handle_sage_input(sib, False, True) ({call: {getattr: {atomic:QQbar}.polynomial_root}({call: {getattr: {atomic:AA}.common_polynomial}({binop:- {binop:** {gen:y {constr_parent: {subscr: {atomic:QQ}[{atomic:'y'}]} with gens: ('y',)}} {atomic:3}} {atomic:2}})}, {call: {atomic:RIF}({call: {atomic:RR}({atomic:1.259921049894873})}, {call: {atomic:RR}({atomic:1.2599210498948732})})})}, True)
- is_complex()[source]#
Whether this is a root in \(\overline{\QQ}\) (rather than \(\mathbf{A}\)). Note that this may return True even if the root is actually real, as the second example shows; it does not trigger exact computation to see if the root is real.
EXAMPLES:
sage: x = polygen(QQ) sage: (x^2 - x - 1).roots(ring=AA, multiplicities=False)[1]._descr.is_complex() False sage: (x^2 - x - 1).roots(ring=QQbar, multiplicities=False)[1]._descr.is_complex() True
>>> from sage.all import * >>> x = polygen(QQ) >>> (x**Integer(2) - x - Integer(1)).roots(ring=AA, multiplicities=False)[Integer(1)]._descr.is_complex() False >>> (x**Integer(2) - x - Integer(1)).roots(ring=QQbar, multiplicities=False)[Integer(1)]._descr.is_complex() True
- refine_interval(interval, prec)[source]#
Takes an interval which is assumed to enclose exactly one root of the polynomial (or, with multiplicity=`k`, exactly one root of the \(k-1\)-st derivative); and a precision, in bits.
Tries to find a narrow interval enclosing the root using interval arithmetic of the given precision. (No particular number of resulting bits of precision is guaranteed.)
Uses a combination of Newton’s method (adapted for interval arithmetic) and bisection. The algorithm will converge very quickly if started with a sufficiently narrow interval.
EXAMPLES:
sage: from sage.rings.qqbar import ANRoot sage: x = polygen(AA) sage: rt2 = ANRoot(x^2 - 2, RIF(0, 2)) sage: rt2.refine_interval(RIF(0, 2), 75) 1.4142135623730950488017?
>>> from sage.all import * >>> from sage.rings.qqbar import ANRoot >>> x = polygen(AA) >>> rt2 = ANRoot(x**Integer(2) - Integer(2), RIF(Integer(0), Integer(2))) >>> rt2.refine_interval(RIF(Integer(0), Integer(2)), Integer(75)) 1.4142135623730950488017?
- class sage.rings.qqbar.ANUnaryExpr(arg, op)[source]#
Bases:
ANDescr
Initialize this ANUnaryExpr.
EXAMPLES:
sage: t = ~QQbar(sqrt(2)); type(t._descr) # indirect doctest # needs sage.symbolic <class 'sage.rings.qqbar.ANUnaryExpr'>
>>> from sage.all import * >>> t = ~QQbar(sqrt(Integer(2))); type(t._descr) # indirect doctest # needs sage.symbolic <class 'sage.rings.qqbar.ANUnaryExpr'>
- exactify()[source]#
Trigger exact computation of
self
.EXAMPLES:
sage: v = (-QQbar(sqrt(2)))._descr # needs sage.symbolic sage: type(v) # needs sage.symbolic <class 'sage.rings.qqbar.ANUnaryExpr'> sage: v.exactify() # needs sage.symbolic -a where a^2 - 2 = 0 and a in 1.414213562373095?
>>> from sage.all import * >>> v = (-QQbar(sqrt(Integer(2))))._descr # needs sage.symbolic >>> type(v) # needs sage.symbolic <class 'sage.rings.qqbar.ANUnaryExpr'> >>> v.exactify() # needs sage.symbolic -a where a^2 - 2 = 0 and a in 1.414213562373095?
- handle_sage_input(sib, coerce, is_qqbar)[source]#
Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always
True
forANUnaryExpr
).EXAMPLES:
sage: sage_input(-sqrt(AA(2)), verify=True) # Verified R.<x> = AA[] -AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) sage: sage_input(~sqrt(AA(2)), verify=True) # Verified R.<x> = AA[] ~AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) sage: sage_input(sqrt(QQbar(-3)).conjugate(), verify=True) # Verified R.<x> = QQbar[] QQbar.polynomial_root(AA.common_polynomial(x^2 + 3), CIF(RIF(RR(0)), RIF(RR(1.7320508075688772), RR(1.7320508075688774)))).conjugate() sage: sage_input(QQbar.zeta(3).real(), verify=True) # Verified R.<y> = QQ[] QQbar.polynomial_root(AA.common_polynomial(y^2 + y + 1), CIF(RIF(-RR(0.50000000000000011), -RR(0.49999999999999994)), RIF(RR(0.8660254037844386), RR(0.86602540378443871)))).real() sage: sage_input(QQbar.zeta(3).imag(), verify=True) # Verified R.<y> = QQ[] QQbar.polynomial_root(AA.common_polynomial(y^2 + y + 1), CIF(RIF(-RR(0.50000000000000011), -RR(0.49999999999999994)), RIF(RR(0.8660254037844386), RR(0.86602540378443871)))).imag() sage: sage_input(abs(sqrt(QQbar(-3))), verify=True) # Verified R.<x> = QQbar[] abs(QQbar.polynomial_root(AA.common_polynomial(x^2 + 3), CIF(RIF(RR(0)), RIF(RR(1.7320508075688772), RR(1.7320508075688774))))) sage: sage_input(sqrt(QQbar(-3)).norm(), verify=True) # Verified R.<x> = QQbar[] QQbar.polynomial_root(AA.common_polynomial(x^2 + 3), CIF(RIF(RR(0)), RIF(RR(1.7320508075688772), RR(1.7320508075688774)))).norm() sage: sage_input(QQbar(QQbar.zeta(3).real()), verify=True) # Verified R.<y> = QQ[] QQbar(QQbar.polynomial_root(AA.common_polynomial(y^2 + y + 1), CIF(RIF(-RR(0.50000000000000011), -RR(0.49999999999999994)), RIF(RR(0.8660254037844386), RR(0.86602540378443871)))).real()) sage: from sage.rings.qqbar import * sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() sage: unexp = ANUnaryExpr(sqrt(AA(2)), '~') sage: unexp.handle_sage_input(sib, False, False) ({unop:~ {call: {getattr: {atomic:AA}.polynomial_root}({call: {getattr: {atomic:AA}.common_polynomial}({binop:- {binop:** {gen:x {constr_parent: {subscr: {atomic:AA}[{atomic:'x'}]} with gens: ('x',)}} {atomic:2}} {atomic:2}})}, {call: {atomic:RIF}({call: {atomic:RR}({atomic:1.4142135623730949})}, {call: {atomic:RR}({atomic:1.4142135623730951})})})}}, True) sage: unexp.handle_sage_input(sib, False, True) ({call: {atomic:QQbar}({unop:~ {call: {getattr: {atomic:AA}.polynomial_root}({call: {getattr: {atomic:AA}.common_polynomial}({binop:- {binop:** {gen:x {constr_parent: {subscr: {atomic:AA}[{atomic:'x'}]} with gens: ('x',)}} {atomic:2}} {atomic:2}})}, {call: {atomic:RIF}({call: {atomic:RR}({atomic:1.4142135623730949})}, {call: {atomic:RR}({atomic:1.4142135623730951})})})}})}, True)
>>> from sage.all import * >>> sage_input(-sqrt(AA(Integer(2))), verify=True) # Verified R.<x> = AA[] -AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) >>> sage_input(~sqrt(AA(Integer(2))), verify=True) # Verified R.<x> = AA[] ~AA.polynomial_root(AA.common_polynomial(x^2 - 2), RIF(RR(1.4142135623730949), RR(1.4142135623730951))) >>> sage_input(sqrt(QQbar(-Integer(3))).conjugate(), verify=True) # Verified R.<x> = QQbar[] QQbar.polynomial_root(AA.common_polynomial(x^2 + 3), CIF(RIF(RR(0)), RIF(RR(1.7320508075688772), RR(1.7320508075688774)))).conjugate() >>> sage_input(QQbar.zeta(Integer(3)).real(), verify=True) # Verified R.<y> = QQ[] QQbar.polynomial_root(AA.common_polynomial(y^2 + y + 1), CIF(RIF(-RR(0.50000000000000011), -RR(0.49999999999999994)), RIF(RR(0.8660254037844386), RR(0.86602540378443871)))).real() >>> sage_input(QQbar.zeta(Integer(3)).imag(), verify=True) # Verified R.<y> = QQ[] QQbar.polynomial_root(AA.common_polynomial(y^2 + y + 1), CIF(RIF(-RR(0.50000000000000011), -RR(0.49999999999999994)), RIF(RR(0.8660254037844386), RR(0.86602540378443871)))).imag() >>> sage_input(abs(sqrt(QQbar(-Integer(3)))), verify=True) # Verified R.<x> = QQbar[] abs(QQbar.polynomial_root(AA.common_polynomial(x^2 + 3), CIF(RIF(RR(0)), RIF(RR(1.7320508075688772), RR(1.7320508075688774))))) >>> sage_input(sqrt(QQbar(-Integer(3))).norm(), verify=True) # Verified R.<x> = QQbar[] QQbar.polynomial_root(AA.common_polynomial(x^2 + 3), CIF(RIF(RR(0)), RIF(RR(1.7320508075688772), RR(1.7320508075688774)))).norm() >>> sage_input(QQbar(QQbar.zeta(Integer(3)).real()), verify=True) # Verified R.<y> = QQ[] QQbar(QQbar.polynomial_root(AA.common_polynomial(y^2 + y + 1), CIF(RIF(-RR(0.50000000000000011), -RR(0.49999999999999994)), RIF(RR(0.8660254037844386), RR(0.86602540378443871)))).real()) >>> from sage.rings.qqbar import * >>> from sage.misc.sage_input import SageInputBuilder >>> sib = SageInputBuilder() >>> unexp = ANUnaryExpr(sqrt(AA(Integer(2))), '~') >>> unexp.handle_sage_input(sib, False, False) ({unop:~ {call: {getattr: {atomic:AA}.polynomial_root}({call: {getattr: {atomic:AA}.common_polynomial}({binop:- {binop:** {gen:x {constr_parent: {subscr: {atomic:AA}[{atomic:'x'}]} with gens: ('x',)}} {atomic:2}} {atomic:2}})}, {call: {atomic:RIF}({call: {atomic:RR}({atomic:1.4142135623730949})}, {call: {atomic:RR}({atomic:1.4142135623730951})})})}}, True) >>> unexp.handle_sage_input(sib, False, True) ({call: {atomic:QQbar}({unop:~ {call: {getattr: {atomic:AA}.polynomial_root}({call: {getattr: {atomic:AA}.common_polynomial}({binop:- {binop:** {gen:x {constr_parent: {subscr: {atomic:AA}[{atomic:'x'}]} with gens: ('x',)}} {atomic:2}} {atomic:2}})}, {call: {atomic:RIF}({call: {atomic:RR}({atomic:1.4142135623730949})}, {call: {atomic:RR}({atomic:1.4142135623730951})})})}})}, True)
- is_complex()[source]#
Return whether or not this element is complex. Note that this is a data type check, and triggers no computations – if it returns
False
, the element might still be real, it just doesn’t know it yet.EXAMPLES:
sage: # needs sage.symbolic sage: t = AA(sqrt(2)) sage: s = (-t)._descr sage: s <sage.rings.qqbar.ANUnaryExpr object at ...> sage: s.is_complex() False sage: QQbar(-sqrt(2))._descr.is_complex() True
>>> from sage.all import * >>> # needs sage.symbolic >>> t = AA(sqrt(Integer(2))) >>> s = (-t)._descr >>> s <sage.rings.qqbar.ANUnaryExpr object at ...> >>> s.is_complex() False >>> QQbar(-sqrt(Integer(2)))._descr.is_complex() True
- class sage.rings.qqbar.AlgebraicField[source]#
Bases:
Singleton
,AlgebraicField_common
,AlgebraicField
The field of all algebraic complex numbers.
- algebraic_closure()[source]#
Return the algebraic closure of this field.
As this field is already algebraically closed, just returns
self
.EXAMPLES:
sage: QQbar.algebraic_closure() Algebraic Field
>>> from sage.all import * >>> QQbar.algebraic_closure() Algebraic Field
- completion(p, prec, extras={})[source]#
Return the completion of
self
at the place \(p\).Only implemented for \(p = \infty\) at present.
INPUT:
p
– either a prime (not implemented at present) orInfinity
prec
– precision of approximate field to returnextras
– (optional) a dict of extra keyword arguments for theRealField
constructor
EXAMPLES:
sage: QQbar.completion(infinity, 500) Complex Field with 500 bits of precision sage: QQbar.completion(infinity, prec=53, extras={'type':'RDF'}) Complex Double Field sage: QQbar.completion(infinity, 53) is CC True sage: QQbar.completion(3, 20) Traceback (most recent call last): ... NotImplementedError
>>> from sage.all import * >>> QQbar.completion(infinity, Integer(500)) Complex Field with 500 bits of precision >>> QQbar.completion(infinity, prec=Integer(53), extras={'type':'RDF'}) Complex Double Field >>> QQbar.completion(infinity, Integer(53)) is CC True >>> QQbar.completion(Integer(3), Integer(20)) Traceback (most recent call last): ... NotImplementedError
- construction()[source]#
Return a functor that constructs
self
(used by the coercion machinery).EXAMPLES:
sage: QQbar.construction() (AlgebraicClosureFunctor, Rational Field)
>>> from sage.all import * >>> QQbar.construction() (AlgebraicClosureFunctor, Rational Field)
- gen(n=0)[source]#
Return the \(n\)-th element of the tuple returned by
gens()
.EXAMPLES:
sage: QQbar.gen(0) I sage: QQbar.gen(1) Traceback (most recent call last): ... IndexError: n must be 0
>>> from sage.all import * >>> QQbar.gen(Integer(0)) I >>> QQbar.gen(Integer(1)) Traceback (most recent call last): ... IndexError: n must be 0
- gens()[source]#
Return a set of generators for this field.
As this field is not finitely generated over its prime field, we opt for just returning I.
EXAMPLES:
sage: QQbar.gens() (I,)
>>> from sage.all import * >>> QQbar.gens() (I,)
- ngens()[source]#
Return the size of the tuple returned by
gens()
.EXAMPLES:
sage: QQbar.ngens() 1
>>> from sage.all import * >>> QQbar.ngens() 1
- polynomial_root(poly, interval, multiplicity=1)[source]#
Given a polynomial with algebraic coefficients and an interval enclosing exactly one root of the polynomial, constructs an algebraic real representation of that root.
The polynomial need not be irreducible, or even squarefree; but if the given root is a multiple root, its multiplicity must be specified. (IMPORTANT NOTE: Currently, multiplicity-\(k\) roots are handled by taking the \((k-1)\)-st derivative of the polynomial. This means that the interval must enclose exactly one root of this derivative.)
The conditions on the arguments (that the interval encloses exactly one root, and that multiple roots match the given multiplicity) are not checked; if they are not satisfied, an error may be thrown (possibly later, when the algebraic number is used), or wrong answers may result.
Note that if you are constructing multiple roots of a single polynomial, it is better to use
QQbar.common_polynomial
to get a shared polynomial.EXAMPLES:
sage: x = polygen(QQbar) sage: phi = QQbar.polynomial_root(x^2 - x - 1, RIF(0, 2)); phi 1.618033988749895? sage: p = (x-1)^7 * (x-2) sage: r = QQbar.polynomial_root(p, RIF(9/10, 11/10), multiplicity=7) sage: r; r == 1 1 True sage: p = (x-phi)*(x-sqrt(QQbar(2))) sage: r = QQbar.polynomial_root(p, RIF(1, 3/2)) sage: r; r == sqrt(QQbar(2)) 1.414213562373095? True
>>> from sage.all import * >>> x = polygen(QQbar) >>> phi = QQbar.polynomial_root(x**Integer(2) - x - Integer(1), RIF(Integer(0), Integer(2))); phi 1.618033988749895? >>> p = (x-Integer(1))**Integer(7) * (x-Integer(2)) >>> r = QQbar.polynomial_root(p, RIF(Integer(9)/Integer(10), Integer(11)/Integer(10)), multiplicity=Integer(7)) >>> r; r == Integer(1) 1 True >>> p = (x-phi)*(x-sqrt(QQbar(Integer(2)))) >>> r = QQbar.polynomial_root(p, RIF(Integer(1), Integer(3)/Integer(2))) >>> r; r == sqrt(QQbar(Integer(2))) 1.414213562373095? True
- random_element(poly_degree=2, *args, **kwds)[source]#
Return a random algebraic number.
INPUT:
poly_degree
– default: 2; degree of the random polynomial over the integers of which the returned algebraic number is a root. This is not necessarily the degree of the minimal polynomial of the number. Increase this parameter to achieve a greater diversity of algebraic numbers, at a cost of greater computation time. You can also vary the distribution of the coefficients but that will not vary the degree of the extension containing the element.args
,kwds
– arguments and keywords passed to the random number generator for elements ofZZ
, the integers. Seerandom_element()
for details, or see example below.
OUTPUT:
An element of
QQbar
, the field of algebraic numbers (seesage.rings.qqbar
).ALGORITHM:
A polynomial with degree between 1 and
poly_degree
, with random integer coefficients is created. A root of this polynomial is chosen at random. The default degree is 2 and the integer coefficients come from a distribution heavily weighted towards \(0, \pm 1, \pm 2\).EXAMPLES:
sage: a = QQbar.random_element() sage: a # random 0.2626138748742799? + 0.8769062830975992?*I sage: a in QQbar True sage: b = QQbar.random_element(poly_degree=20) sage: b # random -0.8642649077479498? - 0.5995098147478391?*I sage: b in QQbar True
>>> from sage.all import * >>> a = QQbar.random_element() >>> a # random 0.2626138748742799? + 0.8769062830975992?*I >>> a in QQbar True >>> b = QQbar.random_element(poly_degree=Integer(20)) >>> b # random -0.8642649077479498? - 0.5995098147478391?*I >>> b in QQbar True
Parameters for the distribution of the integer coefficients of the polynomials can be passed on to the random element method for integers. For example, current default behavior of this method returns zero about 15% of the time; if we do not include zero as a possible coefficient, there will never be a zero constant term, and thus never a zero root.
sage: z = [QQbar.random_element(x=1, y=10) for _ in range(20)] sage: QQbar(0) in z False
>>> from sage.all import * >>> z = [QQbar.random_element(x=Integer(1), y=Integer(10)) for _ in range(Integer(20))] >>> QQbar(Integer(0)) in z False
If you just want real algebraic numbers you can filter them out. Using an odd degree for the polynomials will ensure some degree of success.
sage: r = [] sage: while len(r) < 3: ....: x = QQbar.random_element(poly_degree=3) ....: if x in AA: ....: r.append(x) sage: (len(r) == 3) and all(z in AA for z in r) True
>>> from sage.all import * >>> r = [] >>> while len(r) < Integer(3): ... x = QQbar.random_element(poly_degree=Integer(3)) ... if x in AA: ... r.append(x) >>> (len(r) == Integer(3)) and all(z in AA for z in r) True
- zeta(n=4)[source]#
Return a primitive \(n\)’th root of unity, specifically \(\exp(2*\pi*i/n)\).
INPUT:
n
(integer) – default 4
EXAMPLES:
sage: QQbar.zeta(1) 1 sage: QQbar.zeta(2) -1 sage: QQbar.zeta(3) -0.500000000000000? + 0.866025403784439?*I sage: QQbar.zeta(4) I sage: QQbar.zeta() I sage: QQbar.zeta(5) 0.3090169943749474? + 0.9510565162951536?*I sage: QQbar.zeta(3000) 0.999997806755380? + 0.002094393571219374?*I
>>> from sage.all import * >>> QQbar.zeta(Integer(1)) 1 >>> QQbar.zeta(Integer(2)) -1 >>> QQbar.zeta(Integer(3)) -0.500000000000000? + 0.866025403784439?*I >>> QQbar.zeta(Integer(4)) I >>> QQbar.zeta() I >>> QQbar.zeta(Integer(5)) 0.3090169943749474? + 0.9510565162951536?*I >>> QQbar.zeta(Integer(3000)) 0.999997806755380? + 0.002094393571219374?*I
- class sage.rings.qqbar.AlgebraicField_common[source]#
Bases:
AlgebraicField_common
Common base class for the classes
AlgebraicRealField
andAlgebraicField
.- characteristic()[source]#
Return the characteristic of this field.
Since this class is only used for fields of characteristic 0, this always returns 0.
EXAMPLES:
sage: AA.characteristic() 0
>>> from sage.all import * >>> AA.characteristic() 0
- common_polynomial(poly)[source]#
Given a polynomial with algebraic coefficients, return a wrapper that caches high-precision calculations and factorizations. This wrapper can be passed to
polynomial_root()
in place of the polynomial.Using
common_polynomial()
makes no semantic difference, but will improve efficiency if you are dealing with multiple roots of a single polynomial.EXAMPLES:
sage: x = polygen(ZZ) sage: p = AA.common_polynomial(x^2 - x - 1) sage: phi = AA.polynomial_root(p, RIF(1, 2)) sage: tau = AA.polynomial_root(p, RIF(-1, 0)) sage: phi + tau == 1 True sage: phi * tau == -1 True sage: # needs sage.symbolic sage: x = polygen(SR) sage: p = (x - sqrt(-5)) * (x - sqrt(3)); p x^2 + (-sqrt(3) - sqrt(-5))*x + sqrt(3)*sqrt(-5) sage: p = QQbar.common_polynomial(p) sage: a = QQbar.polynomial_root(p, CIF(RIF(-0.1, 0.1), RIF(2, 3))); a 0.?e-18 + 2.236067977499790?*I sage: b = QQbar.polynomial_root(p, RIF(1, 2)); b 1.732050807568878?
>>> from sage.all import * >>> x = polygen(ZZ) >>> p = AA.common_polynomial(x**Integer(2) - x - Integer(1)) >>> phi = AA.polynomial_root(p, RIF(Integer(1), Integer(2))) >>> tau = AA.polynomial_root(p, RIF(-Integer(1), Integer(0))) >>> phi + tau == Integer(1) True >>> phi * tau == -Integer(1) True >>> # needs sage.symbolic >>> x = polygen(SR) >>> p = (x - sqrt(-Integer(5))) * (x - sqrt(Integer(3))); p x^2 + (-sqrt(3) - sqrt(-5))*x + sqrt(3)*sqrt(-5) >>> p = QQbar.common_polynomial(p) >>> a = QQbar.polynomial_root(p, CIF(RIF(-RealNumber('0.1'), RealNumber('0.1')), RIF(Integer(2), Integer(3)))); a 0.?e-18 + 2.236067977499790?*I >>> b = QQbar.polynomial_root(p, RIF(Integer(1), Integer(2))); b 1.732050807568878?
These “common polynomials” can be shared between real and complex roots:
sage: p = AA.common_polynomial(x^3 - x - 1) sage: r1 = AA.polynomial_root(p, RIF(1.3, 1.4)); r1 1.324717957244746? sage: r2 = QQbar.polynomial_root(p, CIF(RIF(-0.7, -0.6), RIF(0.5, 0.6))); r2 -0.6623589786223730? + 0.5622795120623013?*I
>>> from sage.all import * >>> p = AA.common_polynomial(x**Integer(3) - x - Integer(1)) >>> r1 = AA.polynomial_root(p, RIF(RealNumber('1.3'), RealNumber('1.4'))); r1 1.324717957244746? >>> r2 = QQbar.polynomial_root(p, CIF(RIF(-RealNumber('0.7'), -RealNumber('0.6')), RIF(RealNumber('0.5'), RealNumber('0.6')))); r2 -0.6623589786223730? + 0.5622795120623013?*I
- class sage.rings.qqbar.AlgebraicGenerator(field, root)[source]#
Bases:
SageObject
An
AlgebraicGenerator
represents both an algebraic number \(\alpha\) and the number field \(\QQ[\alpha]\). There is a singleAlgebraicGenerator
representing \(\QQ\) (with \(\alpha=0\)).The
AlgebraicGenerator
class is private, and should not be used directly.- conjugate()[source]#
If this generator is for the algebraic number \(\alpha\), return a generator for the complex conjugate of \(\alpha\).
EXAMPLES:
sage: from sage.rings.qqbar import AlgebraicGenerator sage: x = polygen(QQ); f = x^4 + x + 17 sage: nf = NumberField(f,name='a') sage: b = f.roots(QQbar)[0][0] sage: root = b._descr sage: gen = AlgebraicGenerator(nf, root) sage: gen.conjugate() Number Field in a with defining polynomial x^4 + x + 17 with a in -1.436449997483091? + 1.374535713065812?*I
>>> from sage.all import * >>> from sage.rings.qqbar import AlgebraicGenerator >>> x = polygen(QQ); f = x**Integer(4) + x + Integer(17) >>> nf = NumberField(f,name='a') >>> b = f.roots(QQbar)[Integer(0)][Integer(0)] >>> root = b._descr >>> gen = AlgebraicGenerator(nf, root) >>> gen.conjugate() Number Field in a with defining polynomial x^4 + x + 17 with a in -1.436449997483091? + 1.374535713065812?*I
- field()[source]#
Return the number field attached to self.
EXAMPLES:
sage: from sage.rings.qqbar import qq_generator sage: qq_generator.field() Rational Field
>>> from sage.all import * >>> from sage.rings.qqbar import qq_generator >>> qq_generator.field() Rational Field
- is_complex()[source]#
Return
True
if this is a generator for a non-real number field.EXAMPLES:
sage: z7 = QQbar.zeta(7) sage: g = z7._descr._generator sage: g.is_complex() True sage: from sage.rings.qqbar import ANRoot, AlgebraicGenerator sage: y = polygen(QQ, 'y') sage: x = polygen(QQbar) sage: nf = NumberField(y^2 - y - 1, name='a', check=False) sage: root = ANRoot(x^2 - x - 1, RIF(1, 2)) sage: gen = AlgebraicGenerator(nf, root) sage: gen.is_complex() False
>>> from sage.all import * >>> z7 = QQbar.zeta(Integer(7)) >>> g = z7._descr._generator >>> g.is_complex() True >>> from sage.rings.qqbar import ANRoot, AlgebraicGenerator >>> y = polygen(QQ, 'y') >>> x = polygen(QQbar) >>> nf = NumberField(y**Integer(2) - y - Integer(1), name='a', check=False) >>> root = ANRoot(x**Integer(2) - x - Integer(1), RIF(Integer(1), Integer(2))) >>> gen = AlgebraicGenerator(nf, root) >>> gen.is_complex() False
- is_trivial()[source]#
Return
True
iff this is the trivial generator (alpha == 1), which does not actually extend the rationals.EXAMPLES:
sage: from sage.rings.qqbar import qq_generator sage: qq_generator.is_trivial() True
>>> from sage.all import * >>> from sage.rings.qqbar import qq_generator >>> qq_generator.is_trivial() True
- pari_field()[source]#
Return the PARI field attached to this generator.
EXAMPLES:
sage: from sage.rings.qqbar import qq_generator sage: qq_generator.pari_field() Traceback (most recent call last): ... ValueError: No PARI field attached to trivial generator sage: from sage.rings.qqbar import ANRoot, AlgebraicGenerator, qq_generator sage: y = polygen(QQ) sage: x = polygen(QQbar) sage: nf = NumberField(y^2 - y - 1, name='a', check=False) sage: root = ANRoot(x^2 - x - 1, RIF(1, 2)) sage: gen = AlgebraicGenerator(nf, root) sage: gen.pari_field() [[y^2 - y - 1, [2, 0], ...]
>>> from sage.all import * >>> from sage.rings.qqbar import qq_generator >>> qq_generator.pari_field() Traceback (most recent call last): ... ValueError: No PARI field attached to trivial generator >>> from sage.rings.qqbar import ANRoot, AlgebraicGenerator, qq_generator >>> y = polygen(QQ) >>> x = polygen(QQbar) >>> nf = NumberField(y**Integer(2) - y - Integer(1), name='a', check=False) >>> root = ANRoot(x**Integer(2) - x - Integer(1), RIF(Integer(1), Integer(2))) >>> gen = AlgebraicGenerator(nf, root) >>> gen.pari_field() [[y^2 - y - 1, [2, 0], ...]
- root_as_algebraic()[source]#
Return the root attached to self as an algebraic number.
EXAMPLES:
sage: t = sage.rings.qqbar.qq_generator.root_as_algebraic(); t 1 sage: t.parent() Algebraic Real Field
>>> from sage.all import * >>> t = sage.rings.qqbar.qq_generator.root_as_algebraic(); t 1 >>> t.parent() Algebraic Real Field
- super_poly(super, checked=None)[source]#
Given a generator
gen
and another generatorsuper
, wheresuper
is the result of a tree ofunion()
operations where one of the leaves isgen
,gen.super_poly(super)
returns a polynomial expressing the value ofgen
in terms of the value ofsuper
(except that ifgen
isqq_generator
,super_poly()
always returns None.)EXAMPLES:
sage: from sage.rings.qqbar import AlgebraicGenerator, ANRoot, qq_generator sage: _.<y> = QQ['y'] sage: x = polygen(QQbar) sage: nf2 = NumberField(y^2 - 2, name='a', check=False) sage: root2 = ANRoot(x^2 - 2, RIF(1, 2)) sage: gen2 = AlgebraicGenerator(nf2, root2) sage: gen2 Number Field in a with defining polynomial y^2 - 2 with a in 1.414213562373095? sage: nf3 = NumberField(y^2 - 3, name='a', check=False) sage: root3 = ANRoot(x^2 - 3, RIF(1, 2)) sage: gen3 = AlgebraicGenerator(nf3, root3) sage: gen3 Number Field in a with defining polynomial y^2 - 3 with a in 1.732050807568878? sage: gen2_3 = gen2.union(gen3) sage: gen2_3 Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a in -1.931851652578137? sage: qq_generator.super_poly(gen2) is None True sage: gen2.super_poly(gen2_3) -a^3 + 3*a sage: gen3.super_poly(gen2_3) a^2 - 2
>>> from sage.all import * >>> from sage.rings.qqbar import AlgebraicGenerator, ANRoot, qq_generator >>> _ = QQ['y']; (y,) = _._first_ngens(1) >>> x = polygen(QQbar) >>> nf2 = NumberField(y**Integer(2) - Integer(2), name='a', check=False) >>> root2 = ANRoot(x**Integer(2) - Integer(2), RIF(Integer(1), Integer(2))) >>> gen2 = AlgebraicGenerator(nf2, root2) >>> gen2 Number Field in a with defining polynomial y^2 - 2 with a in 1.414213562373095? >>> nf3 = NumberField(y**Integer(2) - Integer(3), name='a', check=False) >>> root3 = ANRoot(x**Integer(2) - Integer(3), RIF(Integer(1), Integer(2))) >>> gen3 = AlgebraicGenerator(nf3, root3) >>> gen3 Number Field in a with defining polynomial y^2 - 3 with a in 1.732050807568878? >>> gen2_3 = gen2.union(gen3) >>> gen2_3 Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a in -1.931851652578137? >>> qq_generator.super_poly(gen2) is None True >>> gen2.super_poly(gen2_3) -a^3 + 3*a >>> gen3.super_poly(gen2_3) a^2 - 2
- union(other, name='a')[source]#
Given generators
self
, \(\alpha\), andother
, \(\beta\),self.union(other)
gives a generator for the number field \(\QQ[\alpha][\beta]\).INPUT:
other
– an algebraic numbername
– string (default:'a'
); a name for the primitive element
EXAMPLES:
sage: from sage.rings.qqbar import ANRoot, AlgebraicGenerator, qq_generator sage: _.<y> = QQ['y'] sage: x = polygen(QQbar) sage: nf2 = NumberField(y^2 - 2, name='a', check=False) sage: root2 = ANRoot(x^2 - 2, RIF(1, 2)) sage: gen2 = AlgebraicGenerator(nf2, root2) sage: gen2 Number Field in a with defining polynomial y^2 - 2 with a in 1.414213562373095? sage: nf3 = NumberField(y^2 - 3, name='a', check=False) sage: root3 = ANRoot(x^2 - 3, RIF(1, 2)) sage: gen3 = AlgebraicGenerator(nf3, root3) sage: gen3 Number Field in a with defining polynomial y^2 - 3 with a in 1.732050807568878? sage: gen2.union(qq_generator) is gen2 True sage: qq_generator.union(gen3) is gen3 True sage: gen2.union(gen3, name='b') Number Field in b with defining polynomial y^4 - 4*y^2 + 1 with b in -1.931851652578137?
>>> from sage.all import * >>> from sage.rings.qqbar import ANRoot, AlgebraicGenerator, qq_generator >>> _ = QQ['y']; (y,) = _._first_ngens(1) >>> x = polygen(QQbar) >>> nf2 = NumberField(y**Integer(2) - Integer(2), name='a', check=False) >>> root2 = ANRoot(x**Integer(2) - Integer(2), RIF(Integer(1), Integer(2))) >>> gen2 = AlgebraicGenerator(nf2, root2) >>> gen2 Number Field in a with defining polynomial y^2 - 2 with a in 1.414213562373095? >>> nf3 = NumberField(y**Integer(2) - Integer(3), name='a', check=False) >>> root3 = ANRoot(x**Integer(2) - Integer(3), RIF(Integer(1), Integer(2))) >>> gen3 = AlgebraicGenerator(nf3, root3) >>> gen3 Number Field in a with defining polynomial y^2 - 3 with a in 1.732050807568878? >>> gen2.union(qq_generator) is gen2 True >>> qq_generator.union(gen3) is gen3 True >>> gen2.union(gen3, name='b') Number Field in b with defining polynomial y^4 - 4*y^2 + 1 with b in -1.931851652578137?
- class sage.rings.qqbar.AlgebraicGeneratorRelation(child1, child1_poly, child2, child2_poly, parent)[source]#
Bases:
SageObject
A simple class for maintaining relations in the lattice of algebraic extensions.
- class sage.rings.qqbar.AlgebraicNumber(x)[source]#
Bases:
AlgebraicNumber_base
The class for algebraic numbers (complex numbers which are the roots of a polynomial with integer coefficients). Much of its functionality is inherited from
AlgebraicNumber_base
.- _richcmp_(other, op)[source]#
Compare two algebraic numbers, lexicographically. (That is, first compare the real components; if the real components are equal, compare the imaginary components.)
EXAMPLES:
sage: x = QQbar.zeta(3); x -0.500000000000000? + 0.866025403784439?*I sage: QQbar(-1) < x True sage: QQbar(-1/2) < x True sage: QQbar(0) > x True
>>> from sage.all import * >>> x = QQbar.zeta(Integer(3)); x -0.500000000000000? + 0.866025403784439?*I >>> QQbar(-Integer(1)) < x True >>> QQbar(-Integer(1)/Integer(2)) < x True >>> QQbar(Integer(0)) > x True
One problem with this lexicographic ordering is the fact that if two algebraic numbers have the same real component, that real component has to be compared for exact equality, which can be a costly operation. For the special case where both numbers have the same minimal polynomial, that cost can be avoided, though (see Issue #16964):
sage: x = polygen(ZZ) sage: p = 69721504*x^8 + 251777664*x^6 + 329532012*x^4 + 184429548*x^2 + 37344321 sage: sorted(p.roots(QQbar,False)) [-0.0221204634374361? - 1.090991904211621?*I, -0.0221204634374361? + 1.090991904211621?*I, -0.8088604911480535?*I, 0.?e-182 - 0.7598602580415435?*I, 0.?e-249 + 0.7598602580415435?*I, 0.8088604911480535?*I, 0.0221204634374361? - 1.090991904211621?*I, 0.0221204634374361? + 1.090991904211621?*I]
>>> from sage.all import * >>> x = polygen(ZZ) >>> p = Integer(69721504)*x**Integer(8) + Integer(251777664)*x**Integer(6) + Integer(329532012)*x**Integer(4) + Integer(184429548)*x**Integer(2) + Integer(37344321) >>> sorted(p.roots(QQbar,False)) [-0.0221204634374361? - 1.090991904211621?*I, -0.0221204634374361? + 1.090991904211621?*I, -0.8088604911480535?*I, 0.?e-182 - 0.7598602580415435?*I, 0.?e-249 + 0.7598602580415435?*I, 0.8088604911480535?*I, 0.0221204634374361? - 1.090991904211621?*I, 0.0221204634374361? + 1.090991904211621?*I]
It also works for comparison of conjugate roots even in a degenerate situation where many roots have the same real part. In the following example, the polynomial
p2
is irreducible and all its roots have real part equal to \(1\):sage: p1 = x^8 + 74*x^7 + 2300*x^6 + 38928*x^5 + \ ....: 388193*x^4 + 2295312*x^3 + 7613898*x^2 + \ ....: 12066806*x + 5477001 sage: p2 = p1((x-1)^2) sage: sum(1 for r in p2.roots(CC,False) if abs(r.real() - 1) < 0.0001) 16 sage: r1 = QQbar.polynomial_root(p2, CIF(1, (-4.1,-4.0))) sage: r2 = QQbar.polynomial_root(p2, CIF(1, (4.0, 4.1))) sage: all([r1<r2, r1==r1, r2==r2, r2>r1]) True
>>> from sage.all import * >>> p1 = x**Integer(8) + Integer(74)*x**Integer(7) + Integer(2300)*x**Integer(6) + Integer(38928)*x**Integer(5) + Integer(388193)*x**Integer(4) + Integer(2295312)*x**Integer(3) + Integer(7613898)*x**Integer(2) + Integer(12066806)*x + Integer(5477001) >>> p2 = p1((x-Integer(1))**Integer(2)) >>> sum(Integer(1) for r in p2.roots(CC,False) if abs(r.real() - Integer(1)) < RealNumber('0.0001')) 16 >>> r1 = QQbar.polynomial_root(p2, CIF(Integer(1), (-RealNumber('4.1'),-RealNumber('4.0')))) >>> r2 = QQbar.polynomial_root(p2, CIF(Integer(1), (RealNumber('4.0'), RealNumber('4.1')))) >>> all([r1<r2, r1==r1, r2==r2, r2>r1]) True
Though, comparing roots which are not equal or conjugate is much slower because the algorithm needs to check the equality of the real parts:
sage: sorted(p2.roots(QQbar,False)) # long time - 3 secs [1.000000000000000? - 4.016778562562223?*I, 1.000000000000000? - 3.850538755978243?*I, 1.000000000000000? - 3.390564396412898?*I, ... 1.000000000000000? + 3.390564396412898?*I, 1.000000000000000? + 3.850538755978243?*I, 1.000000000000000? + 4.016778562562223?*I]
>>> from sage.all import * >>> sorted(p2.roots(QQbar,False)) # long time - 3 secs [1.000000000000000? - 4.016778562562223?*I, 1.000000000000000? - 3.850538755978243?*I, 1.000000000000000? - 3.390564396412898?*I, ... 1.000000000000000? + 3.390564396412898?*I, 1.000000000000000? + 3.850538755978243?*I, 1.000000000000000? + 4.016778562562223?*I]
- complex_exact(field)[source]#
Given a
ComplexField
, return the best possible approximation of this number in that field. Note that if either component is sufficiently close to the halfway point between two floating-point numbers in the correspondingRealField
, then this will trigger exact computation, which may be very slow.EXAMPLES:
sage: a = QQbar.zeta(9) + QQbar(I) + QQbar.zeta(9).conjugate(); a 1.532088886237957? + 1.000000000000000?*I sage: a.complex_exact(CIF) 1.532088886237957? + 1*I
>>> from sage.all import * >>> a = QQbar.zeta(Integer(9)) + QQbar(I) + QQbar.zeta(Integer(9)).conjugate(); a 1.532088886237957? + 1.000000000000000?*I >>> a.complex_exact(CIF) 1.532088886237957? + 1*I
- complex_number(field)[source]#
Given the complex field
field
, compute an accurate approximation of this element in that field.The approximation will be off by at most two ulp’s in each component, except for components which are very close to zero, which will have an absolute error at most \(2^{-prec+1}\) where
prec
is the precision of the field.EXAMPLES:
sage: a = QQbar.zeta(5) sage: a.complex_number(CC) 0.309016994374947 + 0.951056516295154*I sage: b = QQbar(2).sqrt() + QQbar(3).sqrt() * QQbar.gen() sage: b.complex_number(ComplexField(128)) 1.4142135623730950488016887242096980786 + 1.7320508075688772935274463415058723669*I
>>> from sage.all import * >>> a = QQbar.zeta(Integer(5)) >>> a.complex_number(CC) 0.309016994374947 + 0.951056516295154*I >>> b = QQbar(Integer(2)).sqrt() + QQbar(Integer(3)).sqrt() * QQbar.gen() >>> b.complex_number(ComplexField(Integer(128))) 1.4142135623730950488016887242096980786 + 1.7320508075688772935274463415058723669*I
- conjugate()[source]#
Return the complex conjugate of
self
.EXAMPLES:
sage: QQbar(3 + 4*I).conjugate() 3 - 4*I sage: QQbar.zeta(7).conjugate() 0.6234898018587335? - 0.7818314824680299?*I sage: QQbar.zeta(7) + QQbar.zeta(7).conjugate() 1.246979603717467? + 0.?e-18*I
>>> from sage.all import * >>> QQbar(Integer(3) + Integer(4)*I).conjugate() 3 - 4*I >>> QQbar.zeta(Integer(7)).conjugate() 0.6234898018587335? - 0.7818314824680299?*I >>> QQbar.zeta(Integer(7)) + QQbar.zeta(Integer(7)).conjugate() 1.246979603717467? + 0.?e-18*I
- imag()[source]#
Return the imaginary part of
self
.EXAMPLES:
sage: QQbar.zeta(7).imag() 0.7818314824680299?
>>> from sage.all import * >>> QQbar.zeta(Integer(7)).imag() 0.7818314824680299?
- interval_exact(field)[source]#
Given a
ComplexIntervalField
, compute the best possible approximation of this number in that field. Note that if either the real or imaginary parts of this number are sufficiently close to some floating-point number (and, in particular, if either is exactly representable in floating-point), then this will trigger exact computation, which may be very slow.EXAMPLES:
sage: a = QQbar(I).sqrt(); a 0.7071067811865475? + 0.7071067811865475?*I sage: a.interval_exact(CIF) 0.7071067811865475? + 0.7071067811865475?*I sage: b = QQbar((1+I)*sqrt(2)/2) # needs sage.symbolic sage: (a - b).interval(CIF) # needs sage.symbolic 0.?e-19 + 0.?e-18*I sage: (a - b).interval_exact(CIF) # needs sage.symbolic 0
>>> from sage.all import * >>> a = QQbar(I).sqrt(); a 0.7071067811865475? + 0.7071067811865475?*I >>> a.interval_exact(CIF) 0.7071067811865475? + 0.7071067811865475?*I >>> b = QQbar((Integer(1)+I)*sqrt(Integer(2))/Integer(2)) # needs sage.symbolic >>> (a - b).interval(CIF) # needs sage.symbolic 0.?e-19 + 0.?e-18*I >>> (a - b).interval_exact(CIF) # needs sage.symbolic 0
- multiplicative_order()[source]#
Compute the multiplicative order of this algebraic number.
That is, find the smallest positive integer \(n\) such that \(x^n = 1\). If there is no such \(n\), returns
+Infinity
.We first check that
abs(x)
is very close to 1. If so, we compute \(x\) exactly and examine its argument.EXAMPLES:
sage: QQbar(-sqrt(3)/2 - I/2).multiplicative_order() # needs sage.symbolic 12 sage: QQbar(1).multiplicative_order() 1 sage: QQbar(-I).multiplicative_order() 4 sage: QQbar(707/1000 + 707/1000*I).multiplicative_order() +Infinity sage: QQbar(3/5 + 4/5*I).multiplicative_order() +Infinity
>>> from sage.all import * >>> QQbar(-sqrt(Integer(3))/Integer(2) - I/Integer(2)).multiplicative_order() # needs sage.symbolic 12 >>> QQbar(Integer(1)).multiplicative_order() 1 >>> QQbar(-I).multiplicative_order() 4 >>> QQbar(Integer(707)/Integer(1000) + Integer(707)/Integer(1000)*I).multiplicative_order() +Infinity >>> QQbar(Integer(3)/Integer(5) + Integer(4)/Integer(5)*I).multiplicative_order() +Infinity
- norm()[source]#
Return
self * self.conjugate()
.This is the algebraic definition of norm, if we view
QQbar
asAA[I]
.EXAMPLES:
sage: QQbar(3 + 4*I).norm() 25 sage: type(QQbar(I).norm()) <class 'sage.rings.qqbar.AlgebraicReal'> sage: QQbar.zeta(1007).norm() 1.000000000000000?
>>> from sage.all import * >>> QQbar(Integer(3) + Integer(4)*I).norm() 25 >>> type(QQbar(I).norm()) <class 'sage.rings.qqbar.AlgebraicReal'> >>> QQbar.zeta(Integer(1007)).norm() 1.000000000000000?
- rational_argument()[source]#
Return the argument of
self
, divided by \(2\pi\), as long as this result is rational. Otherwise returnsNone
. Always triggers exact computation.EXAMPLES:
sage: QQbar((1+I)*(sqrt(2)+sqrt(5))).rational_argument() # needs sage.symbolic 1/8 sage: QQbar(-1 + I*sqrt(3)).rational_argument() # needs sage.symbolic 1/3 sage: QQbar(-1 - I*sqrt(3)).rational_argument() # needs sage.symbolic -1/3 sage: QQbar(3+4*I).rational_argument() is None True sage: (QQbar(2)**(1/5) * QQbar.zeta(7)**2).rational_argument() # long time 2/7 sage: (QQbar.zeta(73)**5).rational_argument() 5/73 sage: (QQbar.zeta(3)^65536).rational_argument() 1/3
>>> from sage.all import * >>> QQbar((Integer(1)+I)*(sqrt(Integer(2))+sqrt(Integer(5)))).rational_argument() # needs sage.symbolic 1/8 >>> QQbar(-Integer(1) + I*sqrt(Integer(3))).rational_argument() # needs sage.symbolic 1/3 >>> QQbar(-Integer(1) - I*sqrt(Integer(3))).rational_argument() # needs sage.symbolic -1/3 >>> QQbar(Integer(3)+Integer(4)*I).rational_argument() is None True >>> (QQbar(Integer(2))**(Integer(1)/Integer(5)) * QQbar.zeta(Integer(7))**Integer(2)).rational_argument() # long time 2/7 >>> (QQbar.zeta(Integer(73))**Integer(5)).rational_argument() 5/73 >>> (QQbar.zeta(Integer(3))**Integer(65536)).rational_argument() 1/3
- class sage.rings.qqbar.AlgebraicNumberPowQQAction(G, S)[source]#
Bases:
Action
Implement powering of an algebraic number (an element of
QQbar
orAA
) by a rational.This is always a right action.
INPUT:
G
– must beQQ
S
– the parent on which to act, eitherAA
orQQbar
.
Note
To compute
x ^ (a/b)
, we take the \(b\)’th root of \(x\); then we take that to the \(a\)’th power. If \(x\) is a negative algebraic real and \(b\) is odd, take the real \(b\)’th root; otherwise take the principal \(b\)’th root.EXAMPLES:
In
QQbar
:sage: QQbar(2)^(1/2) 1.414213562373095? sage: QQbar(8)^(2/3) 4 sage: QQbar(8)^(2/3) == 4 True sage: x = polygen(QQbar) sage: phi = QQbar.polynomial_root(x^2 - x - 1, RIF(1, 2)) sage: tau = QQbar.polynomial_root(x^2 - x - 1, RIF(-1, 0)) sage: rt5 = QQbar(5)^(1/2) sage: phi^10 / rt5 55.00363612324742? sage: tau^10 / rt5 0.003636123247413266? sage: (phi^10 - tau^10) / rt5 55.00000000000000? sage: (phi^10 - tau^10) / rt5 == fibonacci(10) True sage: (phi^50 - tau^50) / rt5 == fibonacci(50) True sage: QQbar(-8)^(1/3) 1.000000000000000? + 1.732050807568878?*I sage: (QQbar(-8)^(1/3))^3 -8 sage: QQbar(32)^(1/5) 2 sage: a = QQbar.zeta(7)^(1/3); a 0.9555728057861407? + 0.2947551744109043?*I sage: a == QQbar.zeta(21) True sage: QQbar.zeta(7)^6 0.6234898018587335? - 0.7818314824680299?*I sage: (QQbar.zeta(7)^6)^(1/3) * QQbar.zeta(21) 1.000000000000000? + 0.?e-17*I
>>> from sage.all import * >>> QQbar(Integer(2))**(Integer(1)/Integer(2)) 1.414213562373095? >>> QQbar(Integer(8))**(Integer(2)/Integer(3)) 4 >>> QQbar(Integer(8))**(Integer(2)/Integer(3)) == Integer(4) True >>> x = polygen(QQbar) >>> phi = QQbar.polynomial_root(x**Integer(2) - x - Integer(1), RIF(Integer(1), Integer(2))) >>> tau = QQbar.polynomial_root(x**Integer(2) - x - Integer(1), RIF(-Integer(1), Integer(0))) >>> rt5 = QQbar(Integer(5))**(Integer(1)/Integer(2)) >>> phi**Integer(10) / rt5 55.00363612324742? >>> tau**Integer(10) / rt5 0.003636123247413266? >>> (phi**Integer(10) - tau**Integer(10)) / rt5 55.00000000000000? >>> (phi**Integer(10) - tau**Integer(10)) / rt5 == fibonacci(Integer(10)) True >>> (phi**Integer(50) - tau**Integer(50)) / rt5 == fibonacci(Integer(50)) True >>> QQbar(-Integer(8))**(Integer(1)/Integer(3)) 1.000000000000000? + 1.732050807568878?*I >>> (QQbar(-Integer(8))**(Integer(1)/Integer(3)))**Integer(3) -8 >>> QQbar(Integer(32))**(Integer(1)/Integer(5)) 2 >>> a = QQbar.zeta(Integer(7))**(Integer(1)/Integer(3)); a 0.9555728057861407? + 0.2947551744109043?*I >>> a == QQbar.zeta(Integer(21)) True >>> QQbar.zeta(Integer(7))**Integer(6) 0.6234898018587335? - 0.7818314824680299?*I >>> (QQbar.zeta(Integer(7))**Integer(6))**(Integer(1)/Integer(3)) * QQbar.zeta(Integer(21)) 1.000000000000000? + 0.?e-17*I
In
AA
:sage: AA(2)^(1/2) 1.414213562373095? sage: AA(8)^(2/3) 4 sage: AA(8)^(2/3) == 4 True sage: x = polygen(AA) sage: phi = AA.polynomial_root(x^2 - x - 1, RIF(0, 2)) sage: tau = AA.polynomial_root(x^2 - x - 1, RIF(-2, 0)) sage: rt5 = AA(5)^(1/2) sage: phi^10 / rt5 55.00363612324742? sage: tau^10 / rt5 0.003636123247413266? sage: (phi^10 - tau^10) / rt5 55.00000000000000? sage: (phi^10 - tau^10) / rt5 == fibonacci(10) True sage: (phi^50 - tau^50) / rt5 == fibonacci(50) True
>>> from sage.all import * >>> AA(Integer(2))**(Integer(1)/Integer(2)) 1.414213562373095? >>> AA(Integer(8))**(Integer(2)/Integer(3)) 4 >>> AA(Integer(8))**(Integer(2)/Integer(3)) == Integer(4) True >>> x = polygen(AA) >>> phi = AA.polynomial_root(x**Integer(2) - x - Integer(1), RIF(Integer(0), Integer(2))) >>> tau = AA.polynomial_root(x**Integer(2) - x - Integer(1), RIF(-Integer(2), Integer(0))) >>> rt5 = AA(Integer(5))**(Integer(1)/Integer(2)) >>> phi**Integer(10) / rt5 55.00363612324742? >>> tau**Integer(10) / rt5 0.003636123247413266? >>> (phi**Integer(10) - tau**Integer(10)) / rt5 55.00000000000000? >>> (phi**Integer(10) - tau**Integer(10)) / rt5 == fibonacci(Integer(10)) True >>> (phi**Integer(50) - tau**Integer(50)) / rt5 == fibonacci(Integer(50)) True
- class sage.rings.qqbar.AlgebraicNumber_base(parent, x)[source]#
Bases:
FieldElement
This is the common base class for algebraic numbers (complex numbers which are the zero of a polynomial in \(\ZZ[x]\)) and algebraic reals (algebraic numbers which happen to be real).
AlgebraicNumber
objects can be created usingQQbar
(==AlgebraicNumberField()
), andAlgebraicReal
objects can be created usingAA
(==AlgebraicRealField()
). They can be created either by coercing a rational or a symbolic expression, or by using theQQbar.polynomial_root()
orAA.polynomial_root()
method to construct a particular root of a polynomial with algebraic coefficients. Also,AlgebraicNumber
andAlgebraicReal
are closed under addition, subtraction, multiplication, division (except by 0), and rational powers (including roots), except that for a negativeAlgebraicReal
, taking a power with an even denominator returns anAlgebraicNumber
instead of anAlgebraicReal
.AlgebraicNumber
andAlgebraicReal
objects can be approximated to any desired precision. They can be compared exactly; if the two numbers are very close, or are equal, this may require exact computation, which can be extremely slow.As long as exact computation is not triggered, computation with algebraic numbers should not be too much slower than computation with intervals. As mentioned above, exact computation is triggered when comparing two algebraic numbers which are very close together. This can be an explicit comparison in user code, but the following list of actions (not necessarily complete) can also trigger exact computation:
Dividing by an algebraic number which is very close to 0.
Using an algebraic number which is very close to 0 as the leading coefficient in a polynomial.
Taking a root of an algebraic number which is very close to 0.
The exact definition of “very close” is subject to change; currently, we compute our best approximation of the two numbers using 128-bit arithmetic, and see if that’s sufficient to decide the comparison. Note that comparing two algebraic numbers which are actually equal will always trigger exact computation, unless they are actually the same object.
EXAMPLES:
sage: sqrt(QQbar(2)) 1.414213562373095? sage: sqrt(QQbar(2))^2 == 2 True sage: x = polygen(QQbar) sage: phi = QQbar.polynomial_root(x^2 - x - 1, RIF(1, 2)) sage: phi 1.618033988749895? sage: phi^2 == phi+1 True sage: AA(sqrt(65537)) # needs sage.symbolic 256.0019531175495?
>>> from sage.all import * >>> sqrt(QQbar(Integer(2))) 1.414213562373095? >>> sqrt(QQbar(Integer(2)))**Integer(2) == Integer(2) True >>> x = polygen(QQbar) >>> phi = QQbar.polynomial_root(x**Integer(2) - x - Integer(1), RIF(Integer(1), Integer(2))) >>> phi 1.618033988749895? >>> phi**Integer(2) == phi+Integer(1) True >>> AA(sqrt(Integer(65537))) # needs sage.symbolic 256.0019531175495?
- as_number_field_element(minimal=False, embedded=False, prec=53)[source]#
Return a number field containing this value, a representation of this value as an element of that number field, and a homomorphism from the number field back to
AA
orQQbar
.INPUT:
minimal
– Boolean (default:False
). Whether to minimize the degree of the extension.embedded
– Boolean (default:False
). Whether to make the NumberField embedded.prec
– integer (default:53
). The number of bit of precision to guarantee finding real roots.
This may not return the smallest such number field, unless
minimal=True
is specified.To compute a single number field containing multiple algebraic numbers, use the function
number_field_elements_from_algebraics
instead.EXAMPLES:
sage: QQbar(sqrt(8)).as_number_field_element() # needs sage.symbolic (Number Field in a with defining polynomial y^2 - 2, 2*a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 2 To: Algebraic Real Field Defn: a |--> 1.414213562373095?) sage: x = polygen(ZZ) sage: p = x^3 + x^2 + x + 17 sage: (rt,) = p.roots(ring=AA, multiplicities=False); rt -2.804642726932742? sage: (nf, elt, hom) = rt.as_number_field_element() sage: nf, elt, hom (Number Field in a with defining polynomial y^3 - 2*y^2 - 31*y - 50, a^2 - 5*a - 19, Ring morphism: From: Number Field in a with defining polynomial y^3 - 2*y^2 - 31*y - 50 To: Algebraic Real Field Defn: a |--> 7.237653139801104?) sage: elt == rt False sage: AA(elt) Traceback (most recent call last): ... ValueError: need a real or complex embedding to convert a non rational element of a number field into an algebraic number sage: hom(elt) == rt True
>>> from sage.all import * >>> QQbar(sqrt(Integer(8))).as_number_field_element() # needs sage.symbolic (Number Field in a with defining polynomial y^2 - 2, 2*a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 2 To: Algebraic Real Field Defn: a |--> 1.414213562373095?) >>> x = polygen(ZZ) >>> p = x**Integer(3) + x**Integer(2) + x + Integer(17) >>> (rt,) = p.roots(ring=AA, multiplicities=False); rt -2.804642726932742? >>> (nf, elt, hom) = rt.as_number_field_element() >>> nf, elt, hom (Number Field in a with defining polynomial y^3 - 2*y^2 - 31*y - 50, a^2 - 5*a - 19, Ring morphism: From: Number Field in a with defining polynomial y^3 - 2*y^2 - 31*y - 50 To: Algebraic Real Field Defn: a |--> 7.237653139801104?) >>> elt == rt False >>> AA(elt) Traceback (most recent call last): ... ValueError: need a real or complex embedding to convert a non rational element of a number field into an algebraic number >>> hom(elt) == rt True
Creating an element of an embedded number field:
sage: (nf, elt, hom) = rt.as_number_field_element(embedded=True) sage: nf.coerce_embedding() Generic morphism: From: Number Field in a with defining polynomial y^3 - 2*y^2 - 31*y - 50 with a = 7.237653139801104? To: Algebraic Real Field Defn: a -> 7.237653139801104? sage: elt a^2 - 5*a - 19 sage: elt.parent() == nf True sage: hom(elt).parent() Algebraic Real Field sage: hom(elt) == rt True sage: elt == rt True sage: AA(elt) -2.804642726932742? sage: RR(elt) -2.80464272693274
>>> from sage.all import * >>> (nf, elt, hom) = rt.as_number_field_element(embedded=True) >>> nf.coerce_embedding() Generic morphism: From: Number Field in a with defining polynomial y^3 - 2*y^2 - 31*y - 50 with a = 7.237653139801104? To: Algebraic Real Field Defn: a -> 7.237653139801104? >>> elt a^2 - 5*a - 19 >>> elt.parent() == nf True >>> hom(elt).parent() Algebraic Real Field >>> hom(elt) == rt True >>> elt == rt True >>> AA(elt) -2.804642726932742? >>> RR(elt) -2.80464272693274
A complex algebraic number as an element of an embedded number field:
sage: # needs sage.symbolic sage: num = QQbar(sqrt(2) + 3^(1/3)*I) sage: nf, elt, hom = num.as_number_field_element(embedded=True) sage: hom(elt).parent() is QQbar True sage: nf.coerce_embedding() is not None True sage: QQbar(elt) == num == hom(elt) True
>>> from sage.all import * >>> # needs sage.symbolic >>> num = QQbar(sqrt(Integer(2)) + Integer(3)**(Integer(1)/Integer(3))*I) >>> nf, elt, hom = num.as_number_field_element(embedded=True) >>> hom(elt).parent() is QQbar True >>> nf.coerce_embedding() is not None True >>> QQbar(elt) == num == hom(elt) True
We see an example where we do not get the minimal number field unless we specify
minimal=True
:sage: # needs sage.symbolic sage: rt2 = AA(sqrt(2)) sage: rt3 = AA(sqrt(3)) sage: rt3b = rt2 + rt3 - rt2 sage: rt3b.as_number_field_element() (Number Field in a with defining polynomial y^4 - 4*y^2 + 1, a^2 - 2, Ring morphism: From: Number Field in a with defining polynomial y^4 - 4*y^2 + 1 To: Algebraic Real Field Defn: a |--> -1.931851652578137?) sage: rt3b.as_number_field_element(minimal=True) (Number Field in a with defining polynomial y^2 - 3, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 3 To: Algebraic Real Field Defn: a |--> 1.732050807568878?)
>>> from sage.all import * >>> # needs sage.symbolic >>> rt2 = AA(sqrt(Integer(2))) >>> rt3 = AA(sqrt(Integer(3))) >>> rt3b = rt2 + rt3 - rt2 >>> rt3b.as_number_field_element() (Number Field in a with defining polynomial y^4 - 4*y^2 + 1, a^2 - 2, Ring morphism: From: Number Field in a with defining polynomial y^4 - 4*y^2 + 1 To: Algebraic Real Field Defn: a |--> -1.931851652578137?) >>> rt3b.as_number_field_element(minimal=True) (Number Field in a with defining polynomial y^2 - 3, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 3 To: Algebraic Real Field Defn: a |--> 1.732050807568878?)
- degree()[source]#
Return the degree of this algebraic number (the degree of its minimal polynomial, or equivalently, the degree of the smallest algebraic extension of the rationals containing this number).
EXAMPLES:
sage: QQbar(5/3).degree() 1 sage: sqrt(QQbar(2)).degree() 2 sage: QQbar(17).nth_root(5).degree() 5 sage: sqrt(3+sqrt(QQbar(8))).degree() 2
>>> from sage.all import * >>> QQbar(Integer(5)/Integer(3)).degree() 1 >>> sqrt(QQbar(Integer(2))).degree() 2 >>> QQbar(Integer(17)).nth_root(Integer(5)).degree() 5 >>> sqrt(Integer(3)+sqrt(QQbar(Integer(8)))).degree() 2
- exactify()[source]#
Compute an exact representation for this number.
EXAMPLES:
sage: two = QQbar(4).nth_root(4)^2 sage: two 2.000000000000000? sage: two.exactify() sage: two 2
>>> from sage.all import * >>> two = QQbar(Integer(4)).nth_root(Integer(4))**Integer(2) >>> two 2.000000000000000? >>> two.exactify() >>> two 2
- interval(field)[source]#
Given an interval (or ball) field (real or complex, as appropriate) of precision \(p\), compute an interval representation of self with
diameter()
at most \(2^{-p}\); then round that representation into the given field. Herediameter()
is relative diameter for intervals not containing 0, and absolute diameter for intervals that do contain 0; thus, if the returned interval does not contain 0, it has at least \(p-1\) good bits.EXAMPLES:
sage: RIF64 = RealIntervalField(64) sage: x = AA(2).sqrt() sage: y = x*x sage: y = 1000 * y - 999 * y sage: y.interval_fast(RIF64) 2.000000000000000? sage: y.interval(RIF64) 2.000000000000000000? sage: CIF64 = ComplexIntervalField(64) sage: x = QQbar.zeta(11) sage: x.interval_fast(CIF64) 0.8412535328311811689? + 0.5406408174555975821?*I sage: x.interval(CIF64) 0.8412535328311811689? + 0.5406408174555975822?*I sage: x.interval(CBF) # abs tol 1e-16 [0.8412535328311812 +/- 3.12e-17] + [0.5406408174555976 +/- 1.79e-17]*I
>>> from sage.all import * >>> RIF64 = RealIntervalField(Integer(64)) >>> x = AA(Integer(2)).sqrt() >>> y = x*x >>> y = Integer(1000) * y - Integer(999) * y >>> y.interval_fast(RIF64) 2.000000000000000? >>> y.interval(RIF64) 2.000000000000000000? >>> CIF64 = ComplexIntervalField(Integer(64)) >>> x = QQbar.zeta(Integer(11)) >>> x.interval_fast(CIF64) 0.8412535328311811689? + 0.5406408174555975821?*I >>> x.interval(CIF64) 0.8412535328311811689? + 0.5406408174555975822?*I >>> x.interval(CBF) # abs tol 1e-16 [0.8412535328311812 +/- 3.12e-17] + [0.5406408174555976 +/- 1.79e-17]*I
The following implicitly use this method:
sage: RIF(AA(5).sqrt()) 2.236067977499790? sage: AA(-5).sqrt().interval(RIF) Traceback (most recent call last): ... TypeError: unable to convert 2.236067977499790?*I to real interval
>>> from sage.all import * >>> RIF(AA(Integer(5)).sqrt()) 2.236067977499790? >>> AA(-Integer(5)).sqrt().interval(RIF) Traceback (most recent call last): ... TypeError: unable to convert 2.236067977499790?*I to real interval
- interval_diameter(diam)[source]#
Compute an interval representation of self with
diameter()
at mostdiam
. The precision of the returned value is unpredictable.EXAMPLES:
sage: AA(2).sqrt().interval_diameter(1e-10) 1.4142135623730950488? sage: AA(2).sqrt().interval_diameter(1e-30) 1.41421356237309504880168872420969807857? sage: QQbar(2).sqrt().interval_diameter(1e-10) 1.4142135623730950488? sage: QQbar(2).sqrt().interval_diameter(1e-30) 1.41421356237309504880168872420969807857?
>>> from sage.all import * >>> AA(Integer(2)).sqrt().interval_diameter(RealNumber('1e-10')) 1.4142135623730950488? >>> AA(Integer(2)).sqrt().interval_diameter(RealNumber('1e-30')) 1.41421356237309504880168872420969807857? >>> QQbar(Integer(2)).sqrt().interval_diameter(RealNumber('1e-10')) 1.4142135623730950488? >>> QQbar(Integer(2)).sqrt().interval_diameter(RealNumber('1e-30')) 1.41421356237309504880168872420969807857?
- interval_fast(field)[source]#
Given a
RealIntervalField
orComplexIntervalField
, compute the value of this number using interval arithmetic of at least the precision of the field, and return the value in that field. (More precision may be used in the computation.) The returned interval may be arbitrarily imprecise, if this number is the result of a sufficiently long computation chain.EXAMPLES:
sage: x = AA(2).sqrt() sage: x.interval_fast(RIF) 1.414213562373095? sage: x.interval_fast(RealIntervalField(200)) 1.414213562373095048801688724209698078569671875376948073176680? sage: x = QQbar(I).sqrt() sage: x.interval_fast(CIF) 0.7071067811865475? + 0.7071067811865475?*I sage: x.interval_fast(RIF) Traceback (most recent call last): ... TypeError: unable to convert complex interval 0.7071067811865475244? + 0.7071067811865475244?*I to real interval
>>> from sage.all import * >>> x = AA(Integer(2)).sqrt() >>> x.interval_fast(RIF) 1.414213562373095? >>> x.interval_fast(RealIntervalField(Integer(200))) 1.414213562373095048801688724209698078569671875376948073176680? >>> x = QQbar(I).sqrt() >>> x.interval_fast(CIF) 0.7071067811865475? + 0.7071067811865475?*I >>> x.interval_fast(RIF) Traceback (most recent call last): ... TypeError: unable to convert complex interval 0.7071067811865475244? + 0.7071067811865475244?*I to real interval
- is_integer()[source]#
Return
True
if this number is a integer.EXAMPLES:
sage: QQbar(2).is_integer() True sage: QQbar(1/2).is_integer() False
>>> from sage.all import * >>> QQbar(Integer(2)).is_integer() True >>> QQbar(Integer(1)/Integer(2)).is_integer() False
- is_square()[source]#
Return whether or not this number is square.
OUTPUT:
(boolean)
True
in all cases for elements ofQQbar
;True
for non-negative elements ofAA
; otherwiseFalse
EXAMPLES:
sage: AA(2).is_square() True sage: AA(-2).is_square() False sage: QQbar(-2).is_square() True sage: QQbar(I).is_square() True
>>> from sage.all import * >>> AA(Integer(2)).is_square() True >>> AA(-Integer(2)).is_square() False >>> QQbar(-Integer(2)).is_square() True >>> QQbar(I).is_square() True
- minpoly()[source]#
Compute the minimal polynomial of this algebraic number. The minimal polynomial is the monic polynomial of least degree having this number as a root; it is unique.
EXAMPLES:
sage: QQbar(4).sqrt().minpoly() x - 2 sage: ((QQbar(2).nth_root(4))^2).minpoly() x^2 - 2 sage: v = sqrt(QQbar(2)) + sqrt(QQbar(3)); v 3.146264369941973? sage: p = v.minpoly(); p x^4 - 10*x^2 + 1 sage: p(RR(v.real())) 1.31006316905768e-14
>>> from sage.all import * >>> QQbar(Integer(4)).sqrt().minpoly() x - 2 >>> ((QQbar(Integer(2)).nth_root(Integer(4)))**Integer(2)).minpoly() x^2 - 2 >>> v = sqrt(QQbar(Integer(2))) + sqrt(QQbar(Integer(3))); v 3.146264369941973? >>> p = v.minpoly(); p x^4 - 10*x^2 + 1 >>> p(RR(v.real())) 1.31006316905768e-14
- nth_root(n, all=False)[source]#
Return the
n
-th root of this number.INPUT:
all
– bool (default:False
). IfTrue
, return a list of all \(n\)-th roots as complex algebraic numbers.
Warning
Note that for odd \(n\), all=`False` and negative real numbers,
AlgebraicReal
andAlgebraicNumber
values give different answers:AlgebraicReal
values prefer real results, andAlgebraicNumber
values return the principal root.EXAMPLES:
sage: AA(-8).nth_root(3) -2 sage: QQbar(-8).nth_root(3) 1.000000000000000? + 1.732050807568878?*I sage: QQbar.zeta(12).nth_root(15) 0.9993908270190957? + 0.03489949670250097?*I
>>> from sage.all import * >>> AA(-Integer(8)).nth_root(Integer(3)) -2 >>> QQbar(-Integer(8)).nth_root(Integer(3)) 1.000000000000000? + 1.732050807568878?*I >>> QQbar.zeta(Integer(12)).nth_root(Integer(15)) 0.9993908270190957? + 0.03489949670250097?*I
You can get all
n
-th roots of algebraic numbers:sage: AA(-8).nth_root(3, all=True) [1.000000000000000? + 1.732050807568878?*I, -2.000000000000000? + 0.?e-18*I, 1.000000000000000? - 1.732050807568878?*I] sage: QQbar(1+I).nth_root(4, all=True) [1.069553932363986? + 0.2127475047267431?*I, -0.2127475047267431? + 1.069553932363986?*I, -1.069553932363986? - 0.2127475047267431?*I, 0.2127475047267431? - 1.069553932363986?*I]
>>> from sage.all import * >>> AA(-Integer(8)).nth_root(Integer(3), all=True) [1.000000000000000? + 1.732050807568878?*I, -2.000000000000000? + 0.?e-18*I, 1.000000000000000? - 1.732050807568878?*I] >>> QQbar(Integer(1)+I).nth_root(Integer(4), all=True) [1.069553932363986? + 0.2127475047267431?*I, -0.2127475047267431? + 1.069553932363986?*I, -1.069553932363986? - 0.2127475047267431?*I, 0.2127475047267431? - 1.069553932363986?*I]
- radical_expression()[source]#
Attempt to obtain a symbolic expression using radicals. If no exact symbolic expression can be found, the algebraic number will be returned without modification.
EXAMPLES:
sage: # needs sage.symbolic sage: AA(1/sqrt(5)).radical_expression() sqrt(1/5) sage: AA(sqrt(5 + sqrt(5))).radical_expression() sqrt(sqrt(5) + 5) sage: QQbar.zeta(5).radical_expression() 1/4*sqrt(5) + 1/2*sqrt(-1/2*sqrt(5) - 5/2) - 1/4 sage: x = polygen(QQ, 'x') sage: a = (x^7 - x - 1).roots(AA, False)[0] sage: a.radical_expression() 1.112775684278706? sage: a.radical_expression().parent() == SR False sage: a = sorted((x^7-x-1).roots(QQbar, False), key=imag)[0] sage: a.radical_expression() -0.3636235193291805? - 0.9525611952610331?*I sage: QQbar.zeta(5).imag().radical_expression() 1/2*sqrt(1/2*sqrt(5) + 5/2) sage: AA(5/3).radical_expression() 5/3 sage: AA(5/3).radical_expression().parent() == SR True sage: QQbar(0).radical_expression() 0
>>> from sage.all import * >>> # needs sage.symbolic >>> AA(Integer(1)/sqrt(Integer(5))).radical_expression() sqrt(1/5) >>> AA(sqrt(Integer(5) + sqrt(Integer(5)))).radical_expression() sqrt(sqrt(5) + 5) >>> QQbar.zeta(Integer(5)).radical_expression() 1/4*sqrt(5) + 1/2*sqrt(-1/2*sqrt(5) - 5/2) - 1/4 >>> x = polygen(QQ, 'x') >>> a = (x**Integer(7) - x - Integer(1)).roots(AA, False)[Integer(0)] >>> a.radical_expression() 1.112775684278706? >>> a.radical_expression().parent() == SR False >>> a = sorted((x**Integer(7)-x-Integer(1)).roots(QQbar, False), key=imag)[Integer(0)] >>> a.radical_expression() -0.3636235193291805? - 0.9525611952610331?*I >>> QQbar.zeta(Integer(5)).imag().radical_expression() 1/2*sqrt(1/2*sqrt(5) + 5/2) >>> AA(Integer(5)/Integer(3)).radical_expression() 5/3 >>> AA(Integer(5)/Integer(3)).radical_expression().parent() == SR True >>> QQbar(Integer(0)).radical_expression() 0
- simplify()[source]#
Compute an exact representation for this number, in the smallest possible number field.
EXAMPLES:
sage: # needs sage.symbolic sage: rt2 = AA(sqrt(2)) sage: rt3 = AA(sqrt(3)) sage: rt2b = rt3 + rt2 - rt3 sage: rt2b.exactify() sage: rt2b._exact_value() a^3 - 3*a where a^4 - 4*a^2 + 1 = 0 and a in -0.5176380902050415? sage: rt2b.simplify() sage: rt2b._exact_value() a where a^2 - 2 = 0 and a in 1.414213562373095?
>>> from sage.all import * >>> # needs sage.symbolic >>> rt2 = AA(sqrt(Integer(2))) >>> rt3 = AA(sqrt(Integer(3))) >>> rt2b = rt3 + rt2 - rt3 >>> rt2b.exactify() >>> rt2b._exact_value() a^3 - 3*a where a^4 - 4*a^2 + 1 = 0 and a in -0.5176380902050415? >>> rt2b.simplify() >>> rt2b._exact_value() a where a^2 - 2 = 0 and a in 1.414213562373095?
- sqrt(all=False, extend=True)[source]#
Return the square root(s) of this number.
INPUT:
extend
– bool (default:True
); ignored if self is in QQbar, or positive in AA. If self is negative in AA, do the following: if True, return a square root of self in QQbar, otherwise raise a ValueError.all
– bool (default:False
); if True, return a list of all square roots. If False, return just one square root, or raise an ValueError if self is a negative element of AA and extend=False.
OUTPUT:
Either the principal square root of self, or a list of its square roots (with the principal one first).
EXAMPLES:
sage: AA(2).sqrt() 1.414213562373095? sage: QQbar(I).sqrt() 0.7071067811865475? + 0.7071067811865475?*I sage: QQbar(I).sqrt(all=True) [0.7071067811865475? + 0.7071067811865475?*I, -0.7071067811865475? - 0.7071067811865475?*I] sage: a = QQbar(0) sage: a.sqrt() 0 sage: a.sqrt(all=True) [0] sage: a = AA(0) sage: a.sqrt() 0 sage: a.sqrt(all=True) [0]
>>> from sage.all import * >>> AA(Integer(2)).sqrt() 1.414213562373095? >>> QQbar(I).sqrt() 0.7071067811865475? + 0.7071067811865475?*I >>> QQbar(I).sqrt(all=True) [0.7071067811865475? + 0.7071067811865475?*I, -0.7071067811865475? - 0.7071067811865475?*I] >>> a = QQbar(Integer(0)) >>> a.sqrt() 0 >>> a.sqrt(all=True) [0] >>> a = AA(Integer(0)) >>> a.sqrt() 0 >>> a.sqrt(all=True) [0]
This second example just shows that the program does not care where 0 is defined, it gives the same answer regardless. After all, how many ways can you square-root zero?
sage: AA(-2).sqrt() 1.414213562373095?*I sage: AA(-2).sqrt(all=True) [1.414213562373095?*I, -1.414213562373095?*I] sage: AA(-2).sqrt(extend=False) Traceback (most recent call last): ... ValueError: -2 is not a square in AA, being negative. Use extend = True for a square root in QQbar.
>>> from sage.all import * >>> AA(-Integer(2)).sqrt() 1.414213562373095?*I >>> AA(-Integer(2)).sqrt(all=True) [1.414213562373095?*I, -1.414213562373095?*I] >>> AA(-Integer(2)).sqrt(extend=False) Traceback (most recent call last): ... ValueError: -2 is not a square in AA, being negative. Use extend = True for a square root in QQbar.
- class sage.rings.qqbar.AlgebraicPolynomialTracker(poly)[source]#
Bases:
SageObject
Keeps track of a polynomial used for algebraic numbers.
If multiple algebraic numbers are created as roots of a single polynomial, this allows the polynomial and information about the polynomial to be shared. This reduces work if the polynomial must be recomputed at higher precision, or if it must be factored.
This class is private, and should only be constructed by
AA.common_polynomial()
orQQbar.common_polynomial()
, and should only be used as an argument toAA.polynomial_root()
orQQbar.polynomial_root()
. (It does not matter whether you create the common polynomial withAA.common_polynomial()
orQQbar.common_polynomial()
.)EXAMPLES:
sage: x = polygen(QQbar) sage: P = QQbar.common_polynomial(x^2 - x - 1) sage: P x^2 - x - 1 sage: QQbar.polynomial_root(P, RIF(1, 2)) 1.618033988749895?
>>> from sage.all import * >>> x = polygen(QQbar) >>> P = QQbar.common_polynomial(x**Integer(2) - x - Integer(1)) >>> P x^2 - x - 1 >>> QQbar.polynomial_root(P, RIF(Integer(1), Integer(2))) 1.618033988749895?
- complex_roots(prec, multiplicity)[source]#
Find the roots of
self
in the complex field to precisionprec
.EXAMPLES:
sage: x = polygen(ZZ) sage: cp = AA.common_polynomial(x^4 - 2)
>>> from sage.all import * >>> x = polygen(ZZ) >>> cp = AA.common_polynomial(x**Integer(4) - Integer(2))
Note that the precision is not guaranteed to find the tightest possible interval since
complex_roots()
depends on the underlying BLAS implementation.sage: cp.complex_roots(30, 1) [-1.18920711500272...?, 1.189207115002721?, -1.189207115002721?*I, 1.189207115002721?*I]
>>> from sage.all import * >>> cp.complex_roots(Integer(30), Integer(1)) [-1.18920711500272...?, 1.189207115002721?, -1.189207115002721?*I, 1.189207115002721?*I]
- exactify()[source]#
Compute a common field that holds all of the algebraic coefficients of this polynomial, then factor the polynomial over that field. Store the factors for later use (ignoring multiplicity).
EXAMPLES:
sage: x = polygen(AA) sage: p = sqrt(AA(2)) * x^2 - sqrt(AA(3)) sage: cp = AA.common_polynomial(p) sage: cp._exact False sage: cp.exactify() sage: cp._exact True
>>> from sage.all import * >>> x = polygen(AA) >>> p = sqrt(AA(Integer(2))) * x**Integer(2) - sqrt(AA(Integer(3))) >>> cp = AA.common_polynomial(p) >>> cp._exact False >>> cp.exactify() >>> cp._exact True
- factors()[source]#
EXAMPLES:
sage: x = polygen(QQ) sage: f = QQbar.common_polynomial(x^4 + 4) sage: f.factors() [y^2 - 2*y + 2, y^2 + 2*y + 2]
>>> from sage.all import * >>> x = polygen(QQ) >>> f = QQbar.common_polynomial(x**Integer(4) + Integer(4)) >>> f.factors() [y^2 - 2*y + 2, y^2 + 2*y + 2]
- generator()[source]#
Return an
AlgebraicGenerator
for a number field containing all the coefficients ofself
.EXAMPLES:
sage: x = polygen(AA) sage: p = sqrt(AA(2)) * x^2 - sqrt(AA(3)) sage: cp = AA.common_polynomial(p) sage: cp.generator() Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a in -0.5176380902050415?
>>> from sage.all import * >>> x = polygen(AA) >>> p = sqrt(AA(Integer(2))) * x**Integer(2) - sqrt(AA(Integer(3))) >>> cp = AA.common_polynomial(p) >>> cp.generator() Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a in -0.5176380902050415?
- is_complex()[source]#
Return
True
if the coefficients of this polynomial are non-real.EXAMPLES:
sage: x = polygen(QQ); f = x^3 - 7 sage: g = AA.common_polynomial(f) sage: g.is_complex() False sage: QQbar.common_polynomial(x^3 - QQbar(I)).is_complex() True
>>> from sage.all import * >>> x = polygen(QQ); f = x**Integer(3) - Integer(7) >>> g = AA.common_polynomial(f) >>> g.is_complex() False >>> QQbar.common_polynomial(x**Integer(3) - QQbar(I)).is_complex() True
- class sage.rings.qqbar.AlgebraicReal(x)[source]#
Bases:
AlgebraicNumber_base
A real algebraic number.
- _richcmp_(other, op)[source]#
Compare two algebraic reals.
EXAMPLES:
sage: AA(2).sqrt() < AA(3).sqrt() True sage: ((5+AA(5).sqrt())/2).sqrt() == 2*QQbar.zeta(5).imag() True sage: AA(3).sqrt() + AA(2).sqrt() < 3 False
>>> from sage.all import * >>> AA(Integer(2)).sqrt() < AA(Integer(3)).sqrt() True >>> ((Integer(5)+AA(Integer(5)).sqrt())/Integer(2)).sqrt() == Integer(2)*QQbar.zeta(Integer(5)).imag() True >>> AA(Integer(3)).sqrt() + AA(Integer(2)).sqrt() < Integer(3) False
- ceil()[source]#
Return the smallest integer not smaller than
self
.EXAMPLES:
sage: AA(sqrt(2)).ceil() # needs sage.symbolic 2 sage: AA(-sqrt(2)).ceil() # needs sage.symbolic -1 sage: AA(42).ceil() 42
>>> from sage.all import * >>> AA(sqrt(Integer(2))).ceil() # needs sage.symbolic 2 >>> AA(-sqrt(Integer(2))).ceil() # needs sage.symbolic -1 >>> AA(Integer(42)).ceil() 42
- conjugate()[source]#
Return the complex conjugate of
self
, i.e. returns itself.EXAMPLES:
sage: a = AA(sqrt(2) + sqrt(3)) # needs sage.symbolic sage: a.conjugate() # needs sage.symbolic 3.146264369941973? sage: a.conjugate() is a # needs sage.symbolic True
>>> from sage.all import * >>> a = AA(sqrt(Integer(2)) + sqrt(Integer(3))) # needs sage.symbolic >>> a.conjugate() # needs sage.symbolic 3.146264369941973? >>> a.conjugate() is a # needs sage.symbolic True
- floor()[source]#
Return the largest integer not greater than
self
.EXAMPLES:
sage: AA(sqrt(2)).floor() # needs sage.symbolic 1 sage: AA(-sqrt(2)).floor() # needs sage.symbolic -2 sage: AA(42).floor() 42
>>> from sage.all import * >>> AA(sqrt(Integer(2))).floor() # needs sage.symbolic 1 >>> AA(-sqrt(Integer(2))).floor() # needs sage.symbolic -2 >>> AA(Integer(42)).floor() 42
- imag()[source]#
Return the imaginary part of this algebraic real.
It always returns 0.
EXAMPLES:
sage: a = AA(sqrt(2) + sqrt(3)) # needs sage.symbolic sage: a.imag() # needs sage.symbolic 0 sage: parent(a.imag()) # needs sage.symbolic Algebraic Real Field
>>> from sage.all import * >>> a = AA(sqrt(Integer(2)) + sqrt(Integer(3))) # needs sage.symbolic >>> a.imag() # needs sage.symbolic 0 >>> parent(a.imag()) # needs sage.symbolic Algebraic Real Field
- interval_exact(field)[source]#
Given a
RealIntervalField
, compute the best possible approximation of this number in that field. Note that if this number is sufficiently close to some floating-point number (and, in particular, if this number is exactly representable in floating-point), then this will trigger exact computation, which may be very slow.EXAMPLES:
sage: x = AA(2).sqrt() sage: y = x*x sage: x.interval(RIF) 1.414213562373095? sage: x.interval_exact(RIF) 1.414213562373095? sage: y.interval(RIF) 2.000000000000000? sage: y.interval_exact(RIF) 2 sage: z = 1 + AA(2).sqrt() / 2^200 sage: z.interval(RIF) 1.000000000000001? sage: z.interval_exact(RIF) 1.000000000000001?
>>> from sage.all import * >>> x = AA(Integer(2)).sqrt() >>> y = x*x >>> x.interval(RIF) 1.414213562373095? >>> x.interval_exact(RIF) 1.414213562373095? >>> y.interval(RIF) 2.000000000000000? >>> y.interval_exact(RIF) 2 >>> z = Integer(1) + AA(Integer(2)).sqrt() / Integer(2)**Integer(200) >>> z.interval(RIF) 1.000000000000001? >>> z.interval_exact(RIF) 1.000000000000001?
- multiplicative_order()[source]#
Compute the multiplicative order of this real algebraic number.
That is, find the smallest positive integer \(n\) such that \(x^n = 1\). If there is no such \(n\), returns
+Infinity
.We first check that
abs(x)
is very close to 1. If so, we compute \(x\) exactly and compare it to \(1\) and \(-1\).EXAMPLES:
sage: AA(1).multiplicative_order() 1 sage: AA(-1).multiplicative_order() 2 sage: AA(5).sqrt().multiplicative_order() +Infinity
>>> from sage.all import * >>> AA(Integer(1)).multiplicative_order() 1 >>> AA(-Integer(1)).multiplicative_order() 2 >>> AA(Integer(5)).sqrt().multiplicative_order() +Infinity
- real()[source]#
Return the real part of this algebraic real.
It always returns
self
.EXAMPLES:
sage: a = AA(sqrt(2) + sqrt(3)) # needs sage.symbolic sage: a.real() # needs sage.symbolic 3.146264369941973? sage: a.real() is a # needs sage.symbolic True
>>> from sage.all import * >>> a = AA(sqrt(Integer(2)) + sqrt(Integer(3))) # needs sage.symbolic >>> a.real() # needs sage.symbolic 3.146264369941973? >>> a.real() is a # needs sage.symbolic True
- real_exact(field)[source]#
Given a
RealField
, compute the best possible approximation of this number in that field. Note that if this number is sufficiently close to the halfway point between two floating-point numbers in the field (for the default round-to-nearest mode) or if the number is sufficiently close to a floating-point number in the field (for directed rounding modes), then this will trigger exact computation, which may be very slow.The rounding mode of the field is respected.
EXAMPLES:
sage: x = AA(2).sqrt()^2 sage: x.real_exact(RR) 2.00000000000000 sage: x.real_exact(RealField(53, rnd='RNDD')) 2.00000000000000 sage: x.real_exact(RealField(53, rnd='RNDU')) 2.00000000000000 sage: x.real_exact(RealField(53, rnd='RNDZ')) 2.00000000000000 sage: (-x).real_exact(RR) -2.00000000000000 sage: (-x).real_exact(RealField(53, rnd='RNDD')) -2.00000000000000 sage: (-x).real_exact(RealField(53, rnd='RNDU')) -2.00000000000000 sage: (-x).real_exact(RealField(53, rnd='RNDZ')) -2.00000000000000 sage: y = (x-2).real_exact(RR).abs() sage: y == 0.0 or y == -0.0 # the sign of 0.0 is not significant in MPFI True sage: y = (x-2).real_exact(RealField(53, rnd='RNDD')) sage: y == 0.0 or y == -0.0 # same as above True sage: y = (x-2).real_exact(RealField(53, rnd='RNDU')) sage: y == 0.0 or y == -0.0 # idem True sage: y = (x-2).real_exact(RealField(53, rnd='RNDZ')) sage: y == 0.0 or y == -0.0 # ibidem True sage: y = AA(2).sqrt() sage: y.real_exact(RR) 1.41421356237310 sage: y.real_exact(RealField(53, rnd='RNDD')) 1.41421356237309 sage: y.real_exact(RealField(53, rnd='RNDU')) 1.41421356237310 sage: y.real_exact(RealField(53, rnd='RNDZ')) 1.41421356237309
>>> from sage.all import * >>> x = AA(Integer(2)).sqrt()**Integer(2) >>> x.real_exact(RR) 2.00000000000000 >>> x.real_exact(RealField(Integer(53), rnd='RNDD')) 2.00000000000000 >>> x.real_exact(RealField(Integer(53), rnd='RNDU')) 2.00000000000000 >>> x.real_exact(RealField(Integer(53), rnd='RNDZ')) 2.00000000000000 >>> (-x).real_exact(RR) -2.00000000000000 >>> (-x).real_exact(RealField(Integer(53), rnd='RNDD')) -2.00000000000000 >>> (-x).real_exact(RealField(Integer(53), rnd='RNDU')) -2.00000000000000 >>> (-x).real_exact(RealField(Integer(53), rnd='RNDZ')) -2.00000000000000 >>> y = (x-Integer(2)).real_exact(RR).abs() >>> y == RealNumber('0.0') or y == -RealNumber('0.0') # the sign of 0.0 is not significant in MPFI True >>> y = (x-Integer(2)).real_exact(RealField(Integer(53), rnd='RNDD')) >>> y == RealNumber('0.0') or y == -RealNumber('0.0') # same as above True >>> y = (x-Integer(2)).real_exact(RealField(Integer(53), rnd='RNDU')) >>> y == RealNumber('0.0') or y == -RealNumber('0.0') # idem True >>> y = (x-Integer(2)).real_exact(RealField(Integer(53), rnd='RNDZ')) >>> y == RealNumber('0.0') or y == -RealNumber('0.0') # ibidem True >>> y = AA(Integer(2)).sqrt() >>> y.real_exact(RR) 1.41421356237310 >>> y.real_exact(RealField(Integer(53), rnd='RNDD')) 1.41421356237309 >>> y.real_exact(RealField(Integer(53), rnd='RNDU')) 1.41421356237310 >>> y.real_exact(RealField(Integer(53), rnd='RNDZ')) 1.41421356237309
- real_number(field)[source]#
Given a
RealField
, compute a good approximation toself
in that field. The approximation will be off by at most two ulp’s, except for numbers which are very close to 0, which will have an absolute error at most2**(-(field.prec()-1))
. Also, the rounding mode of the field is respected.EXAMPLES:
sage: x = AA(2).sqrt()^2 sage: x.real_number(RR) 2.00000000000000 sage: x.real_number(RealField(53, rnd='RNDD')) 1.99999999999999 sage: x.real_number(RealField(53, rnd='RNDU')) 2.00000000000001 sage: x.real_number(RealField(53, rnd='RNDZ')) 1.99999999999999 sage: (-x).real_number(RR) -2.00000000000000 sage: (-x).real_number(RealField(53, rnd='RNDD')) -2.00000000000001 sage: (-x).real_number(RealField(53, rnd='RNDU')) -1.99999999999999 sage: (-x).real_number(RealField(53, rnd='RNDZ')) -1.99999999999999 sage: (x-2).real_number(RR) 5.42101086242752e-20 sage: (x-2).real_number(RealField(53, rnd='RNDD')) -1.08420217248551e-19 sage: (x-2).real_number(RealField(53, rnd='RNDU')) 2.16840434497101e-19 sage: (x-2).real_number(RealField(53, rnd='RNDZ')) 0.000000000000000 sage: y = AA(2).sqrt() sage: y.real_number(RR) 1.41421356237309 sage: y.real_number(RealField(53, rnd='RNDD')) 1.41421356237309 sage: y.real_number(RealField(53, rnd='RNDU')) 1.41421356237310 sage: y.real_number(RealField(53, rnd='RNDZ')) 1.41421356237309
>>> from sage.all import * >>> x = AA(Integer(2)).sqrt()**Integer(2) >>> x.real_number(RR) 2.00000000000000 >>> x.real_number(RealField(Integer(53), rnd='RNDD')) 1.99999999999999 >>> x.real_number(RealField(Integer(53), rnd='RNDU')) 2.00000000000001 >>> x.real_number(RealField(Integer(53), rnd='RNDZ')) 1.99999999999999 >>> (-x).real_number(RR) -2.00000000000000 >>> (-x).real_number(RealField(Integer(53), rnd='RNDD')) -2.00000000000001 >>> (-x).real_number(RealField(Integer(53), rnd='RNDU')) -1.99999999999999 >>> (-x).real_number(RealField(Integer(53), rnd='RNDZ')) -1.99999999999999 >>> (x-Integer(2)).real_number(RR) 5.42101086242752e-20 >>> (x-Integer(2)).real_number(RealField(Integer(53), rnd='RNDD')) -1.08420217248551e-19 >>> (x-Integer(2)).real_number(RealField(Integer(53), rnd='RNDU')) 2.16840434497101e-19 >>> (x-Integer(2)).real_number(RealField(Integer(53), rnd='RNDZ')) 0.000000000000000 >>> y = AA(Integer(2)).sqrt() >>> y.real_number(RR) 1.41421356237309 >>> y.real_number(RealField(Integer(53), rnd='RNDD')) 1.41421356237309 >>> y.real_number(RealField(Integer(53), rnd='RNDU')) 1.41421356237310 >>> y.real_number(RealField(Integer(53), rnd='RNDZ')) 1.41421356237309
- round()[source]#
Round
self
to the nearest integer.EXAMPLES:
sage: AA(sqrt(2)).round() # needs sage.symbolic 1 sage: AA(1/2).round() 1 sage: AA(-1/2).round() -1
>>> from sage.all import * >>> AA(sqrt(Integer(2))).round() # needs sage.symbolic 1 >>> AA(Integer(1)/Integer(2)).round() 1 >>> AA(-Integer(1)/Integer(2)).round() -1
- sign()[source]#
Compute the sign of this algebraic number (return \(-1\) if negative, \(0\) if zero, or \(1\) if positive).
This computes an interval enclosing this number using 128-bit interval arithmetic; if this interval includes 0, then fall back to exact computation (which can be very slow).
EXAMPLES:
sage: AA(-5).nth_root(7).sign() -1 sage: (AA(2).sqrt() - AA(2).sqrt()).sign() 0 sage: a = AA(2).sqrt() + AA(3).sqrt() - 58114382797550084497/18470915334626475921 sage: a.sign() 1 sage: b = AA(2).sqrt() + AA(3).sqrt() - 2602510228533039296408/827174681630786895911 sage: b.sign() -1 sage: c = AA(5)**(1/3) - 1437624125539676934786/840727688792155114277 sage: c.sign() 1 sage: (((a+b)*(a+c)*(b+c))**9 / (a*b*c)).sign() 1 sage: (a-b).sign() 1 sage: (b-a).sign() -1 sage: (a*b).sign() -1 sage: ((a*b).abs() + a).sign() 1 sage: (a*b - b*a).sign() 0 sage: a = AA(sqrt(1/2)) # needs sage.symbolic sage: b = AA(-sqrt(1/2)) # needs sage.symbolic sage: (a + b).sign() # needs sage.symbolic 0
>>> from sage.all import * >>> AA(-Integer(5)).nth_root(Integer(7)).sign() -1 >>> (AA(Integer(2)).sqrt() - AA(Integer(2)).sqrt()).sign() 0 >>> a = AA(Integer(2)).sqrt() + AA(Integer(3)).sqrt() - Integer(58114382797550084497)/Integer(18470915334626475921) >>> a.sign() 1 >>> b = AA(Integer(2)).sqrt() + AA(Integer(3)).sqrt() - Integer(2602510228533039296408)/Integer(827174681630786895911) >>> b.sign() -1 >>> c = AA(Integer(5))**(Integer(1)/Integer(3)) - Integer(1437624125539676934786)/Integer(840727688792155114277) >>> c.sign() 1 >>> (((a+b)*(a+c)*(b+c))**Integer(9) / (a*b*c)).sign() 1 >>> (a-b).sign() 1 >>> (b-a).sign() -1 >>> (a*b).sign() -1 >>> ((a*b).abs() + a).sign() 1 >>> (a*b - b*a).sign() 0 >>> a = AA(sqrt(Integer(1)/Integer(2))) # needs sage.symbolic >>> b = AA(-sqrt(Integer(1)/Integer(2))) # needs sage.symbolic >>> (a + b).sign() # needs sage.symbolic 0
- trunc()[source]#
Round
self
to the nearest integer toward zero.EXAMPLES:
sage: AA(sqrt(2)).trunc() # needs sage.symbolic 1 sage: AA(-sqrt(2)).trunc() # needs sage.symbolic -1 sage: AA(1).trunc() 1 sage: AA(-1).trunc() -1
>>> from sage.all import * >>> AA(sqrt(Integer(2))).trunc() # needs sage.symbolic 1 >>> AA(-sqrt(Integer(2))).trunc() # needs sage.symbolic -1 >>> AA(Integer(1)).trunc() 1 >>> AA(-Integer(1)).trunc() -1
- class sage.rings.qqbar.AlgebraicRealField[source]#
Bases:
Singleton
,AlgebraicField_common
,AlgebraicRealField
The field of algebraic reals.
- algebraic_closure()[source]#
Return the algebraic closure of this field, which is the field \(\overline{\QQ}\) of algebraic numbers.
EXAMPLES:
sage: AA.algebraic_closure() Algebraic Field
>>> from sage.all import * >>> AA.algebraic_closure() Algebraic Field
- completion(p, prec, extras={})[source]#
Return the completion of
self
at the place \(p\).Only implemented for \(p = \infty\) at present.
INPUT:
p
– either a prime (not implemented at present) orInfinity
prec
– precision of approximate field to returnextras
– (optional) a dict of extra keyword arguments for theRealField
constructor
EXAMPLES:
sage: AA.completion(infinity, 500) Real Field with 500 bits of precision sage: AA.completion(infinity, prec=53, extras={'type':'RDF'}) Real Double Field sage: AA.completion(infinity, 53) is RR True sage: AA.completion(7, 10) Traceback (most recent call last): ... NotImplementedError
>>> from sage.all import * >>> AA.completion(infinity, Integer(500)) Real Field with 500 bits of precision >>> AA.completion(infinity, prec=Integer(53), extras={'type':'RDF'}) Real Double Field >>> AA.completion(infinity, Integer(53)) is RR True >>> AA.completion(Integer(7), Integer(10)) Traceback (most recent call last): ... NotImplementedError
- gen(n=0)[source]#
Return the \(n\)-th element of the tuple returned by
gens()
.EXAMPLES:
sage: AA.gen(0) 1 sage: AA.gen(1) Traceback (most recent call last): ... IndexError: n must be 0
>>> from sage.all import * >>> AA.gen(Integer(0)) 1 >>> AA.gen(Integer(1)) Traceback (most recent call last): ... IndexError: n must be 0
- gens()[source]#
Return a set of generators for this field.
As this field is not finitely generated, we opt for just returning 1.
EXAMPLES:
sage: AA.gens() (1,)
>>> from sage.all import * >>> AA.gens() (1,)
- ngens()[source]#
Return the size of the tuple returned by
gens()
.EXAMPLES:
sage: AA.ngens() 1
>>> from sage.all import * >>> AA.ngens() 1
- polynomial_root(poly, interval, multiplicity=1)[source]#
Given a polynomial with algebraic coefficients and an interval enclosing exactly one root of the polynomial, constructs an algebraic real representation of that root.
The polynomial need not be irreducible, or even squarefree; but if the given root is a multiple root, its multiplicity must be specified. (IMPORTANT NOTE: Currently, multiplicity-\(k\) roots are handled by taking the \((k-1)\)-st derivative of the polynomial. This means that the interval must enclose exactly one root of this derivative.)
The conditions on the arguments (that the interval encloses exactly one root, and that multiple roots match the given multiplicity) are not checked; if they are not satisfied, an error may be thrown (possibly later, when the algebraic number is used), or wrong answers may result.
Note that if you are constructing multiple roots of a single polynomial, it is better to use
AA.common_polynomial
(orQQbar.common_polynomial
; the two are equivalent) to get a shared polynomial.EXAMPLES:
sage: x = polygen(AA) sage: phi = AA.polynomial_root(x^2 - x - 1, RIF(1, 2)); phi 1.618033988749895? sage: p = (x-1)^7 * (x-2) sage: r = AA.polynomial_root(p, RIF(9/10, 11/10), multiplicity=7) sage: r; r == 1 1.000000000000000? True sage: p = (x-phi)*(x-sqrt(AA(2))) sage: r = AA.polynomial_root(p, RIF(1, 3/2)) sage: r; r == sqrt(AA(2)) 1.414213562373095? True
>>> from sage.all import * >>> x = polygen(AA) >>> phi = AA.polynomial_root(x**Integer(2) - x - Integer(1), RIF(Integer(1), Integer(2))); phi 1.618033988749895? >>> p = (x-Integer(1))**Integer(7) * (x-Integer(2)) >>> r = AA.polynomial_root(p, RIF(Integer(9)/Integer(10), Integer(11)/Integer(10)), multiplicity=Integer(7)) >>> r; r == Integer(1) 1.000000000000000? True >>> p = (x-phi)*(x-sqrt(AA(Integer(2)))) >>> r = AA.polynomial_root(p, RIF(Integer(1), Integer(3)/Integer(2))) >>> r; r == sqrt(AA(Integer(2))) 1.414213562373095? True
We allow complex polynomials, as long as the particular root in question is real.
sage: K.<im> = QQ[I] sage: x = polygen(K) sage: p = (im + 1) * (x^3 - 2); p (I + 1)*x^3 - 2*I - 2 sage: r = AA.polynomial_root(p, RIF(1, 2)); r^3 2.000000000000000?
>>> from sage.all import * >>> K = QQ[I]; (im,) = K._first_ngens(1) >>> x = polygen(K) >>> p = (im + Integer(1)) * (x**Integer(3) - Integer(2)); p (I + 1)*x^3 - 2*I - 2 >>> r = AA.polynomial_root(p, RIF(Integer(1), Integer(2))); r**Integer(3) 2.000000000000000?
- random_element(poly_degree=2, *args, **kwds)[source]#
Return a random algebraic real number.
INPUT:
poly_degree
– default: 2; degree of the random polynomial over the integers of which the returned algebraic real number is a (real part of a) root. This is not necessarily the degree of the minimal polynomial of the number. Increase this parameter to achieve a greater diversity of algebraic numbers, at a cost of greater computation time. You can also vary the distribution of the coefficients but that will not vary the degree of the extension containing the element.args
,kwds
– arguments and keywords passed to the random number generator for elements ofZZ
, the integers. Seerandom_element()
for details, or see example below.
OUTPUT:
An element of
AA
, the field of algebraic real numbers (seesage.rings.qqbar
).ALGORITHM:
We pass all arguments to
AlgebraicField.random_element()
, and then take the real part of the result.EXAMPLES:
sage: a = AA.random_element() sage: a in AA True
>>> from sage.all import * >>> a = AA.random_element() >>> a in AA True
sage: b = AA.random_element(poly_degree=5) sage: b in AA True
>>> from sage.all import * >>> b = AA.random_element(poly_degree=Integer(5)) >>> b in AA True
Parameters for the distribution of the integer coefficients of the polynomials can be passed on to the random element method for integers. For example, we can rule out zero as a coefficient (and therefore as a root) by requesting coefficients between
1
and10
:sage: z = [AA.random_element(x=1, y=10) for _ in range(5)] sage: AA(0) in z False
>>> from sage.all import * >>> z = [AA.random_element(x=Integer(1), y=Integer(10)) for _ in range(Integer(5))] >>> AA(Integer(0)) in z False
- zeta(n=2)[source]#
Return an \(n\)-th root of unity in this field. This will raise a
ValueError
if \(n \ne \{1, 2\}\) since no such root exists.INPUT:
n
(integer) – default 2
EXAMPLES:
sage: AA.zeta(1) 1 sage: AA.zeta(2) -1 sage: AA.zeta() -1 sage: AA.zeta(3) Traceback (most recent call last): ... ValueError: no n-th root of unity in algebraic reals
>>> from sage.all import * >>> AA.zeta(Integer(1)) 1 >>> AA.zeta(Integer(2)) -1 >>> AA.zeta() -1 >>> AA.zeta(Integer(3)) Traceback (most recent call last): ... ValueError: no n-th root of unity in algebraic reals
Some silly inputs:
sage: AA.zeta(Mod(-5, 7)) -1 sage: AA.zeta(0) Traceback (most recent call last): ... ValueError: no n-th root of unity in algebraic reals
>>> from sage.all import * >>> AA.zeta(Mod(-Integer(5), Integer(7))) -1 >>> AA.zeta(Integer(0)) Traceback (most recent call last): ... ValueError: no n-th root of unity in algebraic reals
- sage.rings.qqbar.an_binop_element(a, b, op)[source]#
Add, subtract, multiply or divide two elements represented as elements of number fields.
EXAMPLES:
sage: sqrt2 = QQbar(2).sqrt() sage: sqrt3 = QQbar(3).sqrt() sage: sqrt5 = QQbar(5).sqrt() sage: a = sqrt2 + sqrt3; a.exactify() sage: b = sqrt3 + sqrt5; b.exactify() sage: type(a._descr) <class 'sage.rings.qqbar.ANExtensionElement'> sage: from sage.rings.qqbar import an_binop_element sage: an_binop_element(a, b, operator.add) <sage.rings.qqbar.ANBinaryExpr object at ...> sage: an_binop_element(a, b, operator.sub) <sage.rings.qqbar.ANBinaryExpr object at ...> sage: an_binop_element(a, b, operator.mul) <sage.rings.qqbar.ANBinaryExpr object at ...> sage: an_binop_element(a, b, operator.truediv) <sage.rings.qqbar.ANBinaryExpr object at ...>
>>> from sage.all import * >>> sqrt2 = QQbar(Integer(2)).sqrt() >>> sqrt3 = QQbar(Integer(3)).sqrt() >>> sqrt5 = QQbar(Integer(5)).sqrt() >>> a = sqrt2 + sqrt3; a.exactify() >>> b = sqrt3 + sqrt5; b.exactify() >>> type(a._descr) <class 'sage.rings.qqbar.ANExtensionElement'> >>> from sage.rings.qqbar import an_binop_element >>> an_binop_element(a, b, operator.add) <sage.rings.qqbar.ANBinaryExpr object at ...> >>> an_binop_element(a, b, operator.sub) <sage.rings.qqbar.ANBinaryExpr object at ...> >>> an_binop_element(a, b, operator.mul) <sage.rings.qqbar.ANBinaryExpr object at ...> >>> an_binop_element(a, b, operator.truediv) <sage.rings.qqbar.ANBinaryExpr object at ...>
The code tries to use existing unions of number fields:
sage: sqrt17 = QQbar(17).sqrt() sage: sqrt19 = QQbar(19).sqrt() sage: a = sqrt17 + sqrt19 sage: b = sqrt17 * sqrt19 - sqrt17 + sqrt19 * (sqrt17 + 2) sage: b, type(b._descr) (40.53909377268655?, <class 'sage.rings.qqbar.ANBinaryExpr'>) sage: a.exactify() sage: b = sqrt17 * sqrt19 - sqrt17 + sqrt19 * (sqrt17 + 2) sage: b, type(b._descr) (40.53909377268655?, <class 'sage.rings.qqbar.ANExtensionElement'>)
>>> from sage.all import * >>> sqrt17 = QQbar(Integer(17)).sqrt() >>> sqrt19 = QQbar(Integer(19)).sqrt() >>> a = sqrt17 + sqrt19 >>> b = sqrt17 * sqrt19 - sqrt17 + sqrt19 * (sqrt17 + Integer(2)) >>> b, type(b._descr) (40.53909377268655?, <class 'sage.rings.qqbar.ANBinaryExpr'>) >>> a.exactify() >>> b = sqrt17 * sqrt19 - sqrt17 + sqrt19 * (sqrt17 + Integer(2)) >>> b, type(b._descr) (40.53909377268655?, <class 'sage.rings.qqbar.ANExtensionElement'>)
- sage.rings.qqbar.an_binop_expr(a, b, op)[source]#
Add, subtract, multiply or divide algebraic numbers represented as binary expressions.
INPUT:
a
,b
– two elementsop
– an operator
EXAMPLES:
sage: # needs sage.symbolic sage: a = QQbar(sqrt(2)) + QQbar(sqrt(3)) sage: b = QQbar(sqrt(3)) + QQbar(sqrt(5)) sage: type(a._descr); type(b._descr) <class 'sage.rings.qqbar.ANBinaryExpr'> <class 'sage.rings.qqbar.ANBinaryExpr'> sage: from sage.rings.qqbar import an_binop_expr sage: x = an_binop_expr(a, b, operator.add); x <sage.rings.qqbar.ANBinaryExpr object at ...> sage: x.exactify() 6/7*a^7 - 2/7*a^6 - 71/7*a^5 + 26/7*a^4 + 125/7*a^3 - 72/7*a^2 - 43/7*a + 47/7 where a^8 - 12*a^6 + 23*a^4 - 12*a^2 + 1 = 0 and a in -0.3199179336182997? sage: # needs sage.symbolic sage: a = QQbar(sqrt(2)) + QQbar(sqrt(3)) sage: b = QQbar(sqrt(3)) + QQbar(sqrt(5)) sage: type(a._descr) <class 'sage.rings.qqbar.ANBinaryExpr'> sage: x = an_binop_expr(a, b, operator.mul); x <sage.rings.qqbar.ANBinaryExpr object at ...> sage: x.exactify() 2*a^7 - a^6 - 24*a^5 + 12*a^4 + 46*a^3 - 22*a^2 - 22*a + 9 where a^8 - 12*a^6 + 23*a^4 - 12*a^2 + 1 = 0 and a in -0.3199179336182997?
>>> from sage.all import * >>> # needs sage.symbolic >>> a = QQbar(sqrt(Integer(2))) + QQbar(sqrt(Integer(3))) >>> b = QQbar(sqrt(Integer(3))) + QQbar(sqrt(Integer(5))) >>> type(a._descr); type(b._descr) <class 'sage.rings.qqbar.ANBinaryExpr'> <class 'sage.rings.qqbar.ANBinaryExpr'> >>> from sage.rings.qqbar import an_binop_expr >>> x = an_binop_expr(a, b, operator.add); x <sage.rings.qqbar.ANBinaryExpr object at ...> >>> x.exactify() 6/7*a^7 - 2/7*a^6 - 71/7*a^5 + 26/7*a^4 + 125/7*a^3 - 72/7*a^2 - 43/7*a + 47/7 where a^8 - 12*a^6 + 23*a^4 - 12*a^2 + 1 = 0 and a in -0.3199179336182997? >>> # needs sage.symbolic >>> a = QQbar(sqrt(Integer(2))) + QQbar(sqrt(Integer(3))) >>> b = QQbar(sqrt(Integer(3))) + QQbar(sqrt(Integer(5))) >>> type(a._descr) <class 'sage.rings.qqbar.ANBinaryExpr'> >>> x = an_binop_expr(a, b, operator.mul); x <sage.rings.qqbar.ANBinaryExpr object at ...> >>> x.exactify() 2*a^7 - a^6 - 24*a^5 + 12*a^4 + 46*a^3 - 22*a^2 - 22*a + 9 where a^8 - 12*a^6 + 23*a^4 - 12*a^2 + 1 = 0 and a in -0.3199179336182997?
- sage.rings.qqbar.an_binop_rational(a, b, op)[source]#
Used to add, subtract, multiply or divide algebraic numbers.
Used when both are actually rational.
EXAMPLES:
sage: from sage.rings.qqbar import an_binop_rational sage: f = an_binop_rational(QQbar(2), QQbar(3/7), operator.add) sage: f 17/7 sage: type(f) <class 'sage.rings.qqbar.ANRational'> sage: f = an_binop_rational(QQbar(2), QQbar(3/7), operator.mul) sage: f 6/7 sage: type(f) <class 'sage.rings.qqbar.ANRational'>
>>> from sage.all import * >>> from sage.rings.qqbar import an_binop_rational >>> f = an_binop_rational(QQbar(Integer(2)), QQbar(Integer(3)/Integer(7)), operator.add) >>> f 17/7 >>> type(f) <class 'sage.rings.qqbar.ANRational'> >>> f = an_binop_rational(QQbar(Integer(2)), QQbar(Integer(3)/Integer(7)), operator.mul) >>> f 6/7 >>> type(f) <class 'sage.rings.qqbar.ANRational'>
- sage.rings.qqbar.clear_denominators(poly)[source]#
Take a monic polynomial and rescale the variable to get a monic polynomial with “integral” coefficients.
This works on any univariate polynomial whose base ring has a
denominator()
method that returns integers; for example, the base ring might be \(\QQ\) or a number field.Returns the scale factor and the new polynomial.
(Inspired by pari:primitive_pol_to_monic .)
We assume that coefficient denominators are “small”; the algorithm factors the denominators, to give the smallest possible scale factor.
EXAMPLES:
sage: from sage.rings.qqbar import clear_denominators sage: _.<x> = QQ['x'] sage: clear_denominators(x + 3/2) (2, x + 3) sage: clear_denominators(x^2 + x/2 + 1/4) (2, x^2 + x + 1)
>>> from sage.all import * >>> from sage.rings.qqbar import clear_denominators >>> _ = QQ['x']; (x,) = _._first_ngens(1) >>> clear_denominators(x + Integer(3)/Integer(2)) (2, x + 3) >>> clear_denominators(x**Integer(2) + x/Integer(2) + Integer(1)/Integer(4)) (2, x^2 + x + 1)
- sage.rings.qqbar.cmp_elements_with_same_minpoly(a, b, p)[source]#
Compare the algebraic elements
a
andb
knowing that they have the same minimal polynomialp
.This is a helper function for comparison of algebraic elements (i.e. the methods
AlgebraicNumber._richcmp_()
andAlgebraicReal._richcmp_()
).INPUT:
a
andb
– elements of the algebraic or the real algebraic field with same minimal polynomialp
– the minimal polynomial
OUTPUT:
\(-1\), \(0\), \(1\), \(None\) depending on whether \(a < b\), \(a = b\) or \(a > b\) or the function did not succeed with the given precision of \(a\) and \(b\).
EXAMPLES:
sage: from sage.rings.qqbar import cmp_elements_with_same_minpoly sage: x = polygen(ZZ) sage: p = x^2 - 2 sage: a = AA.polynomial_root(p, RIF(1,2)) sage: b = AA.polynomial_root(p, RIF(-2,-1)) sage: cmp_elements_with_same_minpoly(a, b, p) 1 sage: cmp_elements_with_same_minpoly(-a, b, p) 0
>>> from sage.all import * >>> from sage.rings.qqbar import cmp_elements_with_same_minpoly >>> x = polygen(ZZ) >>> p = x**Integer(2) - Integer(2) >>> a = AA.polynomial_root(p, RIF(Integer(1),Integer(2))) >>> b = AA.polynomial_root(p, RIF(-Integer(2),-Integer(1))) >>> cmp_elements_with_same_minpoly(a, b, p) 1 >>> cmp_elements_with_same_minpoly(-a, b, p) 0
- sage.rings.qqbar.conjugate_expand(v)[source]#
If the interval
v
(which may be real or complex) includes some purely real numbers, returnv'
containingv
such thatv' == v'.conjugate()
. Otherwise returnv
unchanged. (Note that ifv' == v'.conjugate()
, andv'
includes one non-real root of a real polynomial, thenv'
also includes the conjugate of that root. Also note that the diameter of the return value is at most twice the diameter of the input.)EXAMPLES:
sage: from sage.rings.qqbar import conjugate_expand sage: conjugate_expand(CIF(RIF(0, 1), RIF(1, 2))).str(style='brackets') '[0.0000000000000000 .. 1.0000000000000000] + [1.0000000000000000 .. 2.0000000000000000]*I' sage: conjugate_expand(CIF(RIF(0, 1), RIF(0, 1))).str(style='brackets') '[0.0000000000000000 .. 1.0000000000000000] + [-1.0000000000000000 .. 1.0000000000000000]*I' sage: conjugate_expand(CIF(RIF(0, 1), RIF(-2, 1))).str(style='brackets') '[0.0000000000000000 .. 1.0000000000000000] + [-2.0000000000000000 .. 2.0000000000000000]*I' sage: conjugate_expand(RIF(1, 2)).str(style='brackets') '[1.0000000000000000 .. 2.0000000000000000]'
>>> from sage.all import * >>> from sage.rings.qqbar import conjugate_expand >>> conjugate_expand(CIF(RIF(Integer(0), Integer(1)), RIF(Integer(1), Integer(2)))).str(style='brackets') '[0.0000000000000000 .. 1.0000000000000000] + [1.0000000000000000 .. 2.0000000000000000]*I' >>> conjugate_expand(CIF(RIF(Integer(0), Integer(1)), RIF(Integer(0), Integer(1)))).str(style='brackets') '[0.0000000000000000 .. 1.0000000000000000] + [-1.0000000000000000 .. 1.0000000000000000]*I' >>> conjugate_expand(CIF(RIF(Integer(0), Integer(1)), RIF(-Integer(2), Integer(1)))).str(style='brackets') '[0.0000000000000000 .. 1.0000000000000000] + [-2.0000000000000000 .. 2.0000000000000000]*I' >>> conjugate_expand(RIF(Integer(1), Integer(2))).str(style='brackets') '[1.0000000000000000 .. 2.0000000000000000]'
- sage.rings.qqbar.conjugate_shrink(v)[source]#
If the interval
v
includes some purely real numbers, return a real interval containing only those real numbers. Otherwise returnv
unchanged.If
v
includes exactly one root of a real polynomial, andv
was returned byconjugate_expand()
, thenconjugate_shrink(v)
still includes that root, and is aRealIntervalFieldElement
iff the root in question is real.EXAMPLES:
sage: from sage.rings.qqbar import conjugate_shrink sage: conjugate_shrink(RIF(3, 4)).str(style='brackets') '[3.0000000000000000 .. 4.0000000000000000]' sage: conjugate_shrink(CIF(RIF(1, 2), RIF(1, 2))).str(style='brackets') '[1.0000000000000000 .. 2.0000000000000000] + [1.0000000000000000 .. 2.0000000000000000]*I' sage: conjugate_shrink(CIF(RIF(1, 2), RIF(0, 1))).str(style='brackets') '[1.0000000000000000 .. 2.0000000000000000]' sage: conjugate_shrink(CIF(RIF(1, 2), RIF(-1, 2))).str(style='brackets') '[1.0000000000000000 .. 2.0000000000000000]'
>>> from sage.all import * >>> from sage.rings.qqbar import conjugate_shrink >>> conjugate_shrink(RIF(Integer(3), Integer(4))).str(style='brackets') '[3.0000000000000000 .. 4.0000000000000000]' >>> conjugate_shrink(CIF(RIF(Integer(1), Integer(2)), RIF(Integer(1), Integer(2)))).str(style='brackets') '[1.0000000000000000 .. 2.0000000000000000] + [1.0000000000000000 .. 2.0000000000000000]*I' >>> conjugate_shrink(CIF(RIF(Integer(1), Integer(2)), RIF(Integer(0), Integer(1)))).str(style='brackets') '[1.0000000000000000 .. 2.0000000000000000]' >>> conjugate_shrink(CIF(RIF(Integer(1), Integer(2)), RIF(-Integer(1), Integer(2)))).str(style='brackets') '[1.0000000000000000 .. 2.0000000000000000]'
- sage.rings.qqbar.do_polred(poly, threshold=32)[source]#
Find a polynomial of reasonably small discriminant that generates the same number field as
poly
, using the PARIpolredbest
function.INPUT:
poly
– a monic irreducible polynomial with integer coefficientsthreshold
– an integer used to decide whether to runpolredbest
OUTPUT:
A triple (
elt_fwd
,elt_back
,new_poly
), where:new_poly
is the new polynomial defining the same number field,elt_fwd
is a polynomial expression for a root of the new polynomial in terms of a root of the original polynomial,elt_back
is a polynomial expression for a root of the original polynomial in terms of a root of the new polynomial.
EXAMPLES:
sage: from sage.rings.qqbar import do_polred sage: R.<x> = QQ['x'] sage: oldpol = x^2 - 5 sage: fwd, back, newpol = do_polred(oldpol) sage: newpol x^2 - x - 1 sage: Kold.<a> = NumberField(oldpol) sage: Knew.<b> = NumberField(newpol) sage: newpol(fwd(a)) 0 sage: oldpol(back(b)) 0 sage: do_polred(x^2 - x - 11) (1/3*x + 1/3, 3*x - 1, x^2 - x - 1) sage: do_polred(x^3 + 123456) (-1/4*x, -4*x, x^3 - 1929)
>>> from sage.all import * >>> from sage.rings.qqbar import do_polred >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> oldpol = x**Integer(2) - Integer(5) >>> fwd, back, newpol = do_polred(oldpol) >>> newpol x^2 - x - 1 >>> Kold = NumberField(oldpol, names=('a',)); (a,) = Kold._first_ngens(1) >>> Knew = NumberField(newpol, names=('b',)); (b,) = Knew._first_ngens(1) >>> newpol(fwd(a)) 0 >>> oldpol(back(b)) 0 >>> do_polred(x**Integer(2) - x - Integer(11)) (1/3*x + 1/3, 3*x - 1, x^2 - x - 1) >>> do_polred(x**Integer(3) + Integer(123456)) (-1/4*x, -4*x, x^3 - 1929)
This shows that Issue #13054 has been fixed:
sage: do_polred(x^4 - 4294967296*x^2 + 54265257667816538374400) (1/4*x, 4*x, x^4 - 268435456*x^2 + 211973662764908353025)
>>> from sage.all import * >>> do_polred(x**Integer(4) - Integer(4294967296)*x**Integer(2) + Integer(54265257667816538374400)) (1/4*x, 4*x, x^4 - 268435456*x^2 + 211973662764908353025)
- sage.rings.qqbar.find_zero_result(fn, l)[source]#
l
is a list of some sort.fn
is a function which maps an element ofl
and a precision into an interval (either real or complex) of that precision, such that for sufficient precision, exactly one element ofl
results in an interval containing 0. Returns that one element ofl
.EXAMPLES:
sage: from sage.rings.qqbar import find_zero_result sage: _.<x> = QQ['x'] sage: delta = 10^(-70) sage: p1 = x - 1 sage: p2 = x - 1 - delta sage: p3 = x - 1 + delta sage: p2 == find_zero_result(lambda p, prec: p(RealIntervalField(prec)(1 + delta)), [p1, p2, p3]) True
>>> from sage.all import * >>> from sage.rings.qqbar import find_zero_result >>> _ = QQ['x']; (x,) = _._first_ngens(1) >>> delta = Integer(10)**(-Integer(70)) >>> p1 = x - Integer(1) >>> p2 = x - Integer(1) - delta >>> p3 = x - Integer(1) + delta >>> p2 == find_zero_result(lambda p, prec: p(RealIntervalField(prec)(Integer(1) + delta)), [p1, p2, p3]) True
- sage.rings.qqbar.get_AA_golden_ratio()[source]#
Return the golden ratio as an element of the algebraic real field. Used by
sage.symbolic.constants.golden_ratio._algebraic_()
.EXAMPLES:
sage: AA(golden_ratio) # indirect doctest # needs sage.symbolic 1.618033988749895?
>>> from sage.all import * >>> AA(golden_ratio) # indirect doctest # needs sage.symbolic 1.618033988749895?
- sage.rings.qqbar.is_AlgebraicField(F)[source]#
Check whether
F
is anAlgebraicField
instance.This function is deprecated. Use
isinstance()
withAlgebraicField
instead.EXAMPLES:
sage: from sage.rings.qqbar import is_AlgebraicField sage: [is_AlgebraicField(x) for x in [AA, QQbar, None, 0, "spam"]] doctest:warning... DeprecationWarning: is_AlgebraicField is deprecated; use isinstance(..., sage.rings.abc.AlgebraicField instead See https://github.com/sagemath/sage/issues/32660 for details. [False, True, False, False, False]
>>> from sage.all import * >>> from sage.rings.qqbar import is_AlgebraicField >>> [is_AlgebraicField(x) for x in [AA, QQbar, None, Integer(0), "spam"]] doctest:warning... DeprecationWarning: is_AlgebraicField is deprecated; use isinstance(..., sage.rings.abc.AlgebraicField instead See https://github.com/sagemath/sage/issues/32660 for details. [False, True, False, False, False]
- sage.rings.qqbar.is_AlgebraicNumber(x)[source]#
Test if
x
is an instance ofAlgebraicNumber
. For internal use.EXAMPLES:
sage: from sage.rings.qqbar import is_AlgebraicNumber sage: is_AlgebraicNumber(AA(sqrt(2))) # needs sage.symbolic doctest:warning... DeprecationWarning: The function is_AlgebraicNumber is deprecated; use 'isinstance(..., AlgebraicNumber)' instead. See https://github.com/sagemath/sage/issues/38128 for details. False sage: is_AlgebraicNumber(QQbar(sqrt(2))) # needs sage.symbolic True sage: is_AlgebraicNumber("spam") False
>>> from sage.all import * >>> from sage.rings.qqbar import is_AlgebraicNumber >>> is_AlgebraicNumber(AA(sqrt(Integer(2)))) # needs sage.symbolic doctest:warning... DeprecationWarning: The function is_AlgebraicNumber is deprecated; use 'isinstance(..., AlgebraicNumber)' instead. See https://github.com/sagemath/sage/issues/38128 for details. False >>> is_AlgebraicNumber(QQbar(sqrt(Integer(2)))) # needs sage.symbolic True >>> is_AlgebraicNumber("spam") False
- sage.rings.qqbar.is_AlgebraicReal(x)[source]#
Test if
x
is an instance ofAlgebraicReal
. For internal use.EXAMPLES:
sage: from sage.rings.qqbar import is_AlgebraicReal sage: is_AlgebraicReal(AA(sqrt(2))) # needs sage.symbolic doctest:warning... DeprecationWarning: The function is_AlgebraicReal is deprecated; use 'isinstance(..., AlgebraicReal)' instead. See https://github.com/sagemath/sage/issues/38128 for details. True sage: is_AlgebraicReal(QQbar(sqrt(2))) # needs sage.symbolic False sage: is_AlgebraicReal("spam") False
>>> from sage.all import * >>> from sage.rings.qqbar import is_AlgebraicReal >>> is_AlgebraicReal(AA(sqrt(Integer(2)))) # needs sage.symbolic doctest:warning... DeprecationWarning: The function is_AlgebraicReal is deprecated; use 'isinstance(..., AlgebraicReal)' instead. See https://github.com/sagemath/sage/issues/38128 for details. True >>> is_AlgebraicReal(QQbar(sqrt(Integer(2)))) # needs sage.symbolic False >>> is_AlgebraicReal("spam") False
- sage.rings.qqbar.is_AlgebraicRealField(F)[source]#
Check whether
F
is anAlgebraicRealField
instance. For internal use.This function is deprecated. Use
isinstance()
withAlgebraicRealField
instead.EXAMPLES:
sage: from sage.rings.qqbar import is_AlgebraicRealField sage: [is_AlgebraicRealField(x) for x in [AA, QQbar, None, 0, "spam"]] doctest:warning... DeprecationWarning: is_AlgebraicRealField is deprecated; use isinstance(..., sage.rings.abc.AlgebraicRealField instead See https://github.com/sagemath/sage/issues/32660 for details. [True, False, False, False, False]
>>> from sage.all import * >>> from sage.rings.qqbar import is_AlgebraicRealField >>> [is_AlgebraicRealField(x) for x in [AA, QQbar, None, Integer(0), "spam"]] doctest:warning... DeprecationWarning: is_AlgebraicRealField is deprecated; use isinstance(..., sage.rings.abc.AlgebraicRealField instead See https://github.com/sagemath/sage/issues/32660 for details. [True, False, False, False, False]
- sage.rings.qqbar.isolating_interval(intv_fn, pol)[source]#
intv_fn
is a function that takes a precision and returns an interval of that precision containing some particular root of pol. (It must return better approximations as the precision increases.) pol is an irreducible polynomial with rational coefficients.Returns an interval containing at most one root of pol.
EXAMPLES:
sage: from sage.rings.qqbar import isolating_interval sage: _.<x> = QQ['x'] sage: isolating_interval(lambda prec: sqrt(RealIntervalField(prec)(2)), x^2 - 2) 1.4142135623730950488?
>>> from sage.all import * >>> from sage.rings.qqbar import isolating_interval >>> _ = QQ['x']; (x,) = _._first_ngens(1) >>> isolating_interval(lambda prec: sqrt(RealIntervalField(prec)(Integer(2))), x**Integer(2) - Integer(2)) 1.4142135623730950488?
And an example that requires more precision:
sage: delta = 10^(-70) sage: p = (x - 1) * (x - 1 - delta) * (x - 1 + delta) sage: isolating_interval(lambda prec: RealIntervalField(prec)(1 + delta), p) 1.000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000?
>>> from sage.all import * >>> delta = Integer(10)**(-Integer(70)) >>> p = (x - Integer(1)) * (x - Integer(1) - delta) * (x - Integer(1) + delta) >>> isolating_interval(lambda prec: RealIntervalField(prec)(Integer(1) + delta), p) 1.000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000?
The function also works with complex intervals and complex roots:
sage: p = x^2 - x + 13/36 sage: isolating_interval(lambda prec: ComplexIntervalField(prec)(1/2, 1/3), p) 0.500000000000000000000? + 0.3333333333333333334?*I
>>> from sage.all import * >>> p = x**Integer(2) - x + Integer(13)/Integer(36) >>> isolating_interval(lambda prec: ComplexIntervalField(prec)(Integer(1)/Integer(2), Integer(1)/Integer(3)), p) 0.500000000000000000000? + 0.3333333333333333334?*I
- sage.rings.qqbar.number_field_elements_from_algebraics(numbers, minimal=False, same_field=False, embedded=False, name='a', prec=53)[source]#
Given a sequence of elements of either
AA
orQQbar
(or a mixture), computes a number field containing all of these elements, these elements as members of that number field, and a homomorphism from the number field back toAA
orQQbar
.INPUT:
numbers
– a number or list of numbersminimal
– Boolean (default:False
). Whether to minimize the degree of the extensionsame_field
– Boolean (default:False
). See belowembedded
– Boolean (default:False
). Whether to make the NumberField embeddedname
– string (default:'a'
); name of the primitive elementprec
– integer (default:53
). The number of bit of precision to guarantee finding real roots
OUTPUT:
A tuple with the NumberField, the numbers inside the NumberField, and a homomorphism from the number field back to
AA
orQQbar
.This may not return the smallest such number field, unless
minimal=True
is specified.If
same_field=True
is specified, and all of the elements are from the same field (eitherAA
orQQbar
), the generated homomorphism will map back to that field. Otherwise, if all specified elements are real, the homomorphism might map back toAA
(and will, ifminimal=True
is specified), even if the elements were inQQbar
.Also, a single number can be passed, rather than a sequence; and any values which are not elements of
AA
orQQbar
will automatically be coerced toQQbar
This function may be useful for efficiency reasons: doing exact computations in the corresponding number field will be faster than doing exact computations directly in
AA
orQQbar
.EXAMPLES:
We can use this to compute the splitting field of a polynomial. (Unfortunately this takes an unreasonably long time for non-toy examples.):
sage: x = polygen(QQ) sage: p = x^3 + x^2 + x + 17 sage: rts = p.roots(ring=QQbar, multiplicities=False) sage: splitting = number_field_elements_from_algebraics(rts, name='b')[0]; splitting Number Field in b with defining polynomial y^6 - 40*y^4 - 22*y^3 + 873*y^2 + 1386*y + 594 sage: p.roots(ring=splitting) [(361/29286*b^5 - 19/3254*b^4 - 14359/29286*b^3 + 401/29286*b^2 + 18183/1627*b + 15930/1627, 1), (49/117144*b^5 - 179/39048*b^4 - 3247/117144*b^3 + 22553/117144*b^2 + 1744/4881*b - 17195/6508, 1), (-1493/117144*b^5 + 407/39048*b^4 + 60683/117144*b^3 - 24157/117144*b^2 - 56293/4881*b - 53033/6508, 1)] sage: # needs sage.symbolic sage: rt2 = AA(sqrt(2)); rt2 1.414213562373095? sage: rt3 = AA(sqrt(3)); rt3 1.732050807568878? sage: rt3a = QQbar(sqrt(3)); rt3a 1.732050807568878? sage: qqI = QQbar.zeta(4); qqI I sage: z3 = QQbar.zeta(3); z3 -0.500000000000000? + 0.866025403784439?*I sage: rt2b = rt3 + rt2 - rt3; rt2b 1.414213562373095? sage: rt2c = z3 + rt2 - z3; rt2c 1.414213562373095? + 0.?e-19*I sage: number_field_elements_from_algebraics(rt2) (Number Field in a with defining polynomial y^2 - 2, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 2 To: Algebraic Real Field Defn: a |--> 1.414213562373095?) sage: number_field_elements_from_algebraics((rt2,rt3)) (Number Field in a with defining polynomial y^4 - 4*y^2 + 1, [-a^3 + 3*a, a^2 - 2], Ring morphism: From: Number Field in a with defining polynomial y^4 - 4*y^2 + 1 To: Algebraic Real Field Defn: a |--> -1.931851652578137?)
>>> from sage.all import * >>> x = polygen(QQ) >>> p = x**Integer(3) + x**Integer(2) + x + Integer(17) >>> rts = p.roots(ring=QQbar, multiplicities=False) >>> splitting = number_field_elements_from_algebraics(rts, name='b')[Integer(0)]; splitting Number Field in b with defining polynomial y^6 - 40*y^4 - 22*y^3 + 873*y^2 + 1386*y + 594 >>> p.roots(ring=splitting) [(361/29286*b^5 - 19/3254*b^4 - 14359/29286*b^3 + 401/29286*b^2 + 18183/1627*b + 15930/1627, 1), (49/117144*b^5 - 179/39048*b^4 - 3247/117144*b^3 + 22553/117144*b^2 + 1744/4881*b - 17195/6508, 1), (-1493/117144*b^5 + 407/39048*b^4 + 60683/117144*b^3 - 24157/117144*b^2 - 56293/4881*b - 53033/6508, 1)] >>> # needs sage.symbolic >>> rt2 = AA(sqrt(Integer(2))); rt2 1.414213562373095? >>> rt3 = AA(sqrt(Integer(3))); rt3 1.732050807568878? >>> rt3a = QQbar(sqrt(Integer(3))); rt3a 1.732050807568878? >>> qqI = QQbar.zeta(Integer(4)); qqI I >>> z3 = QQbar.zeta(Integer(3)); z3 -0.500000000000000? + 0.866025403784439?*I >>> rt2b = rt3 + rt2 - rt3; rt2b 1.414213562373095? >>> rt2c = z3 + rt2 - z3; rt2c 1.414213562373095? + 0.?e-19*I >>> number_field_elements_from_algebraics(rt2) (Number Field in a with defining polynomial y^2 - 2, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 2 To: Algebraic Real Field Defn: a |--> 1.414213562373095?) >>> number_field_elements_from_algebraics((rt2,rt3)) (Number Field in a with defining polynomial y^4 - 4*y^2 + 1, [-a^3 + 3*a, a^2 - 2], Ring morphism: From: Number Field in a with defining polynomial y^4 - 4*y^2 + 1 To: Algebraic Real Field Defn: a |--> -1.931851652578137?)
rt3a
is a real number inQQbar
. Ordinarily, we’d get a homomorphism toAA
(because all elements are real), but if we specifysame_field=True
, we’ll get a homomorphism back toQQbar
:sage: number_field_elements_from_algebraics(rt3a) # needs sage.symbolic (Number Field in a with defining polynomial y^2 - 3, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 3 To: Algebraic Real Field Defn: a |--> 1.732050807568878?) sage: number_field_elements_from_algebraics(rt3a, same_field=True) # needs sage.symbolic (Number Field in a with defining polynomial y^2 - 3, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 3 To: Algebraic Field Defn: a |--> 1.732050807568878?)
>>> from sage.all import * >>> number_field_elements_from_algebraics(rt3a) # needs sage.symbolic (Number Field in a with defining polynomial y^2 - 3, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 3 To: Algebraic Real Field Defn: a |--> 1.732050807568878?) >>> number_field_elements_from_algebraics(rt3a, same_field=True) # needs sage.symbolic (Number Field in a with defining polynomial y^2 - 3, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 3 To: Algebraic Field Defn: a |--> 1.732050807568878?)
We’ve created
rt2b
in such a way that sage does not initially know that it’s in a degree-2 extension of \(\QQ\):sage: number_field_elements_from_algebraics(rt2b) # needs sage.symbolic (Number Field in a with defining polynomial y^4 - 4*y^2 + 1, -a^3 + 3*a, Ring morphism: From: Number Field in a with defining polynomial y^4 - 4*y^2 + 1 To: Algebraic Real Field Defn: a |--> -1.931851652578137?)
>>> from sage.all import * >>> number_field_elements_from_algebraics(rt2b) # needs sage.symbolic (Number Field in a with defining polynomial y^4 - 4*y^2 + 1, -a^3 + 3*a, Ring morphism: From: Number Field in a with defining polynomial y^4 - 4*y^2 + 1 To: Algebraic Real Field Defn: a |--> -1.931851652578137?)
We can specify
minimal=True
if we want the smallest number field:sage: number_field_elements_from_algebraics(rt2b, minimal=True) # needs sage.symbolic (Number Field in a with defining polynomial y^2 - 2, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 2 To: Algebraic Real Field Defn: a |--> 1.414213562373095?)
>>> from sage.all import * >>> number_field_elements_from_algebraics(rt2b, minimal=True) # needs sage.symbolic (Number Field in a with defining polynomial y^2 - 2, a, Ring morphism: From: Number Field in a with defining polynomial y^2 - 2 To: Algebraic Real Field Defn: a |--> 1.414213562373095?)
Things work fine with rational numbers, too:
sage: number_field_elements_from_algebraics((QQbar(1/2), AA(17))) (Rational Field, [1/2, 17], Ring morphism: From: Rational Field To: Algebraic Real Field Defn: 1 |--> 1)
>>> from sage.all import * >>> number_field_elements_from_algebraics((QQbar(Integer(1)/Integer(2)), AA(Integer(17)))) (Rational Field, [1/2, 17], Ring morphism: From: Rational Field To: Algebraic Real Field Defn: 1 |--> 1)
Or we can just pass in symbolic expressions, as long as they can be coerced into
QQbar
:sage: number_field_elements_from_algebraics((sqrt(7), sqrt(9), sqrt(11))) # needs sage.symbolic (Number Field in a with defining polynomial y^4 - 9*y^2 + 1, [-a^3 + 8*a, 3, -a^3 + 10*a], Ring morphism: From: Number Field in a with defining polynomial y^4 - 9*y^2 + 1 To: Algebraic Real Field Defn: a |--> 0.3354367396454047?)
>>> from sage.all import * >>> number_field_elements_from_algebraics((sqrt(Integer(7)), sqrt(Integer(9)), sqrt(Integer(11)))) # needs sage.symbolic (Number Field in a with defining polynomial y^4 - 9*y^2 + 1, [-a^3 + 8*a, 3, -a^3 + 10*a], Ring morphism: From: Number Field in a with defining polynomial y^4 - 9*y^2 + 1 To: Algebraic Real Field Defn: a |--> 0.3354367396454047?)
Here we see an example of doing some computations with number field elements, and then mapping them back into
QQbar
:sage: # needs sage.symbolic sage: algebraics = (rt2, rt3, qqI, z3) sage: fld,nums,hom = number_field_elements_from_algebraics(algebraics) sage: fld,nums,hom # random (Number Field in a with defining polynomial y^8 - y^4 + 1, [-a^5 + a^3 + a, a^6 - 2*a^2, a^6, -a^4], Ring morphism: From: Number Field in a with defining polynomial y^8 - y^4 + 1 To: Algebraic Field Defn: a |--> -0.2588190451025208? - 0.9659258262890683?*I) sage: (nfrt2, nfrt3, nfI, nfz3) = nums sage: hom(nfrt2) 1.414213562373095? + 0.?e-18*I sage: nfrt2^2 2 sage: nfrt3^2 3 sage: nfz3 + nfz3^2 -1 sage: nfI^2 -1 sage: sum = nfrt2 + nfrt3 + nfI + nfz3; sum a^5 + a^4 - a^3 + 2*a^2 - a - 1 sage: hom(sum) 2.646264369941973? + 1.866025403784439?*I sage: hom(sum) == rt2 + rt3 + qqI + z3 True sage: [hom(n) for n in nums] == [rt2, rt3, qqI, z3] True
>>> from sage.all import * >>> # needs sage.symbolic >>> algebraics = (rt2, rt3, qqI, z3) >>> fld,nums,hom = number_field_elements_from_algebraics(algebraics) >>> fld,nums,hom # random (Number Field in a with defining polynomial y^8 - y^4 + 1, [-a^5 + a^3 + a, a^6 - 2*a^2, a^6, -a^4], Ring morphism: From: Number Field in a with defining polynomial y^8 - y^4 + 1 To: Algebraic Field Defn: a |--> -0.2588190451025208? - 0.9659258262890683?*I) >>> (nfrt2, nfrt3, nfI, nfz3) = nums >>> hom(nfrt2) 1.414213562373095? + 0.?e-18*I >>> nfrt2**Integer(2) 2 >>> nfrt3**Integer(2) 3 >>> nfz3 + nfz3**Integer(2) -1 >>> nfI**Integer(2) -1 >>> sum = nfrt2 + nfrt3 + nfI + nfz3; sum a^5 + a^4 - a^3 + 2*a^2 - a - 1 >>> hom(sum) 2.646264369941973? + 1.866025403784439?*I >>> hom(sum) == rt2 + rt3 + qqI + z3 True >>> [hom(n) for n in nums] == [rt2, rt3, qqI, z3] True
It is also possible to have an embedded Number Field:
sage: x = polygen(ZZ) sage: my_num = AA.polynomial_root(x^3 - 2, RIF(0,3)) sage: res = number_field_elements_from_algebraics(my_num, embedded=True) sage: res[0].gen_embedding() 1.259921049894873? sage: res[2] Ring morphism: From: Number Field in a with defining polynomial y^3 - 2 with a = 1.259921049894873? To: Algebraic Real Field Defn: a |--> 1.259921049894873?
>>> from sage.all import * >>> x = polygen(ZZ) >>> my_num = AA.polynomial_root(x**Integer(3) - Integer(2), RIF(Integer(0),Integer(3))) >>> res = number_field_elements_from_algebraics(my_num, embedded=True) >>> res[Integer(0)].gen_embedding() 1.259921049894873? >>> res[Integer(2)] Ring morphism: From: Number Field in a with defining polynomial y^3 - 2 with a = 1.259921049894873? To: Algebraic Real Field Defn: a |--> 1.259921049894873?
sage: # needs sage.symbolic sage: elems = [2^(1/3), 3^(1/5)] sage: nf, nums, hom = number_field_elements_from_algebraics(elems, ....: embedded=True) sage: nf Number Field in a with defining polynomial y^15 - 9*y^10 + 21*y^5 - 3 with a = 0.6866813218928813? sage: nums [a^10 - 5*a^5 + 2, -a^8 + 4*a^3] sage: hom Ring morphism: From: Number Field in a with defining polynomial y^15 - 9*y^10 + 21*y^5 - 3 with a = 0.6866813218928813? To: Algebraic Real Field Defn: a |--> 0.6866813218928813?
>>> from sage.all import * >>> # needs sage.symbolic >>> elems = [Integer(2)**(Integer(1)/Integer(3)), Integer(3)**(Integer(1)/Integer(5))] >>> nf, nums, hom = number_field_elements_from_algebraics(elems, ... embedded=True) >>> nf Number Field in a with defining polynomial y^15 - 9*y^10 + 21*y^5 - 3 with a = 0.6866813218928813? >>> nums [a^10 - 5*a^5 + 2, -a^8 + 4*a^3] >>> hom Ring morphism: From: Number Field in a with defining polynomial y^15 - 9*y^10 + 21*y^5 - 3 with a = 0.6866813218928813? To: Algebraic Real Field Defn: a |--> 0.6866813218928813?
Complex embeddings are possible as well:
sage: # needs sage.symbolic sage: elems = [sqrt(5), 2^(1/3)+sqrt(3)*I, 3/4] sage: nf, nums, hom = number_field_elements_from_algebraics(elems, ....: embedded=True) sage: nf # random (polynomial and root not unique) Number Field in a with defining polynomial y^24 - 6*y^23 ...- 9*y^2 + 1 with a = 0.2598679? + 0.0572892?*I sage: nf.is_isomorphic(NumberField( ....: x^24 - 9*x^22 + 135*x^20 - 720*x^18 + 1821*x^16 ....: - 3015*x^14 + 3974*x^12 - 3015*x^10 + 1821*x^8 ....: - 720*x^6 + 135*x^4 - 9*x^2 + 1, 'a')) True sage: list(map(QQbar, nums)) == elems == list(map(hom, nums)) True
>>> from sage.all import * >>> # needs sage.symbolic >>> elems = [sqrt(Integer(5)), Integer(2)**(Integer(1)/Integer(3))+sqrt(Integer(3))*I, Integer(3)/Integer(4)] >>> nf, nums, hom = number_field_elements_from_algebraics(elems, ... embedded=True) >>> nf # random (polynomial and root not unique) Number Field in a with defining polynomial y^24 - 6*y^23 ...- 9*y^2 + 1 with a = 0.2598679? + 0.0572892?*I >>> nf.is_isomorphic(NumberField( ... x**Integer(24) - Integer(9)*x**Integer(22) + Integer(135)*x**Integer(20) - Integer(720)*x**Integer(18) + Integer(1821)*x**Integer(16) ... - Integer(3015)*x**Integer(14) + Integer(3974)*x**Integer(12) - Integer(3015)*x**Integer(10) + Integer(1821)*x**Integer(8) ... - Integer(720)*x**Integer(6) + Integer(135)*x**Integer(4) - Integer(9)*x**Integer(2) + Integer(1), 'a')) True >>> list(map(QQbar, nums)) == elems == list(map(hom, nums)) True
- sage.rings.qqbar.prec_seq()[source]#
Return a generator object which iterates over an infinite increasing sequence of precisions to be tried in various numerical computations.
Currently just returns powers of 2 starting at 64.
EXAMPLES:
sage: g = sage.rings.qqbar.prec_seq() sage: [next(g), next(g), next(g)] [64, 128, 256]
>>> from sage.all import * >>> g = sage.rings.qqbar.prec_seq() >>> [next(g), next(g), next(g)] [64, 128, 256]
- sage.rings.qqbar.rational_exact_root(r, d)[source]#
Check whether the rational \(r\) is an exact \(d\)’th power.
If so, this returns the \(d\)’th root of \(r\); otherwise, this returns
None
.EXAMPLES:
sage: from sage.rings.qqbar import rational_exact_root sage: rational_exact_root(16/81, 4) 2/3 sage: rational_exact_root(8/81, 3) is None True
>>> from sage.all import * >>> from sage.rings.qqbar import rational_exact_root >>> rational_exact_root(Integer(16)/Integer(81), Integer(4)) 2/3 >>> rational_exact_root(Integer(8)/Integer(81), Integer(3)) is None True
- sage.rings.qqbar.short_prec_seq()[source]#
Return a sequence of precisions to try in cases when an infinite-precision computation is possible: returns a couple of small powers of 2 and then
None
.EXAMPLES:
sage: from sage.rings.qqbar import short_prec_seq sage: short_prec_seq() (64, 128, None)
>>> from sage.all import * >>> from sage.rings.qqbar import short_prec_seq >>> short_prec_seq() (64, 128, None)
- sage.rings.qqbar.t1[source]#
alias of
ANBinaryExpr
- sage.rings.qqbar.tail_prec_seq()[source]#
A generator over precisions larger than those in
short_prec_seq()
.EXAMPLES:
sage: from sage.rings.qqbar import tail_prec_seq sage: g = tail_prec_seq() sage: [next(g), next(g), next(g)] [256, 512, 1024]
>>> from sage.all import * >>> from sage.rings.qqbar import tail_prec_seq >>> g = tail_prec_seq() >>> [next(g), next(g), next(g)] [256, 512, 1024]