Implementation of the universal cyclotomic field using the Zumbroich basis. The universal cyclotomic field is the smallest subfield of the complex field containing all roots of unity.
REFERENCES:
[Bre97] | (1, 2, 3)
|
AUTHORS:
Note
Todo
EXAMPLES:
The universal cyclotomic field is constructed using:
sage: UCF = UniversalCyclotomicField(); UCF
Universal Cyclotomic Field
One can as well construct it through CyclotomicField():
sage: UCF = CyclotomicField(); UCF
Universal Cyclotomic Field
The cyclotomics themselves are accessable through:
sage: UCF.gen(5)
E(5)
sage: UCF.gen(5,2)
E(5)^2
or the alias:
sage: UCF.gen(5)
E(5)
sage: UCF.gen(5,2)
E(5)^2
One can as well access the universal cyclotomic field using:
sage: UCF.<E> = UniversalCyclotomicField();
sage: E(5)
E(5)
Other names are supported as well:
sage: UCF.<zeta> = UniversalCyclotomicField();
sage: zeta(5)
zeta(5)
As are other bracketings:
sage: UCF.<E> = UniversalCyclotomicField(bracket='');
sage: E(5)
E5
sage: UCF.<E> = UniversalCyclotomicField(bracket="[]");
sage: E(5)
E[5]
sage: UCF.<E> = UniversalCyclotomicField(bracket="(ABCXYZ)");
sage: E(5)
E(ABC5XYZ)
We use the generator “E” and the standard bracketing throughout this file:
sage: UCF.<E> = UniversalCyclotomicField();
Some very first examples:
sage: E(2)
-1
sage: E(3)
E(3)
sage: E(6)
-E(3)^2
Equality and inequality checks:
sage: E(6,2) == E(6)^2 == E(3)
True
sage: E(6)^2 != E(3)
False
Addition and multiplication:
sage: E(2) * E(3)
-E(3)
sage: f = E(2) + E(3); f
2*E(3) + E(3)^2
Inverses:
sage: f^-1
1/3*E(3) + 2/3*E(3)^2
sage: f.inverse()
1/3*E(3) + 2/3*E(3)^2
sage: f * f.inverse()
1
Complex conjugation:
sage: f.conjugate()
E(3) + 2*E(3)^2
Galois conjugation:
sage: f.galois_conjugates()
[2*E(3) + E(3)^2, E(3) + 2*E(3)^2]
sage: f.norm_of_galois_extension()
3
Coercion to the algebraic field QQbar:
sage: QQbar(E(3))
-0.500000000000000? + 0.866025403784439?*I
sage: QQbar(f)
-1.500000000000000? + 0.866025403784439?*I
Partial conversion to the real algebraic field AA:
sage: AA(E(5)+E(5).conjugate())
0.618033988749895?
sage: AA(E(5))
Traceback (most recent call last):
...
TypeError: No conversion of E(5) to the real algebraic field AA.
One can as well define the universal cyclotomic field without any embedding:
sage: UCF.<E> = UniversalCyclotomicField(embedding=None); UCF
Universal Cyclotomic Field
sage: UCF.<E> = UniversalCyclotomicField(embedding=False); UCF
Universal Cyclotomic Field
sage: QQbar(E(5))
Traceback (most recent call last):
...
TypeError: Illegal initializer for algebraic number
Conversion to CyclotomicField:
Warning
This is only possible if self has the standard embedding
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(5).to_cyclotomic_field()
zeta5
sage: f = E(2) + E(3)
sage: f.to_cyclotomic_field()
zeta3 - 1
sage: CF = CyclotomicField(5)
sage: CF(E(5))
zeta5
sage: CF = CyclotomicField(7)
sage: CF(E(5))
Traceback (most recent call last):
...
TypeError: The element E(5) cannot be converted to Cyclotomic Field of order 7 and degree 6
sage: CF = CyclotomicField(10)
sage: CF(E(5))
zeta10^2
Conversions to and from GAP:
sage: a = gap('E(6)'); a
-E(3)^2
sage: a.parent()
Gap
sage: b = UCF.from_gap(a); b
-E(3)^2
sage: b.parent()
Universal Cyclotomic Field
sage: gap(b)
-E(3)^2
Conversions to and from the cyclotomic field:
sage: a = E(6).to_cyclotomic_field(); a
zeta3 + 1
sage: UCF.from_cyclotomic_field(a)
-E(3)^2
One can also do basic arithmetics with matrices over the universal cyclotomic field:
sage: m = matrix(2,[E(3),1,1,E(4)]); m
[E(3) 1]
[ 1 E(4)]
sage: m.parent()
Full MatrixSpace of 2 by 2 dense matrices over Universal Cyclotomic Field
sage: m^2
[ -E(3) E(12)^4 - E(12)^7 - E(12)^11]
[E(12)^4 - E(12)^7 - E(12)^11 0]
sage: -m
[-E(3) -1]
[ -1 -E(4)]
And compute its characteristic polynomial, echelon form, pivots, and thus its rank:
sage: m.charpoly()
x^2 + (-E(12)^4 + E(12)^7 + E(12)^11)*x + E(12)^4 + E(12)^7 + E(12)^8
sage: m.echelon_form()
[1 0]
[0 1]
sage: m.pivots()
(0, 1)
sage: m.rank()
2
The eigenvalues do not (yet) work:
sage: m.eigenvalues() # not implemented
...
NotImplementedError:
A long real life test. Computing N3 is much faster than computing N2 which is again 3 times faster than computing N1:
sage: W = gap3.ComplexReflectionGroup(14) #optional - gap3 # long time
sage: UC = W.UnipotentCharacters() #optional - gap3 # long time
sage: UCF.<E> = UniversalCyclotomicField(); #optional - gap3 # long time
sage: M = matrix(UCF,UC.families[2].fourierMat) #optional - gap3 # long time
sage: N1 = M*M #optional - gap3 # long time
sage: N2 = UCF._matrix_mult(M,M) #optional - gap3 # long time
sage: CF = CyclotomicField(24) #optional - gap3 # long time
sage: M = matrix(CF,M) #optional - gap3 # long time
sage: N3 = matrix(UCF,M*M) #optional - gap3 # long time
sage: N1 == N2 == N3 #optional - gap3 # long time
True
TESTS:
As an indication that everything works, we start with a test that we obtain the same answers as in GAP:
sage: all(str(E(n,k)).translate(None,' ') == gap.execute('E('+str(n)+')^'+str(k)).translate(None,'\n ') for n in range(1,15) for k in range(n))
True
The following didn’t work first:
sage: str(-E(9)^4-E(9)^7).translate(None,' ') == gap.execute('-E(9)^4-E(9)^7').translate(None,'\n ')
True
sage: str(-E(9)^5-E(9)^8).translate(None,' ') == gap.execute('-E(9)^5-E(9)^8').translate(None,'\n ')
True
Bases: sage.structure.unique_representation.UniqueRepresentation, sage.rings.ring.Field
The universal cyclotomic field, which is the smallest field containing the rational numbers together with all roots of unity.
Its elements are represented as linear combinations of the so-called Zumbroich basis.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField(); UCF
Universal Cyclotomic Field
sage: E(12)
-E(12)^7
sage: E(12) in UCF
True
One also has access to the universal cyclotomic field using the function CyclotomicField():
sage: UCF = CyclotomicField(); UCF
Universal Cyclotomic Field
One can also construct a vector space over the universal cyclotomic field:
sage: UCF^3
Vector space of dimension 3 over Universal Cyclotomic Field
Bases: sage.structure.element.FieldElement
An element of the universal cyclotomic field.
See also
Return the absolute value of this element.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(3).abs()
1
sage: x = 2*E(3); x.abs()
2
sage: x = E(3)+E(4); x.abs()
1.931851652578137?
If no embedding is given, an error is raised:
sage: UCF.<E> = UniversalCyclotomicField(embedding=None)
sage: E(3).abs()
Traceback (most recent call last):
...
ValueError: Universal Cyclotomic Field has no embedding defined.
Returns the coefficient of mon in self.
Parameters: | mon – an element in the Zumbroich basis |
---|
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(6)
-E(3)^2
sage: E(6).coefficient((3,2))
-1
sage: E(6).coefficient((3,1))
0
Alternatively, one can use indexed access:
sage: E(6)[(3,2)]
-1
Returns the complex conjugate of self.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(3).conjugate()
E(3)^2
sage: E(4).conjugate()
-E(4)
Note
the conjugate of a monomial is always a monomial or the negation thereof.
Returns the order of the smallest field containing self.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(4).field_order()
4
sage: E(6).field_order()
3
Returns all Galois conjugates of self.
Those are the elements in the universal cyclotomic field obtained
from self by substituting by
for all
. Remark that for odd primes, the Galois conjugates
permutes the Zumbroich basis. The first Galois conjugate in the
list is self.
Parameters: | m – if given, it must be a multiple of field_order(); the Galois conjugates are then computed with respect to the cyclotomics of order m |
---|
OUTPUT:
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(6).galois_conjugates()
[-E(3)^2, -E(3)]
sage: E(6).galois_conjugates(6)
[-E(3)^2, -E(3)]
sage: E(6).galois_conjugates(12)
[-E(3)^2, -E(3), -E(3)^2, -E(3)]
sage: E(8).galois_conjugates()
[E(8), E(8)^3, -E(8), -E(8)^3]
sage: E(8).galois_conjugates(16)
[E(8), E(8)^3, -E(8), -E(8)^3, E(8), E(8)^3, -E(8), -E(8)^3]
sage: E(9).galois_conjugates()
[-E(9)^4 - E(9)^7, E(9)^2, E(9)^4, E(9)^5, E(9)^7, -E(9)^2 - E(9)^5]
sage: E(11).galois_conjugates()
[E(11), E(11)^2, E(11)^3, E(11)^4, E(11)^5, E(11)^6, E(11)^7, E(11)^8, E(11)^9, E(11)^10]
sage: E(6).galois_conjugates(5)
Traceback (most recent call last):
...
ValueError: The given integer (5) is not a multiple of the field order of -E(3)^2.
Returns the inverse of self.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: f = 2 * E(3) + E(4); f
2*E(12)^4 - E(12)^7 - E(12)^11
sage: f.inverse()
2/13*E(12)^4 - 3/13*E(12)^7 + 8/13*E(12)^8 + 1/13*E(12)^11
sage: f * f.inverse()
1
Returns True if self is one.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(3).is_one()
False
sage: UCF(1).is_one()
True
Returns True if self is rational.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(3).is_rational()
False
sage: UCF(1/3).is_rational()
True
sage: UCF(0).is_rational()
True
Returns True if self is real.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(5).is_real()
False
sage: (E(5)^2 + E(5)^3).is_real()
True
sage: (E(5)^4 + E(5)^3).is_real()
False
Returns True if self is real and positive.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: (E(5)^2 + E(5)^3).is_real_positive()
False
sage: (-E(5)^4 - E(5)^3).is_real_positive()
False
The minimal polynomial of self element over .
Parameters: | var (optional, default:'x') – the minimal polynomial is defined over a polynomial ring in a variable with this name |
---|
See also
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: UCF(4).minpoly()
x - 4
sage: UCF(4).minpoly(var='y')
y - 4
sage: E(3).minpoly()
x^2 + x + 1
sage: E(3).minpoly(var='y')
y^2 + y + 1
TESTS:
sage: x = UCF(4)
sage: x.minpoly() == x.to_cyclotomic_field().minpoly()
True
sage: x = E(3)
sage: x.minpoly() == x.to_cyclotomic_field().minpoly()
True
sage: x = E(3)
sage: x.minpoly(var='y') == x.to_cyclotomic_field().minpoly(var='y')
True
Returns the norm as a Galois extension of , which is
given by the product of all galois_conjugates.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(3).norm_of_galois_extension()
1
sage: E(6).norm_of_galois_extension()
1
sage: (E(2) + E(3)).norm_of_galois_extension()
3
Returns the support of self.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(6).support()
[(3, 2)]
Returns self in CyclotomicField.
Warning
This method raises an error if self.parent() does not have the standard embedding
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(5).to_cyclotomic_field()
zeta5
This method is as well used to convert to a cyclotomic field:
sage: CF = CyclotomicField(5)
sage: CF(E(5))
zeta5
See also
CyclotomicField
Returns an element of self of order order.
Parameters: | order (integer; optional, default:3) – a positive integer. |
---|
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UniversalCyclotomicField().an_element()
E(3)
sage: UniversalCyclotomicField().an_element(order=6)
-E(3)^2
sage: UniversalCyclotomicField().an_element(order=10)
-E(5)^3
Returns 0 which is the characteristic of self.
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.characteristic()
0
Returns the degree of self as a field extension over the Rationals.
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.degree()
+Infinity
Returns the base ring element coeff as an element in self.
Parameters: | coeff – A rational number. |
---|
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: x = UCF.from_base_ring(2); x
2
sage: x.parent()
Universal Cyclotomic Field
Returns the element in self coming from the element in NumberField_cyclotomic.
Parameters: | elem – an element of NumberField_cyclotomic |
---|
Warning
This method raises an error if self does not have the standard embedding.
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: a = CyclotomicField(6).gen(); a
zeta6
sage: UCF.from_cyclotomic_field(a)
-E(3)^2
An example with another embedding:
sage: a = CyclotomicField(5,embedding=CC(exp(4*pi*I/5))).gen(); a
zeta5
sage: UCF.from_cyclotomic_field(a)
E(5)^2
TESTS:
sage: UCF.from_cyclotomic_field(4)
Traceback (most recent call last):
...
TypeError: The given data (4) is not a cyclotomic field element.
sage: UCF = UniversalCyclotomicField(embedding=None);
sage: a = CyclotomicField(5).gen()
sage: UCF.from_cyclotomic_field(a)
Traceback (most recent call last):
...
TypeError: This method can only be used if Universal Cyclotomic Field uses the standard embedding.
Returns the element in self obtained from the gap by executing string.
Parameters: | string – string representing an element in the universal cyclotomic field |
---|
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.from_gap(gap("-E(3)^2"))
-E(3)^2
sage: UCF = UniversalCyclotomicField()
sage: UCF.from_gap(gap("E(3)^2"))
E(3)^2
sage: UCF.from_gap(gap("1/6*E(3)")) # testing a former bug
1/6*E(3)
Returns living in UniversalCyclotomicField, where
denotes the primitive
-th root of unity
.
Parameters: |
|
---|
Note
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: E(3) # indirect doctest
E(3)
sage: E(6) # indirect doctest
-E(3)^2
sage: E(12) # indirect doctest
-E(12)^7
sage: E(6,2) # indirect doctest
E(3)
sage: E(6)^2 # indirect doctest
E(3)
Returns False as self is not finite.
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.is_finite()
False
Returns False since self is not a prime field.
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.is_prime_field()
False
Returns True if self is a subring of other.
Warning
Currently, it is only checked if self is other!
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.is_subring(UCF)
True
sage: UCF.is_subring(CC)
False
Returns the monomial in self associated to mon in the Zumbroich basis.
Parameters: |
|
---|
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.monomial((1,0))
1
sage: UCF.monomial((4,2))
Traceback (most recent call last):
...
ValueError: The given data is not a monomial of the universal cyclotomic field.
Returns the one in self.
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.one()
1
Returns which is the prime subfield of self.
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.prime_subfield()
Rational Field
Returns a (often non-trivial) pseudo-random element of self.
Parameters: | order (integer or None; optional, default:None) – |
---|
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.random_element() # random
3*E(7)^2 + E(7)^3 + 2*E(7)^4 - 5*E(7)^5
sage: UCF.random_element(order=4) # random
-3*E(4)
sage: UCF.random_element(order=12) # random
E(12)^7 - 4*E(12)^8 + E(12)^11
Returns the sum of all elements (which must be coerceable into self) in L.
Parameters: | L – list or tuple of elements in self |
---|
Note
Faster than the usual sum as operated directly on dictionaries, as all steps are done together.
EXAMPLES:
sage: UCF.<E> = UniversalCyclotomicField()
sage: UCF.sum([ E(i) for i in range(1,5) ])
E(12)^4 - E(12)^7 - E(12)^11
Returns the zero in self.
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.zero()
0
Returns the Zumbroich basis of order n.
The Zumbroich basis is a linear basis of the universal cyclotomic field
that behaves very well with considering an primitive -th root of unity
as a (non primitive)
-th root. See [Bre97] for further details.
Parameters: | n – positive integer |
---|
OUTPUT:
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.zumbroich_basis(8)
{E(8)^3, E(4), E(8), 1}
sage: UCF.zumbroich_basis(9)
{E(9)^5, E(9)^4, E(3)^2, E(3), E(9)^7, E(9)^2}
Returns the indices of the Zumbroich basis of order n.
The Zumbroich basis is a linear basis of the universal cyclotomic field
that behaves very well with considering an primitive -th root of unity
as a (non primitive)
-th root. See [Bre97] for further details.
Parameters: | n – positive integer |
---|
OUTPUT:
EXAMPLES:
sage: UCF = UniversalCyclotomicField()
sage: UCF.zumbroich_basis_indices(8)
{(8, 1), (8, 3), (8, 0), (8, 2)}
Bases: sage.structure.unique_representation.UniqueRepresentation, sage.structure.parent.Parent
This class is a thin wrapper to work with indices in the Zumbroich basis.
EXAMPLES:
sage: from sage.rings.universal_cyclotomic_field.universal_cyclotomic_field import ZumbroichBasisIndices
sage: ZumbroichBasisIndices()
The indices of the Zumbroich basis
One can ask for an element to play with:
sage: a = ZumbroichBasisIndices().an_element(); a
(12, 4)
The element a is indeed an element of this class:
sage: a.parent()
The indices of the Zumbroich basis
And one can check if an element is indeed contained in the Zumbroich basis:
sage: a in ZumbroichBasisIndices()
True
sage: (12,4) in ZumbroichBasisIndices()
True
Bases: sage.structure.element_wrapper.ElementWrapper
EXAMPLES:
sage: from sage.structure.element_wrapper import DummyParent
sage: a = ElementWrapper(DummyParent("A parent"), 1)
TESTS:
sage: TestSuite(a).run(skip = "_test_category")
sage: a = ElementWrapper(1, DummyParent("A parent"))
doctest:...: DeprecationWarning: the first argument must be a parent
See http://trac.sagemath.org/14519 for details.
Note
ElementWrapper is not intended to be used directly, hence the failing category test.
Returns an element of the Zumbroich basis.
EXAMPLES:
sage: from sage.rings.universal_cyclotomic_field.universal_cyclotomic_field import ZumbroichBasisIndices
sage: a = ZumbroichBasisIndices().an_element(); a
(12, 4)
Returns the list of tuples such that the set
form a Zumbroich basis for
over
.
Parameters: |
|
---|
EXAMPLES:
sage: from sage.rings.universal_cyclotomic_field.universal_cyclotomic_field import ZumbroichBasisIndices
sage: ZumbroichBasisIndices().indices(6)
{(6, 4), (6, 2)}
sage: ZumbroichBasisIndices().indices(12)
{(12, 7), (12, 4), (12, 11), (12, 8)}
sage: ZumbroichBasisIndices().indices(24)
{(24, 19), (24, 8), (24, 17), (24, 16), (24, 14), (24, 1), (24, 22), (24, 11)}
Returns the parent of an element in the image of embedding.
Parameters: | embedding – A function from the positive integers ![]() |
---|
If the images are in a real or complex field, then it creates an image into a lazy field.
EXAMPLES:
sage: from sage.rings.universal_cyclotomic_field.universal_cyclotomic_field import get_parent_of_embedding
sage: get_parent_of_embedding(lambda n: QQbar.zeta()^n)
Algebraic Field
sage: get_parent_of_embedding(lambda n: CC(exp(2*pi*I/n)))
Complex Lazy Field