25.2.1 Fixed Modulus Rings

The first, and simplest, type of $ \mathbf{Z}_p$ is basically a wrapper around $ \mathbf{Z} / p^n \mathbf{Z}$ , providing a unified interface with the rest of the $ p$ -adics. You specify a precision, and all elements are stored to that absolute precision. If you perform an operation that would normally lose precision, the element does not track that it no longer has full precision.

The fixed modulus ring provides the lowest level of convenience, but it is also the one that has the lowest computational overhead. Once we have ironed out some bugs, the fixed modulus elements will be those most optimized for speed.

As with all of the implementations of $ \mathbf{Z}_p$ , one creates a new ring using the constructor Zp, and passing in 'fixed-mod' for the type parameter. For example,

sage: R = Zp(5, prec = 10, type = 'fixed-mod', print_mode = 'series')
sage: R
5-adic Ring of fixed modulus 5^10

One can create elements as follows:

sage: a = R(375)
sage: a
3*5^3 + O(5^10)
sage: b = R(105)
sage: b
5 + 4*5^2 + O(5^10)

Now that we have some elements, we can do arithmetic in the ring.

sage: a + b
5 + 4*5^2 + 3*5^3 + O(5^10)
sage: a * b
3*5^4 + 2*5^5 + 2*5^6 + O(5^10)

Floor division (//) divides even though the result isn't really known to the claimed precision; note that division isn't defined:

sage: a // 5
3*5^2 + O(5^10)

sage: a / 5
Traceback (most recent call last):
...
ValueError: cannot invert non-unit

Since elements don't actually store their actual precision, one can only divide by units:

sage: a / 2
4*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 2*5^8 + 2*5^9 + O(5^10)
sage: a / b
Traceback (most recent call last):
...
ValueError: cannot invert non-unit

If you want to divide by a non-unit, do it using the // operator:

sage: a // b
3*5^2 + 3*5^3 + 2*5^5 + 5^6 + 4*5^7 + 2*5^8 + O(5^10)

See About this document... for information on suggesting changes.