Issue with orders in number fields

Skip to first unread message

Justin C. Walker

Sep 6, 2023, 8:21:12 PM9/6/23
to SAGE Development
Hi, all,

I think I understand what’s going wrong, but I don’t understand how to fix the following problem:

sage: K.<a>=NumberField(x^2-10)
sage: OK=K.maximal_order()
sage: O=ZZ[a]
sage: a in OK
sage: a in K
sage: a in O
sage: O.index_in(OK)
ValueError                                Traceback (most recent call last)
ValueError: other must have the same ambient number field as self.

Have we just painted ourselves into a (figurative) corner?

Pointers?  Suggestions?

Thanks for any help.


Justin C. Walker, Curmudgeon at Large
Institute for the Absorption of Federal Funds
While creating wives, God promised men
that good and obedient wives would be
found in all corners of the world.
Then He made the earth round.

Nils Bruin

Sep 7, 2023, 11:54:54 AM9/7/23
to sage-devel
Hi Justin,

You can see the problem from:

sage: O.ambient()
Number Field in a0 with defining polynomial x^2 - 10 with a0 = a

As you can see, the ambient field of O is not identical to K (which is the ambient field of OK). It is a field with an *embedding* into K, though, and it happens to be an isomorphism here.

Mathematically, I think sage is right to have some reservation here. If we do

sage: K.<a>=NumberField(x^4-2)
sage: OK=K.ring_of_integers()
sage: b=a^2
sage: O=ZZ[b]
sage: O.ambient()
Number Field in a0 with defining polynomial x^2 - 2 with a0 = a^2

I think you see the problem: the field of fractions of ZZ[b] does not need to be (and in the above example isn't) equal to the parent of b.

In this case, O wouldn't have a finite index in OK.

For programmatic consistency, we generally avoid programming in "shortcuts" based on specific values: while ZZ[a] happens to be an order in the parent K of a if a generates it over QQ, we'd generally *not* special case that to then create ZZ[a] as an order in K, but still create this separate field with generator a0.

It's perhaps inconvenient and pedantic, but I would think this one may even still be on the instructive side for having to explain to a student.

David Roe

Sep 7, 2023, 2:52:21 PM9/7/23
If you want the order generated by a, you can do

sage: K.<a>=NumberField(x^2-10)
sage: OK=K.maximal_order()
sage: O = K.order(a)
sage: O.index_in(OK)

Note that this correctly fails in Nils' example:
sage: K.order(a^2)
ValueError: the rank of the span of gens is wrong


You received this message because you are subscribed to the Google Groups "sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
To view this discussion on the web visit

Nils Bruin

Sep 7, 2023, 6:00:42 PM9/7/23
to sage-devel
Hm, interesting. The current code for ZZ.__getitem__ (i.e., ZZ[a]) does this:

        if isinstance(x, NumberFieldElement_base):
            K, _ = parent(x).subfield(x)
            return K.order(K.gen())

However, this functionality is also available in K.order:

sage: K.order(a,allow_subfield=True)
Order in Number Field in a with defining polynomial x^4 - 2
sage: K.order(a^2,allow_subfield=True)
Order in Number Field in beta with defining polynomial x^2 - 2*x - 1 with beta = -a^2 + 1

so the code could actually just be:
     if isinstance(x, NumberFieldElement_base):
        return K.order(x,allow_subfield=True)

and then Justin's problem would be solved. It's more economical in that no (isomorphic) copy of the field is created. It looks like it does cause different problems, though: it looks like K.order wants a standardised basis, so:

 sage: K.order(a+1).gens()
(1, a, a^2, a^3)
sage: K.order(a^2+a+1).gens()
(1, 7*a^3 + a, 2*a^3 + a^2, 9*a^3)

So K.order(a) does not need to return an order with a power basis on a. Perhaps that's the deeper reason why ZZ[a] does its trickery: certainly one would expect an order with power basis on a from that construction.

Reply all
Reply to author
0 new messages