Ask Your Question

Revision history [back]

I guess you want to stay within the framework of number fields that Sage offers. What you need is to get the generator of your embedded field F as an algebraic number. You can try to get it as follows:

sage: F = NumberField(x^3+3, 'z', embedding=0.7+1.2j)
sage: F.gen_embedding()
0.7211247851537042? + 1.249024766483407?*I

Unfortunately, this number is not an algebraic number but a kind of infinite sequence of digits, known as lazy expansion, for which you can not easily recover the algebraic number it comes from:

sage: F.gen_embedding().parent()
Complex Lazy Field
sage: QQbar(F.gen_embedding())
TypeError: Illegal initializer for algebraic number

So, we have to look at others methods your (embedded) number field offers. If we have the embedding as morphism from F to the Algebraic Field we would be done. Let us try:

sage: F.embeddings(QQbar)
[
Ring morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Algebraic Field
  Defn: z |--> -1.442249570307409?,
Ring morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Algebraic Field
  Defn: z |--> 0.7211247851537042? - 1.249024766483407?*I,
Ring morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Algebraic Field
  Defn: z |--> 0.7211247851537042? + 1.249024766483407?*I
]

While the documentation F.embeddings? says "If possible, the most natural embedding of self into K is put first in the list.", you can see that this method do not care about the embedding you provided (which should have been considerd as the most natural) since it did not put that embedding first, it just chosed the fanciest one.

There should be a method that is able to select the embedding you provided as a morphism into QQbar !!!

Note that we have:

sage: F.coerce_embedding()
Generic morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Complex Lazy Field
  Defn: z -> 0.7211247851537042? + 1.249024766483407?*I

But again, you fall into the ComplexLazyField stuff, so it is useless.

For me, the general issue with embedded number fields in Sage is that the number field does not care much about the embedding you provided. This issue points a general problem with number fields in Sage: there is no specific class for "embedded number field", the fact that a number field is embedded or not is just a ._embedding attribute within the same class NumberField (while the mathematical objects are really different), so you can define an embedding, but then the number field does not offer additional specific methods for that (in particular, it can not select the correct embedding from within F.embeddings(QQbar), which is a pity).

What you can do is to discover by yourself which embedding into QQbar from the list corresponds to the single embedding into CLF (stands for ComplexLazyField). A trick is to extend the morphism from QQbar to CLF and check for equality:

sage: def my_embedding_as_qqbar(K):
....:     for f in F.embeddings(QQbar):
....:         if f.extend_codomain(CLF) == K.coerce_embedding():
....:             return f

sage: f = my_embedding_as_qqbar(F) ; f
Ring morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Algebraic Field
  Defn: z |--> 0.7211247851537042? + 1.249024766483407?*I

Then it is easy to get real and imaginary of the image of the generator parts and start working with them:

sage: r = f.im_gens()[0].real() ; r
0.7211247851537042?
sage: i = f.im_gens()[0].imag() ; i
1.249024766483407?
sage: r.parent()
Algebraic Real Field
sage: r.minpoly()
x^3 - 3/8
sage: i.minpoly()
x^6 - 243/64

It is an interesting task to define a distinct (perhaps inherited) well defined EmbeddedNumberField class with additional methods, in particular F.embedding(field).

I guess you want to stay within the framework of number fields that Sage offers. What you need is to get the generator of your embedded field F as an algebraic number. You can try to get it as follows:

sage: F = NumberField(x^3+3, 'z', embedding=0.7+1.2j)
sage: F.gen_embedding()
0.7211247851537042? + 1.249024766483407?*I

Unfortunately, this number is not an algebraic number but a kind of infinite sequence of digits, known as lazy expansion, for which you can not easily recover the algebraic number it comes from:

sage: F.gen_embedding().parent()
Complex Lazy Field
sage: QQbar(F.gen_embedding())
TypeError: Illegal initializer for algebraic number

So, we have to look at others methods your (embedded) number field offers. If we have the embedding as morphism from F to the Algebraic Field we would be done. Let us try:

sage: F.embeddings(QQbar)
[
Ring morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Algebraic Field
  Defn: z |--> -1.442249570307409?,
Ring morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Algebraic Field
  Defn: z |--> 0.7211247851537042? - 1.249024766483407?*I,
Ring morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Algebraic Field
  Defn: z |--> 0.7211247851537042? + 1.249024766483407?*I
]

While the documentation F.embeddings? says "If possible, the most natural embedding of self into K is put first in the list.", you can see that this method do not care about the embedding you provided (which should have been considerd as the most natural) since it did not put that embedding first, it just chosed the fanciest one.

There should be a method that is able to select the embedding you provided as a morphism into QQbar !!!

Note that we have:

sage: F.coerce_embedding()
Generic morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Complex Lazy Field
  Defn: z -> 0.7211247851537042? + 1.249024766483407?*I

But again, you fall it falls into the ComplexLazyField stuff, , so it is useless.useless for our purpose.

For me, the general issue with embedded number fields in Sage is that the number field does not care much about the embedding you provided. This issue points a general problem with number fields in Sage: there is no specific class for "embedded number field", the fact that a number field is embedded or not is just a ._embedding attribute within the same class NumberField (while the mathematical objects are really different), so you can define an embedding, but then the number field does not offer additional specific methods for that (in particular, it can not select the correct embedding from within F.embeddings(QQbar), which is a pity).

What you can do is to discover by yourself which embedding into QQbar from the list corresponds to the single embedding into CLF (stands for ComplexLazyField). A trick is to extend the morphism from QQbar to CLF and check for equality:

sage: def my_embedding_as_qqbar(K):
....:     for f in F.embeddings(QQbar):
....:         if f.extend_codomain(CLF) == K.coerce_embedding():
....:             return f

sage: f = my_embedding_as_qqbar(F) ; f
Ring morphism:
  From: Number Field in z with defining polynomial x^3 + 3
  To:   Algebraic Field
  Defn: z |--> 0.7211247851537042? + 1.249024766483407?*I

Then it is easy to get real and imaginary of the image of the generator parts and start working with them:

sage: r = f.im_gens()[0].real() ; r
0.7211247851537042?
sage: i = f.im_gens()[0].imag() ; i
1.249024766483407?
sage: r.parent()
Algebraic Real Field
sage: r.minpoly()
x^3 - 3/8
sage: i.minpoly()
x^6 - 243/64

It is an interesting task to define a distinct (perhaps inherited) well defined EmbeddedNumberField class with additional methods, in particular F.embedding(field).