passagemath-ntl 10.6.33__cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-ntl might be problematic. Click here for more details.
- passagemath_ntl-10.6.33.dist-info/METADATA +122 -0
- passagemath_ntl-10.6.33.dist-info/RECORD +161 -0
- passagemath_ntl-10.6.33.dist-info/WHEEL +6 -0
- passagemath_ntl-10.6.33.dist-info/top_level.txt +2 -0
- passagemath_ntl.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
- passagemath_ntl.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
- passagemath_ntl.libs/libmpfi-ad12a86d.so.0.0.0 +0 -0
- passagemath_ntl.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
- passagemath_ntl.libs/libntl-0043a3a2.so.44.0.1 +0 -0
- sage/all__sagemath_ntl.py +7 -0
- sage/libs/all__sagemath_ntl.py +3 -0
- sage/libs/mpfi/__init__.pxd +287 -0
- sage/libs/mpfi/types.pxd +10 -0
- sage/libs/ntl/GF2.pxd +18 -0
- sage/libs/ntl/GF2E.pxd +28 -0
- sage/libs/ntl/GF2EX.pxd +12 -0
- sage/libs/ntl/GF2X.pxd +81 -0
- sage/libs/ntl/ZZ.pxd +93 -0
- sage/libs/ntl/ZZX.pxd +85 -0
- sage/libs/ntl/ZZ_p.pxd +28 -0
- sage/libs/ntl/ZZ_pE.pxd +37 -0
- sage/libs/ntl/ZZ_pEX.pxd +106 -0
- sage/libs/ntl/ZZ_pX.pxd +122 -0
- sage/libs/ntl/__init__.py +4 -0
- sage/libs/ntl/all.py +72 -0
- sage/libs/ntl/conversion.pxd +106 -0
- sage/libs/ntl/convert.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/convert.pxd +7 -0
- sage/libs/ntl/convert.pyx +38 -0
- sage/libs/ntl/decl.pxi +18 -0
- sage/libs/ntl/error.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/error.pyx +63 -0
- sage/libs/ntl/lzz_p.pxd +20 -0
- sage/libs/ntl/lzz_pX.pxd +59 -0
- sage/libs/ntl/mat_GF2.pxd +30 -0
- sage/libs/ntl/mat_GF2E.pxd +30 -0
- sage/libs/ntl/mat_ZZ.pxd +59 -0
- sage/libs/ntl/misc.pxi +33 -0
- sage/libs/ntl/ntl_GF2.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2.pxd +5 -0
- sage/libs/ntl/ntl_GF2.pyx +281 -0
- sage/libs/ntl/ntl_GF2E.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2E.pxd +8 -0
- sage/libs/ntl/ntl_GF2E.pyx +488 -0
- sage/libs/ntl/ntl_GF2EContext.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2EContext.pxd +9 -0
- sage/libs/ntl/ntl_GF2EContext.pyx +134 -0
- sage/libs/ntl/ntl_GF2EX.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2EX.pxd +10 -0
- sage/libs/ntl/ntl_GF2EX.pyx +251 -0
- sage/libs/ntl/ntl_GF2X.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2X.pxd +5 -0
- sage/libs/ntl/ntl_GF2X.pyx +771 -0
- sage/libs/ntl/ntl_GF2X_linkage.pxi +404 -0
- sage/libs/ntl/ntl_ZZ.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ.pxd +7 -0
- sage/libs/ntl/ntl_ZZ.pyx +541 -0
- sage/libs/ntl/ntl_ZZX.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZX.pxd +7 -0
- sage/libs/ntl/ntl_ZZX.pyx +1206 -0
- sage/libs/ntl/ntl_ZZ_p.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_p.pxd +10 -0
- sage/libs/ntl/ntl_ZZ_p.pyx +509 -0
- sage/libs/ntl/ntl_ZZ_pContext.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pContext.pxd +22 -0
- sage/libs/ntl/ntl_ZZ_pContext.pyx +201 -0
- sage/libs/ntl/ntl_ZZ_pE.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pE.pxd +11 -0
- sage/libs/ntl/ntl_ZZ_pE.pyx +349 -0
- sage/libs/ntl/ntl_ZZ_pEContext.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pEContext.pxd +23 -0
- sage/libs/ntl/ntl_ZZ_pEContext.pyx +226 -0
- sage/libs/ntl/ntl_ZZ_pEX.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pEX.pxd +10 -0
- sage/libs/ntl/ntl_ZZ_pEX.pyx +1255 -0
- sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +420 -0
- sage/libs/ntl/ntl_ZZ_pX.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pX.pxd +17 -0
- sage/libs/ntl/ntl_ZZ_pX.pyx +1532 -0
- sage/libs/ntl/ntl_lzz_p.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_p.pxd +8 -0
- sage/libs/ntl/ntl_lzz_p.pyx +440 -0
- sage/libs/ntl/ntl_lzz_pContext.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_pContext.pxd +7 -0
- sage/libs/ntl/ntl_lzz_pContext.pyx +137 -0
- sage/libs/ntl/ntl_lzz_pX.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_pX.pxd +10 -0
- sage/libs/ntl/ntl_lzz_pX.pyx +902 -0
- sage/libs/ntl/ntl_mat_GF2.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_GF2.pxd +8 -0
- sage/libs/ntl/ntl_mat_GF2.pyx +612 -0
- sage/libs/ntl/ntl_mat_GF2E.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_GF2E.pxd +10 -0
- sage/libs/ntl/ntl_mat_GF2E.pyx +752 -0
- sage/libs/ntl/ntl_mat_ZZ.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_ZZ.pxd +6 -0
- sage/libs/ntl/ntl_mat_ZZ.pyx +1523 -0
- sage/libs/ntl/ntl_tools.pxd +3 -0
- sage/libs/ntl/ntlwrap.h +53 -0
- sage/libs/ntl/ntlwrap_impl.h +743 -0
- sage/libs/ntl/types.pxd +157 -0
- sage/libs/ntl/vec_GF2.pxd +26 -0
- sage/libs/ntl/vec_GF2E.pxd +2 -0
- sage/matrix/all__sagemath_ntl.py +1 -0
- sage/matrix/matrix_modn_dense_double.pxd +10 -0
- sage/matrix/matrix_modn_dense_float.pxd +9 -0
- sage/matrix/matrix_modn_dense_template.pxi +3257 -0
- sage/matrix/matrix_modn_dense_template_header.pxi +15 -0
- sage/matrix/matrix_modn_sparse.pxd +8 -0
- sage/misc/all__sagemath_ntl.py +1 -0
- sage/rings/all__sagemath_ntl.py +7 -0
- sage/rings/bernmm.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/bernmm.pyx +161 -0
- sage/rings/bernoulli_mod_p.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/bernoulli_mod_p.pyx +313 -0
- sage/rings/finite_rings/all__sagemath_ntl.py +1 -0
- sage/rings/finite_rings/finite_field_ntl_gf2e.py +305 -0
- sage/rings/finite_rings/residue_field_ntl_gf2e.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +140 -0
- sage/rings/padics/all__sagemath_ntl.py +5 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.pxd +25 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.pyx +2368 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.pxd +33 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.pyx +3277 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.pxd +12 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.pyx +1739 -0
- sage/rings/padics/padic_ZZ_pX_element.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_element.pxd +6 -0
- sage/rings/padics/padic_ZZ_pX_element.pyx +919 -0
- sage/rings/padics/padic_ext_element.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ext_element.pxd +38 -0
- sage/rings/padics/padic_ext_element.pyx +512 -0
- sage/rings/padics/pow_computer_ext.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/pow_computer_ext.pxd +107 -0
- sage/rings/padics/pow_computer_ext.pyx +2401 -0
- sage/rings/polynomial/all__sagemath_ntl.py +1 -0
- sage/rings/polynomial/evaluation_ntl.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/evaluation_ntl.pxd +7 -0
- sage/rings/polynomial/evaluation_ntl.pyx +70 -0
- sage/rings/polynomial/polynomial_gf2x.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_gf2x.pxd +10 -0
- sage/rings/polynomial/polynomial_gf2x.pyx +364 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.pxd +8 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +1128 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.pxd +36 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +2049 -0
- sage/rings/polynomial/polynomial_template.pxi +842 -0
- sage/rings/polynomial/polynomial_template_header.pxi +11 -0
- sage/rings/polynomial/polynomial_zz_pex.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_zz_pex.pxd +12 -0
- sage/rings/polynomial/polynomial_zz_pex.pyx +778 -0
- sage/rings/real_mpfi.pxd +50 -0
- sage/schemes/all__sagemath_ntl.py +1 -0
- sage/schemes/hyperelliptic_curves/all__sagemath_ntl.py +1 -0
- sage/schemes/hyperelliptic_curves/hypellfrob.cpython-314t-aarch64-linux-gnu.so +0 -0
- sage/schemes/hyperelliptic_curves/hypellfrob.pyx +252 -0
|
@@ -0,0 +1,2368 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-ntl
|
|
2
|
+
# distutils: libraries = NTL_LIBRARIES gmp M_LIBRARIES
|
|
3
|
+
# distutils: extra_compile_args = NTL_CFLAGS
|
|
4
|
+
# distutils: include_dirs = NTL_INCDIR
|
|
5
|
+
# distutils: library_dirs = NTL_LIBDIR
|
|
6
|
+
# distutils: extra_link_args = NTL_LIBEXTRA
|
|
7
|
+
# distutils: language = c++
|
|
8
|
+
# sage.doctest: needs sage.rings.padics
|
|
9
|
+
r"""
|
|
10
|
+
`p`-adic ``ZZ_pX`` CA Element
|
|
11
|
+
|
|
12
|
+
This file implements elements of Eisenstein and unramified extensions
|
|
13
|
+
of ``Zp`` with capped absolute precision.
|
|
14
|
+
|
|
15
|
+
For the parent class see padic_extension_leaves.pyx.
|
|
16
|
+
|
|
17
|
+
The underlying implementation is through NTL's ``ZZ_pX`` class. Each
|
|
18
|
+
element contains the following data:
|
|
19
|
+
|
|
20
|
+
- ``absprec`` -- long; an integer giving the precision to which this
|
|
21
|
+
element is defined. This is the power of the uniformizer modulo
|
|
22
|
+
which the element is well defined.
|
|
23
|
+
|
|
24
|
+
- ``value`` -- ``ZZ_pX_c``; an ntl ``ZZ_pX`` storing the value. The
|
|
25
|
+
variable `x` is the uniformizer in the case of Eisenstein extensions
|
|
26
|
+
This ZZ_pX is created with global ntl modulus determined by absprec.
|
|
27
|
+
Let `a` be absprec and `e` be the ramification index over
|
|
28
|
+
`\QQ_p` or `\ZZ_p`. Then the modulus is given by
|
|
29
|
+
`p^{ceil(a/e)}`. Note that all kinds of problems arise if you try
|
|
30
|
+
to mix moduli. ``ZZ_pX_conv_modulus`` gives a semi-safe way to
|
|
31
|
+
convert between different moduli without having to pass through ZZX.
|
|
32
|
+
|
|
33
|
+
- ``prime_pow`` -- (some subclass of ``PowComputer_ZZ_pX``) a class,
|
|
34
|
+
identical among all elements with the same parent, holding common
|
|
35
|
+
data.
|
|
36
|
+
|
|
37
|
+
+ ``prime_pow.deg`` -- the degree of the extension
|
|
38
|
+
|
|
39
|
+
+ ``prime_pow.e`` -- the ramification index
|
|
40
|
+
|
|
41
|
+
+ ``prime_pow.f`` -- the inertia degree
|
|
42
|
+
|
|
43
|
+
+ ``prime_pow.prec_cap`` -- the unramified precision cap. For
|
|
44
|
+
Eisenstein extensions this is the smallest power of p that is
|
|
45
|
+
zero.
|
|
46
|
+
|
|
47
|
+
+ ``prime_pow.ram_prec_cap`` -- the ramified precision cap. For
|
|
48
|
+
Eisenstein extensions this will be the smallest power of `x` that
|
|
49
|
+
is indistinguishable from zero.
|
|
50
|
+
|
|
51
|
+
+ ``prime_pow.pow_ZZ_tmp``, prime_pow.pow_mpz_t_tmp``,
|
|
52
|
+
``prime_pow.pow_Integer`` -- functions for accessing powers of
|
|
53
|
+
`p`. The first two return pointers. See
|
|
54
|
+
``sage/rings/padics/pow_computer_ext`` for examples and important
|
|
55
|
+
warnings.
|
|
56
|
+
|
|
57
|
+
+ ``prime_pow.get_context``, ``prime_pow.get_context_capdiv``,
|
|
58
|
+
``prime_pow.get_top_context`` -- obtain an
|
|
59
|
+
``ntl_ZZ_pContext_class`` corresponding to `p^n`. The capdiv
|
|
60
|
+
version divides by ``prime_pow.e`` as appropriate.
|
|
61
|
+
``top_context`` corresponds to `p^{\texttt{prec\_cap}}`.
|
|
62
|
+
|
|
63
|
+
+ ``prime_pow.restore_context``,
|
|
64
|
+
``prime_pow.restore_context_capdiv``,
|
|
65
|
+
``prime_pow.restore_top_context`` -- restores the given context.
|
|
66
|
+
|
|
67
|
+
+ ``prime_pow.get_modulus``, ``get_modulus_capdiv``,
|
|
68
|
+
``get_top_modulus`` -- returns a ``ZZ_pX_Modulus_c*`` pointing to
|
|
69
|
+
a polynomial modulus defined modulo `p^n` (appropriately divided
|
|
70
|
+
by ``prime_pow.e`` in the capdiv case).
|
|
71
|
+
|
|
72
|
+
EXAMPLES:
|
|
73
|
+
|
|
74
|
+
An Eisenstein extension::
|
|
75
|
+
|
|
76
|
+
sage: R = ZpCA(5,5)
|
|
77
|
+
sage: S.<x> = ZZ[]
|
|
78
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
79
|
+
sage: W.<w> = R.ext(f); W
|
|
80
|
+
5-adic Eisenstein Extension Ring in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
81
|
+
sage: z = (1+w)^5; z
|
|
82
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15
|
|
83
|
+
+ 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
84
|
+
sage: y = z >> 1; y
|
|
85
|
+
w^4 + w^5 + 2*w^6 + 4*w^7 + 3*w^9 + w^11 + 4*w^12 + 4*w^13 + 4*w^14 + 4*w^15
|
|
86
|
+
+ 4*w^16 + 4*w^19 + w^20 + 4*w^23 + O(w^24)
|
|
87
|
+
sage: y.valuation()
|
|
88
|
+
4
|
|
89
|
+
sage: y.precision_relative()
|
|
90
|
+
20
|
|
91
|
+
sage: y.precision_absolute()
|
|
92
|
+
24
|
|
93
|
+
sage: z - (y << 1)
|
|
94
|
+
1 + O(w^25)
|
|
95
|
+
sage: (1/w)^12+w
|
|
96
|
+
w^-12 + w + O(w^12)
|
|
97
|
+
sage: (1/w).parent()
|
|
98
|
+
5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
99
|
+
|
|
100
|
+
An unramified extension::
|
|
101
|
+
|
|
102
|
+
sage: # needs sage.libs.flint
|
|
103
|
+
sage: g = x^3 + 3*x + 3
|
|
104
|
+
sage: A.<a> = R.ext(g)
|
|
105
|
+
sage: z = (1+a)^5; z
|
|
106
|
+
(2*a^2 + 4*a) + (3*a^2 + 3*a + 1)*5 + (4*a^2 + 3*a + 4)*5^2
|
|
107
|
+
+ (4*a^2 + 4*a + 4)*5^3 + (4*a^2 + 4*a + 4)*5^4 + O(5^5)
|
|
108
|
+
sage: z - 1 - 5*a - 10*a^2 - 10*a^3 - 5*a^4 - a^5
|
|
109
|
+
O(5^5)
|
|
110
|
+
sage: y = z >> 1; y
|
|
111
|
+
(3*a^2 + 3*a + 1) + (4*a^2 + 3*a + 4)*5 + (4*a^2 + 4*a + 4)*5^2
|
|
112
|
+
+ (4*a^2 + 4*a + 4)*5^3 + O(5^4)
|
|
113
|
+
sage: 1/a
|
|
114
|
+
(3*a^2 + 4) + (a^2 + 4)*5 + (3*a^2 + 4)*5^2 + (a^2 + 4)*5^3 + (3*a^2 + 4)*5^4 + O(5^5)
|
|
115
|
+
sage: FFA = A.residue_field()
|
|
116
|
+
sage: a0 = FFA.gen(); A(a0^3)
|
|
117
|
+
(2*a + 2) + O(5)
|
|
118
|
+
|
|
119
|
+
Different printing modes::
|
|
120
|
+
|
|
121
|
+
sage: # needs sage.libs.flint
|
|
122
|
+
sage: R = ZpCA(5, print_mode='digits'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
|
|
123
|
+
sage: z = (1+w)^5; repr(z)
|
|
124
|
+
'...4110403113210310442221311242000111011201102002023303214332011214403232013144001400444441030421100001'
|
|
125
|
+
sage: R = ZpCA(5, print_mode='bars'); S.<x> = ZZ[]; g = x^3 + 3*x + 3; A.<a> = R.ext(g)
|
|
126
|
+
sage: z = (1+a)^5; repr(z)
|
|
127
|
+
'...[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 3, 4]|[1, 3, 3]|[0, 4, 2]'
|
|
128
|
+
sage: R = ZpCA(5, print_mode='terse'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
|
|
129
|
+
sage: z = (1+w)^5; z
|
|
130
|
+
6 + 95367431640505*w + 25*w^2 + 95367431640560*w^3 + 5*w^4 + O(w^100)
|
|
131
|
+
sage: R = ZpCA(5, print_mode='val-unit'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
|
|
132
|
+
sage: y = (1+w)^5 - 1; y
|
|
133
|
+
w^5 * (2090041 + 19073486126901*w + 1258902*w^2 + 674*w^3 + 16785*w^4) + O(w^100)
|
|
134
|
+
|
|
135
|
+
You can get at the underlying ntl representation::
|
|
136
|
+
|
|
137
|
+
sage: # needs sage.libs.flint
|
|
138
|
+
sage: z._ntl_rep()
|
|
139
|
+
[6 95367431640505 25 95367431640560 5]
|
|
140
|
+
sage: y._ntl_rep()
|
|
141
|
+
[5 95367431640505 25 95367431640560 5]
|
|
142
|
+
sage: y._ntl_rep_abs()
|
|
143
|
+
([5 95367431640505 25 95367431640560 5], 0)
|
|
144
|
+
|
|
145
|
+
.. NOTE::
|
|
146
|
+
|
|
147
|
+
If you get an error ``internal error: can't grow this _ntl_gbigint,``
|
|
148
|
+
it indicates that moduli are being mixed inappropriately somewhere.
|
|
149
|
+
|
|
150
|
+
For example, when calling a function with a ``ZZ_pX_c`` as an
|
|
151
|
+
argument, it copies. If the modulus is not
|
|
152
|
+
set to the modulus of the ``ZZ_pX_c``, you can get errors.
|
|
153
|
+
|
|
154
|
+
AUTHORS:
|
|
155
|
+
|
|
156
|
+
- David Roe (2008-01-01): initial version
|
|
157
|
+
|
|
158
|
+
- Robert Harron (2011-09): fixes/enhancements
|
|
159
|
+
|
|
160
|
+
- Julian Rueth (2012-10-15): fixed an initialization bug
|
|
161
|
+
"""
|
|
162
|
+
# ****************************************************************************
|
|
163
|
+
# Copyright (C) 2008 David Roe <roed.math@gmail.com>
|
|
164
|
+
# William Stein <wstein@gmail.com>
|
|
165
|
+
# 2012 Julian Rueth <julian.rueth@fsfe.org>
|
|
166
|
+
#
|
|
167
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
168
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
169
|
+
# the License, or (at your option) any later version.
|
|
170
|
+
#
|
|
171
|
+
# https://www.gnu.org/licenses/
|
|
172
|
+
# ****************************************************************************
|
|
173
|
+
|
|
174
|
+
from cysignals.signals cimport sig_on, sig_off
|
|
175
|
+
from sage.ext.stdsage cimport PY_NEW
|
|
176
|
+
include "sage/libs/ntl/decl.pxi"
|
|
177
|
+
|
|
178
|
+
from sage.rings.integer cimport Integer
|
|
179
|
+
from sage.rings.rational cimport Rational
|
|
180
|
+
from sage.libs.gmp.mpz cimport *
|
|
181
|
+
from sage.libs.gmp.mpq cimport *
|
|
182
|
+
from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
|
|
183
|
+
from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
|
|
184
|
+
from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p
|
|
185
|
+
from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class
|
|
186
|
+
from sage.rings.padics.padic_generic_element cimport pAdicGenericElement
|
|
187
|
+
from cypari2.gen import Gen as pari_gen
|
|
188
|
+
from sage.interfaces.abc import GpElement
|
|
189
|
+
from sage.rings.finite_rings.integer_mod import IntegerMod_abstract
|
|
190
|
+
from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
|
|
191
|
+
from sage.rings.padics.padic_ext_element cimport pAdicExtElement
|
|
192
|
+
from sage.rings.padics.precision_error import PrecisionError
|
|
193
|
+
|
|
194
|
+
cdef object infinity
|
|
195
|
+
from sage.rings.infinity import infinity
|
|
196
|
+
|
|
197
|
+
cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) -1
|
|
198
|
+
|
|
199
|
+
cdef class pAdicZZpXCAElement(pAdicZZpXElement):
|
|
200
|
+
def __init__(self, parent, x, absprec=infinity, relprec=infinity, empty=False):
|
|
201
|
+
"""
|
|
202
|
+
Create an element of a capped absolute precision, unramified or
|
|
203
|
+
Eisenstein extension of Zp or Qp.
|
|
204
|
+
|
|
205
|
+
INPUT:
|
|
206
|
+
|
|
207
|
+
- ``parent`` -- either an ``EisensteinRingCappedAbsolute`` or
|
|
208
|
+
``UnramifiedRingCappedAbsolute``
|
|
209
|
+
|
|
210
|
+
- ``x`` -- integer, rational, `p`-adic element, polynomial,
|
|
211
|
+
list, integer_mod, pari int/frac/poly_t/pol_mod, an
|
|
212
|
+
``ntl_ZZ_pX``, an ``ntl_ZZ``, an ``ntl_ZZ_p``, an
|
|
213
|
+
``ntl_ZZX``, or something convertible into parent.residue_field()
|
|
214
|
+
|
|
215
|
+
- ``absprec`` -- an upper bound on the absolute precision of
|
|
216
|
+
the element created
|
|
217
|
+
|
|
218
|
+
- ``relprec`` -- an upper bound on the relative precision of
|
|
219
|
+
the element created
|
|
220
|
+
|
|
221
|
+
- ``empty`` -- whether to return after initializing to zero
|
|
222
|
+
|
|
223
|
+
EXAMPLES::
|
|
224
|
+
|
|
225
|
+
sage: R = ZpCA(5,5)
|
|
226
|
+
sage: S.<x> = ZZ[]
|
|
227
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
228
|
+
sage: W.<w> = R.ext(f)
|
|
229
|
+
sage: z = (1+w)^5; z # indirect doctest
|
|
230
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15
|
|
231
|
+
+ 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
232
|
+
sage: W(R(3,3))
|
|
233
|
+
3 + O(w^15)
|
|
234
|
+
sage: W(pari('3 + O(5^3)'))
|
|
235
|
+
3 + O(w^15)
|
|
236
|
+
sage: W(w, 14)
|
|
237
|
+
w + O(w^14)
|
|
238
|
+
|
|
239
|
+
TESTS:
|
|
240
|
+
|
|
241
|
+
Check that :issue:`13600` is fixed::
|
|
242
|
+
|
|
243
|
+
sage: K = W.fraction_field()
|
|
244
|
+
sage: W(K.zero())
|
|
245
|
+
O(w^25)
|
|
246
|
+
sage: W(K.one())
|
|
247
|
+
1 + O(w^25)
|
|
248
|
+
sage: W(K.zero().add_bigoh(3))
|
|
249
|
+
O(w^3)
|
|
250
|
+
|
|
251
|
+
Check that :issue:`3865` is fixed:
|
|
252
|
+
|
|
253
|
+
sage: W(gp('5 + O(5^2)'))
|
|
254
|
+
w^5 + 2*w^7 + 4*w^9 + O(w^10)
|
|
255
|
+
|
|
256
|
+
Check that :issue:`13612` has been fixed::
|
|
257
|
+
|
|
258
|
+
sage: # needs sage.libs.flint
|
|
259
|
+
sage: R = ZpCA(3)
|
|
260
|
+
sage: S.<a> = R[]
|
|
261
|
+
sage: W.<a> = R.extension(a^2 + 1)
|
|
262
|
+
sage: W(W.residue_field().zero())
|
|
263
|
+
O(3)
|
|
264
|
+
"""
|
|
265
|
+
pAdicZZpXElement.__init__(self, parent)
|
|
266
|
+
cdef long aprec, rprec, ctx_prec
|
|
267
|
+
if empty:
|
|
268
|
+
self.absprec = 0
|
|
269
|
+
return
|
|
270
|
+
self.absprec = -1 # to signal that self is uninitialized
|
|
271
|
+
if absprec is infinity:
|
|
272
|
+
aprec = self.prime_pow.ram_prec_cap
|
|
273
|
+
else:
|
|
274
|
+
if not isinstance(absprec, Integer):
|
|
275
|
+
absprec = Integer(absprec)
|
|
276
|
+
if mpz_sgn((<Integer>absprec).value) < 0:
|
|
277
|
+
aprec = 0
|
|
278
|
+
elif mpz_fits_slong_p((<Integer>absprec).value) == 0:
|
|
279
|
+
aprec = self.prime_pow.ram_prec_cap
|
|
280
|
+
else:
|
|
281
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
282
|
+
if aprec > self.prime_pow.ram_prec_cap:
|
|
283
|
+
aprec = self.prime_pow.ram_prec_cap
|
|
284
|
+
if relprec is infinity:
|
|
285
|
+
# This might not be the right default
|
|
286
|
+
rprec = self.prime_pow.ram_prec_cap
|
|
287
|
+
else:
|
|
288
|
+
if not isinstance(relprec, Integer):
|
|
289
|
+
rprec = Integer(relprec)
|
|
290
|
+
if mpz_cmp_ui((<Integer>relprec).value, aprec) >= 0:
|
|
291
|
+
rprec = self.prime_pow.ram_prec_cap
|
|
292
|
+
elif relprec < 0:
|
|
293
|
+
rprec = 0
|
|
294
|
+
else:
|
|
295
|
+
rprec = mpz_get_si((<Integer>relprec).value)
|
|
296
|
+
cdef mpz_t tmp
|
|
297
|
+
cdef ZZ_c tmp_z
|
|
298
|
+
cdef Py_ssize_t i
|
|
299
|
+
cdef Integer tmp_Int
|
|
300
|
+
cdef Integer xlift
|
|
301
|
+
if isinstance(x, pAdicGenericElement):
|
|
302
|
+
if x.valuation() < 0:
|
|
303
|
+
raise ValueError("element has negative valuation")
|
|
304
|
+
if x._is_base_elt(self.prime_pow.prime):
|
|
305
|
+
xlift = <Integer>x.lift()
|
|
306
|
+
if mpz_sgn(xlift.value) == 0:
|
|
307
|
+
if (<pAdicGenericElement>x)._is_exact_zero():
|
|
308
|
+
self._set_inexact_zero(aprec)
|
|
309
|
+
return
|
|
310
|
+
ltmp = mpz_get_si((<Integer>x.precision_absolute()).value) * self.prime_pow.e
|
|
311
|
+
if ltmp < aprec:
|
|
312
|
+
aprec = ltmp
|
|
313
|
+
if relprec is infinity:
|
|
314
|
+
self._set_from_mpz_abs(xlift.value, aprec)
|
|
315
|
+
else:
|
|
316
|
+
self._set_from_mpz_both(xlift.value, aprec, rprec)
|
|
317
|
+
return
|
|
318
|
+
if parent.prime() != x.parent().prime():
|
|
319
|
+
raise TypeError("cannot coerce between p-adic parents with different primes")
|
|
320
|
+
if isinstance(x, pari_gen) or isinstance(x, GpElement):
|
|
321
|
+
if isinstance(x, GpElement):
|
|
322
|
+
x = x.__pari__()
|
|
323
|
+
if x.type() == "t_PADIC":
|
|
324
|
+
if x.variable() != self.prime_pow.prime:
|
|
325
|
+
raise TypeError("cannot coerce a pari p-adic with the wrong prime")
|
|
326
|
+
ltmp = x.padicprec(self.prime_pow.prime) * self.prime_pow.e
|
|
327
|
+
if ltmp < aprec:
|
|
328
|
+
aprec = ltmp
|
|
329
|
+
x = x.lift()
|
|
330
|
+
if x.type() == 't_INT':
|
|
331
|
+
x = Integer(x)
|
|
332
|
+
elif x.type() == 't_FRAC':
|
|
333
|
+
x = Rational(x)
|
|
334
|
+
elif x.type() == 't_POLMOD' or x.type == 't_POL':
|
|
335
|
+
# This code doesn't check to see if the primes are the same.
|
|
336
|
+
L = []
|
|
337
|
+
x = x.lift().lift()
|
|
338
|
+
for i from 0 <= i <= x.poldegree():
|
|
339
|
+
L.append(Integer(x.polcoef(i)))
|
|
340
|
+
x = L
|
|
341
|
+
else:
|
|
342
|
+
raise TypeError("unsupported coercion from pari: only p-adics, integers, rationals, polynomials and pol_mods allowed")
|
|
343
|
+
elif isinstance(x, IntegerMod_abstract):
|
|
344
|
+
mpz_init(tmp)
|
|
345
|
+
ctx_prec = mpz_remove(tmp, (<Integer>x.modulus()).value, self.prime_pow.prime.value)
|
|
346
|
+
if mpz_cmp_ui(tmp, 1) == 0:
|
|
347
|
+
mpz_clear(tmp)
|
|
348
|
+
x = x.lift()
|
|
349
|
+
if ctx_prec < aprec:
|
|
350
|
+
aprec = ctx_prec
|
|
351
|
+
else:
|
|
352
|
+
mpz_clear(tmp)
|
|
353
|
+
raise TypeError("cannot coerce from the given integer mod ring (not a power of the same prime)")
|
|
354
|
+
elif isinstance(x, ntl_ZZ_p):
|
|
355
|
+
ctx_prec = ZZ_remove(tmp_z, (<ntl_ZZ>x.modulus()).x, self.prime_pow.pow_ZZ_tmp(1)[0])
|
|
356
|
+
if ZZ_IsOne(tmp_z):
|
|
357
|
+
x = x.lift()
|
|
358
|
+
tmp_Int = PY_NEW(Integer)
|
|
359
|
+
ZZ_to_mpz(tmp_Int.value, &(<ntl_ZZ>x).x)
|
|
360
|
+
x = tmp_Int
|
|
361
|
+
if ctx_prec < aprec:
|
|
362
|
+
aprec = ctx_prec
|
|
363
|
+
else:
|
|
364
|
+
raise TypeError("cannot coerce the given ntl_ZZ_p (modulus not a power of the same prime)")
|
|
365
|
+
elif isinstance(x, ntl_ZZ):
|
|
366
|
+
tmp_Int = PY_NEW(Integer)
|
|
367
|
+
ZZ_to_mpz(tmp_Int.value, &(<ntl_ZZ>x).x)
|
|
368
|
+
x = tmp_Int
|
|
369
|
+
elif isinstance(x, int):
|
|
370
|
+
x = Integer(x)
|
|
371
|
+
elif x in parent.residue_field() and x.parent().is_finite():
|
|
372
|
+
# Should only reach here if x is not in F_p
|
|
373
|
+
z = parent.gen()
|
|
374
|
+
poly = x.polynomial().list()
|
|
375
|
+
x = sum([poly[i].lift() * (z ** i) for i in range(len(poly))], parent.zero())
|
|
376
|
+
if 1 < aprec:
|
|
377
|
+
aprec = 1
|
|
378
|
+
cdef pAdicZZpXCAElement _x
|
|
379
|
+
cdef pAdicZZpXCRElement __x
|
|
380
|
+
if isinstance(x, Integer):
|
|
381
|
+
if relprec is infinity:
|
|
382
|
+
self._set_from_mpz_abs((<Integer>x).value, aprec)
|
|
383
|
+
else:
|
|
384
|
+
self._set_from_mpz_both((<Integer>x).value, aprec, rprec)
|
|
385
|
+
elif isinstance(x, Rational):
|
|
386
|
+
if relprec is infinity:
|
|
387
|
+
self._set_from_mpq_abs((<Rational>x).value, aprec)
|
|
388
|
+
else:
|
|
389
|
+
self._set_from_mpq_both((<Rational>x).value, aprec, rprec)
|
|
390
|
+
elif isinstance(x, ntl_ZZ_pX):
|
|
391
|
+
if relprec is infinity:
|
|
392
|
+
self._set_from_ZZ_pX_abs(&(<ntl_ZZ_pX>x).x, (<ntl_ZZ_pX>x).c, aprec)
|
|
393
|
+
else:
|
|
394
|
+
self._set_from_ZZ_pX_both(&(<ntl_ZZ_pX>x).x, (<ntl_ZZ_pX>x).c, aprec, rprec)
|
|
395
|
+
elif isinstance(x, ntl_ZZX):
|
|
396
|
+
if relprec is infinity:
|
|
397
|
+
self._set_from_ZZX_abs((<ntl_ZZX>x).x, aprec)
|
|
398
|
+
else:
|
|
399
|
+
self._set_from_ZZX_both((<ntl_ZZX>x).x, aprec, rprec)
|
|
400
|
+
elif isinstance(x, pAdicExtElement):
|
|
401
|
+
if x.parent() is parent:
|
|
402
|
+
_x = <pAdicZZpXCAElement>x
|
|
403
|
+
if _x.absprec < aprec:
|
|
404
|
+
aprec = _x.absprec
|
|
405
|
+
if rprec < self.prime_pow.ram_prec_cap:
|
|
406
|
+
self._set_from_ZZ_pX_both(&_x.value, None, aprec, rprec)
|
|
407
|
+
else:
|
|
408
|
+
self._set(&_x.value, aprec)
|
|
409
|
+
elif x.parent() is parent.fraction_field():
|
|
410
|
+
__x = <pAdicZZpXCRElement>x
|
|
411
|
+
if __x.relprec < 0:
|
|
412
|
+
__x._normalize()
|
|
413
|
+
if __x._is_exact_zero():
|
|
414
|
+
self._set_inexact_zero(self.prime_pow.ram_prec_cap)
|
|
415
|
+
elif __x.ordp < 0:
|
|
416
|
+
raise ValueError("x has negative valuation")
|
|
417
|
+
elif __x._is_inexact_zero():
|
|
418
|
+
if __x.ordp <= self.prime_pow.ram_prec_cap:
|
|
419
|
+
self._set_inexact_zero(__x.ordp)
|
|
420
|
+
else:
|
|
421
|
+
self._set_inexact_zero(self.prime_pow.ram_prec_cap)
|
|
422
|
+
else:
|
|
423
|
+
poly = __x._ntl_rep_abs()[0]
|
|
424
|
+
if __x.relprec < rprec:
|
|
425
|
+
rprec = __x.relprec
|
|
426
|
+
if rprec + __x.ordp < aprec:
|
|
427
|
+
aprec = rprec + __x.ordp
|
|
428
|
+
self._set(&(<ntl_ZZ_pX>poly).x, aprec)
|
|
429
|
+
else:
|
|
430
|
+
raise NotImplementedError("conversion from different p-adic extensions not yet supported")
|
|
431
|
+
else:
|
|
432
|
+
try:
|
|
433
|
+
x = list(x)
|
|
434
|
+
except TypeError:
|
|
435
|
+
try:
|
|
436
|
+
x = x.list()
|
|
437
|
+
except AttributeError:
|
|
438
|
+
raise TypeError("cannot convert x to a p-adic element")
|
|
439
|
+
self._set_from_list_both(x, aprec, rprec)
|
|
440
|
+
|
|
441
|
+
cdef int _set_inexact_zero(self, long absprec) except -1:
|
|
442
|
+
"""
|
|
443
|
+
Set ``self`` to be zero with valuation ``absprec``.
|
|
444
|
+
|
|
445
|
+
EXAMPLES::
|
|
446
|
+
|
|
447
|
+
sage: R = ZpCA(5,5)
|
|
448
|
+
sage: S.<x> = ZZ[]
|
|
449
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
450
|
+
sage: W.<w> = R.ext(f)
|
|
451
|
+
sage: z = W(0,6); z # indirect doctest
|
|
452
|
+
O(w^6)
|
|
453
|
+
sage: z.valuation()
|
|
454
|
+
6
|
|
455
|
+
sage: z.precision_absolute()
|
|
456
|
+
6
|
|
457
|
+
sage: z.precision_relative()
|
|
458
|
+
0
|
|
459
|
+
"""
|
|
460
|
+
if absprec == self.absprec:
|
|
461
|
+
ZZ_pX_clear(self.value)
|
|
462
|
+
else:
|
|
463
|
+
self._set_prec_abs(absprec)
|
|
464
|
+
|
|
465
|
+
cpdef bint _is_inexact_zero(self) except -1:
|
|
466
|
+
"""
|
|
467
|
+
Test if ``self`` is an inexact zero.
|
|
468
|
+
|
|
469
|
+
EXAMPLES::
|
|
470
|
+
|
|
471
|
+
sage: R = ZpCA(5,5)
|
|
472
|
+
sage: S.<x> = ZZ[]
|
|
473
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
474
|
+
sage: W.<w> = R.ext(f)
|
|
475
|
+
sage: z = W(0)
|
|
476
|
+
sage: z._is_inexact_zero() # indirect doctest
|
|
477
|
+
True
|
|
478
|
+
sage: z = W(0,6)
|
|
479
|
+
sage: z._is_inexact_zero()
|
|
480
|
+
True
|
|
481
|
+
"""
|
|
482
|
+
return self.absprec == 0 or ZZ_pX_IsZero(self.value) or self.valuation_c() == self.absprec
|
|
483
|
+
|
|
484
|
+
cdef int _set(self, ZZ_pX_c* value, long absprec) except -1:
|
|
485
|
+
"""
|
|
486
|
+
Set ``value`` and ``absprec`` directly.
|
|
487
|
+
|
|
488
|
+
EXAMPLES::
|
|
489
|
+
|
|
490
|
+
sage: R = ZpCA(5,5)
|
|
491
|
+
sage: S.<x> = ZZ[]
|
|
492
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
493
|
+
sage: W.<w> = R.ext(f)
|
|
494
|
+
sage: F = W.fraction_field()
|
|
495
|
+
sage: z = F(1+w); z # indirect doctest
|
|
496
|
+
1 + w + O(w^25)
|
|
497
|
+
sage: W.precision_cap()
|
|
498
|
+
25
|
|
499
|
+
sage: F.precision_cap()
|
|
500
|
+
25
|
|
501
|
+
"""
|
|
502
|
+
self._set_prec_abs(absprec) # restores context
|
|
503
|
+
if self.absprec != 0:
|
|
504
|
+
ZZ_pX_conv_modulus(self.value, value[0], self.prime_pow.get_context_capdiv(absprec).x)
|
|
505
|
+
|
|
506
|
+
cdef int _set_from_mpz_abs(self, mpz_t x, long absprec) except -1:
|
|
507
|
+
"""
|
|
508
|
+
Set ``self`` from an ``mpz_t`` with absolute precision
|
|
509
|
+
bounded by ``absprec``.
|
|
510
|
+
|
|
511
|
+
EXAMPLES::
|
|
512
|
+
|
|
513
|
+
sage: R = ZpCA(5,5)
|
|
514
|
+
sage: S.<x> = ZZ[]
|
|
515
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
516
|
+
sage: W.<w> = R.ext(f)
|
|
517
|
+
sage: W(70, absprec = 13) # indirect doctest
|
|
518
|
+
4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
|
|
519
|
+
sage: W(70, absprec = 4)
|
|
520
|
+
O(w^4)
|
|
521
|
+
sage: W(70, absprec = 0)
|
|
522
|
+
O(w^0)
|
|
523
|
+
"""
|
|
524
|
+
self._set_prec_abs(absprec) # restores context
|
|
525
|
+
cdef mpz_t tmp_m
|
|
526
|
+
cdef ZZ_c tmp_z
|
|
527
|
+
if self.absprec != 0:
|
|
528
|
+
mpz_init_set(tmp_m, x)
|
|
529
|
+
mpz_to_ZZ(&tmp_z, tmp_m)
|
|
530
|
+
mpz_clear(tmp_m)
|
|
531
|
+
ZZ_pX_SetCoeff(self.value, 0, ZZ_to_ZZ_p(tmp_z))
|
|
532
|
+
|
|
533
|
+
cdef int _set_from_mpz_both(self, mpz_t x, long absprec, long relprec) except -1:
|
|
534
|
+
"""
|
|
535
|
+
Set ``self`` from an ``mpz_t`` with relative precision
|
|
536
|
+
bounded by ``relprec`` and absolute precision bounded by
|
|
537
|
+
``absprec``.
|
|
538
|
+
|
|
539
|
+
EXAMPLES::
|
|
540
|
+
|
|
541
|
+
sage: R = ZpCA(5,5)
|
|
542
|
+
sage: S.<x> = ZZ[]
|
|
543
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
544
|
+
sage: W.<w> = R.ext(f)
|
|
545
|
+
sage: W(70, relprec = 3) # indirect doctest
|
|
546
|
+
4*w^5 + 3*w^7 + O(w^8)
|
|
547
|
+
sage: W(70, absprec = 4, relprec = 2)
|
|
548
|
+
O(w^4)
|
|
549
|
+
sage: W(70, absprec = 0, relprec = 3)
|
|
550
|
+
O(w^0)
|
|
551
|
+
"""
|
|
552
|
+
if mpz_sgn(x) == 0:
|
|
553
|
+
self._set_inexact_zero(absprec)
|
|
554
|
+
return 0
|
|
555
|
+
cdef mpz_t tmp_m
|
|
556
|
+
cdef ZZ_c tmp_z
|
|
557
|
+
cdef long shift
|
|
558
|
+
mpz_init(tmp_m)
|
|
559
|
+
sig_on()
|
|
560
|
+
shift = mpz_remove(tmp_m, x, self.prime_pow.prime.value)
|
|
561
|
+
mpz_set(tmp_m, x)
|
|
562
|
+
sig_off()
|
|
563
|
+
self._set_prec_both_with_ordp(shift * self.prime_pow.e, absprec, relprec)
|
|
564
|
+
mpz_to_ZZ(&tmp_z, tmp_m)
|
|
565
|
+
mpz_clear(tmp_m)
|
|
566
|
+
if self.absprec != 0:
|
|
567
|
+
ZZ_pX_SetCoeff(self.value, 0, ZZ_to_ZZ_p(tmp_z))
|
|
568
|
+
|
|
569
|
+
cdef int _set_from_mpq_abs(self, mpq_t x, long absprec) except -1:
|
|
570
|
+
"""
|
|
571
|
+
Set ``self`` from an ``mpq_t`` with absolute precision bounded by
|
|
572
|
+
``absprec``.
|
|
573
|
+
|
|
574
|
+
EXAMPLES::
|
|
575
|
+
|
|
576
|
+
sage: R = ZpCA(5,5)
|
|
577
|
+
sage: S.<x> = ZZ[]
|
|
578
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
579
|
+
sage: W.<w> = R.ext(f)
|
|
580
|
+
sage: z = W(70/3, 14); z # indirect doctest
|
|
581
|
+
3*w^5 + w^7 + 2*w^9 + 2*w^10 + 4*w^11 + w^12 + 2*w^13 + O(w^14)
|
|
582
|
+
sage: z * 3
|
|
583
|
+
4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + O(w^14)
|
|
584
|
+
sage: W(70)
|
|
585
|
+
4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + 3*w^16 + w^17 + w^18 + 4*w^20 + 4*w^21 + w^22 + 2*w^23 + O(w^25)
|
|
586
|
+
sage: W(70/3, absprec = 4)
|
|
587
|
+
O(w^4)
|
|
588
|
+
sage: W(70/3, absprec = 0)
|
|
589
|
+
O(w^0)
|
|
590
|
+
"""
|
|
591
|
+
if mpq_sgn(x) == 0:
|
|
592
|
+
self._set_inexact_zero(absprec)
|
|
593
|
+
return 0
|
|
594
|
+
if mpz_divisible_p(mpq_denref(x), self.prime_pow.prime.value):
|
|
595
|
+
raise ValueError("p divides the denominator")
|
|
596
|
+
self._set_prec_abs(absprec) # restores context
|
|
597
|
+
self._set_from_mpq_part2(x)
|
|
598
|
+
|
|
599
|
+
cdef int _set_from_mpq_both(self, mpq_t x, long absprec, long relprec) except -1:
|
|
600
|
+
"""
|
|
601
|
+
Set ``self`` from an ``mpq_t`` with relative precision bounded by
|
|
602
|
+
``relprec`` and absolute precision bounded by ``absprec``.
|
|
603
|
+
|
|
604
|
+
EXAMPLES::
|
|
605
|
+
|
|
606
|
+
sage: R = ZpCA(5,5)
|
|
607
|
+
sage: S.<x> = ZZ[]
|
|
608
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
609
|
+
sage: W.<w> = R.ext(f)
|
|
610
|
+
sage: z = W(70/3, 14); z # indirect doctest
|
|
611
|
+
3*w^5 + w^7 + 2*w^9 + 2*w^10 + 4*w^11 + w^12 + 2*w^13 + O(w^14)
|
|
612
|
+
sage: z * 3
|
|
613
|
+
4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + O(w^14)
|
|
614
|
+
sage: W(70)
|
|
615
|
+
4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + 3*w^16 + w^17 + w^18 + 4*w^20 + 4*w^21 + w^22 + 2*w^23 + O(w^25)
|
|
616
|
+
sage: W(70/3, absprec = 0, relprec = 1)
|
|
617
|
+
O(w^0)
|
|
618
|
+
"""
|
|
619
|
+
if mpq_sgn(x) == 0:
|
|
620
|
+
self._set_inexact_zero(absprec)
|
|
621
|
+
return 0
|
|
622
|
+
cdef long num_ordp
|
|
623
|
+
cdef mpz_t num_unit
|
|
624
|
+
if mpz_divisible_p(mpq_denref(x), self.prime_pow.prime.value):
|
|
625
|
+
raise ValueError("p divides the denominator")
|
|
626
|
+
sig_on()
|
|
627
|
+
mpz_init(num_unit)
|
|
628
|
+
num_ordp = mpz_remove(num_unit, mpq_numref(x), self.prime_pow.prime.value)
|
|
629
|
+
mpz_clear(num_unit)
|
|
630
|
+
sig_off()
|
|
631
|
+
self._set_prec_both_with_ordp(num_ordp * self.prime_pow.e, absprec, relprec) # restores context
|
|
632
|
+
self._set_from_mpq_part2(x)
|
|
633
|
+
|
|
634
|
+
cdef int _set_from_mpq_part2(self, mpq_t x) except -1:
|
|
635
|
+
"""
|
|
636
|
+
Given that the appropriate context has been restored, sets
|
|
637
|
+
``self`` from ``x``.
|
|
638
|
+
|
|
639
|
+
TESTS::
|
|
640
|
+
|
|
641
|
+
sage: R = ZpCA(5,5)
|
|
642
|
+
sage: S.<x> = ZZ[]
|
|
643
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
644
|
+
sage: W.<w> = R.ext(f)
|
|
645
|
+
sage: W(QQ(4), 23) # indirect doctest
|
|
646
|
+
4 + O(w^23)
|
|
647
|
+
"""
|
|
648
|
+
cdef mpz_t tmp_m
|
|
649
|
+
cdef ZZ_c den_z, num_z
|
|
650
|
+
cdef ZZ_p_c value
|
|
651
|
+
if self.absprec != 0:
|
|
652
|
+
mpz_init_set(tmp_m, mpq_numref(x))
|
|
653
|
+
mpz_to_ZZ(&num_z, tmp_m)
|
|
654
|
+
mpz_set(tmp_m, mpq_denref(x))
|
|
655
|
+
mpz_to_ZZ(&den_z, tmp_m)
|
|
656
|
+
mpz_clear(tmp_m)
|
|
657
|
+
ZZ_p_div(value, ZZ_to_ZZ_p(num_z), ZZ_to_ZZ_p(den_z))
|
|
658
|
+
ZZ_pX_SetCoeff(self.value, 0, value)
|
|
659
|
+
|
|
660
|
+
cdef int _set_from_ZZX_abs(self, ZZX_c poly, long absprec) except -1:
|
|
661
|
+
"""
|
|
662
|
+
Set ``self`` from a ``ZZX`` with absolute precision bounded by
|
|
663
|
+
``absprec``.
|
|
664
|
+
|
|
665
|
+
EXAMPLES::
|
|
666
|
+
|
|
667
|
+
sage: R = ZpCA(5,5)
|
|
668
|
+
sage: S.<x> = ZZ[]
|
|
669
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
670
|
+
sage: W.<w> = R.ext(f)
|
|
671
|
+
sage: z = W(ntl.ZZX([4,1,16]), absprec = 14); z # indirect doctest
|
|
672
|
+
4 + w + w^2 + 3*w^7 + w^9 + 2*w^11 + 4*w^13 + O(w^14)
|
|
673
|
+
sage: z._ntl_rep()
|
|
674
|
+
[4 1 16]
|
|
675
|
+
sage: W(ntl.ZZX([4,1,16]), absprec = 0)
|
|
676
|
+
O(w^0)
|
|
677
|
+
"""
|
|
678
|
+
self._set_prec_abs(absprec)
|
|
679
|
+
cdef ZZ_pX_c poly_p
|
|
680
|
+
if self.absprec != 0:
|
|
681
|
+
ZZX_to_ZZ_pX(poly_p, poly)
|
|
682
|
+
self._set_from_ZZ_pX_abs(&poly_p, None, absprec)
|
|
683
|
+
|
|
684
|
+
cdef int _set_from_ZZX_both(self, ZZX_c poly, long absprec, long relprec) except -1:
|
|
685
|
+
"""
|
|
686
|
+
Set ``self`` from a ``ZZX`` with relative precision bounded by
|
|
687
|
+
``relprec`` and absolute precision bounded by ``absprec``.
|
|
688
|
+
|
|
689
|
+
EXAMPLES::
|
|
690
|
+
|
|
691
|
+
sage: R = ZpCA(5,5)
|
|
692
|
+
sage: S.<x> = ZZ[]
|
|
693
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
694
|
+
sage: W.<w> = R.ext(f)
|
|
695
|
+
sage: z = W(ntl.ZZX([4,1,16]), relprec = 12); z # indirect doctest
|
|
696
|
+
4 + w + w^2 + 3*w^7 + w^9 + 2*w^11 + O(w^12)
|
|
697
|
+
sage: z._ntl_rep()
|
|
698
|
+
[4 1 16]
|
|
699
|
+
sage: W(ntl.ZZX([4,1,16]), absprec = 0, relprec = 4)
|
|
700
|
+
O(w^0)
|
|
701
|
+
"""
|
|
702
|
+
self._set_prec_abs(absprec)
|
|
703
|
+
cdef ZZ_pX_c poly_p
|
|
704
|
+
if self.absprec != 0:
|
|
705
|
+
ZZX_to_ZZ_pX(poly_p, poly)
|
|
706
|
+
self._set_from_ZZ_pX_both(&poly_p, None, absprec, relprec)
|
|
707
|
+
|
|
708
|
+
cdef int _set_from_ZZ_pX_abs(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec) except -1:
|
|
709
|
+
"""
|
|
710
|
+
Set ``self`` from a ``ZZ_pX`` with absolute precision bounded by
|
|
711
|
+
``absprec`` (and by ``ctx``).
|
|
712
|
+
|
|
713
|
+
EXAMPLES::
|
|
714
|
+
|
|
715
|
+
sage: R = ZpCA(5,5)
|
|
716
|
+
sage: S.<x> = ZZ[]
|
|
717
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
718
|
+
sage: W.<w> = R.ext(f)
|
|
719
|
+
sage: z = W(ntl.ZZ_pX([4,1,16],5^2)); z # indirect doctest
|
|
720
|
+
4 + w + w^2 + 3*w^7 + w^9 + O(w^10)
|
|
721
|
+
sage: z._ntl_rep()
|
|
722
|
+
[4 1 16]
|
|
723
|
+
sage: W(ntl.ZZ_pX([4,1,16],5^2), absprec = 0)
|
|
724
|
+
O(w^0)
|
|
725
|
+
"""
|
|
726
|
+
cdef long ctx_prec = -1
|
|
727
|
+
if ctx is not None:
|
|
728
|
+
ctx_prec = self._check_ZZ_pContext(ctx) * self.prime_pow.e
|
|
729
|
+
if ctx_prec < absprec:
|
|
730
|
+
absprec = ctx_prec
|
|
731
|
+
if ZZ_pX_IsZero(poly[0]):
|
|
732
|
+
self._set_inexact_zero(absprec)
|
|
733
|
+
return 0
|
|
734
|
+
self._set_prec_abs(absprec) # restores context
|
|
735
|
+
if self.absprec != 0:
|
|
736
|
+
ZZ_pX_conv_modulus(self.value, poly[0], self.prime_pow.get_context_capdiv(absprec).x)
|
|
737
|
+
|
|
738
|
+
cdef int _set_from_ZZ_pX_both(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec, long relprec) except -1:
|
|
739
|
+
"""
|
|
740
|
+
Set ``self`` from a ``ZZ_pX`` with relative precision bounded by
|
|
741
|
+
``relprec`` and absolute precision bounded by ``absprec``.
|
|
742
|
+
|
|
743
|
+
EXAMPLES::
|
|
744
|
+
|
|
745
|
+
sage: R = ZpCA(5,5)
|
|
746
|
+
sage: S.<x> = ZZ[]
|
|
747
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
748
|
+
sage: W.<w> = R.ext(f)
|
|
749
|
+
sage: z = W(ntl.ZZ_pX([4,1,16],5^2), absprec = 8, relprec = 12); z # indirect doctest
|
|
750
|
+
4 + w + w^2 + 3*w^7 + O(w^8)
|
|
751
|
+
sage: z._ntl_rep()
|
|
752
|
+
[4 1 16]
|
|
753
|
+
sage: W(ntl.ZZ_pX([4,1,16],5^2), absprec = 0, relprec = 5)
|
|
754
|
+
O(w^0)
|
|
755
|
+
"""
|
|
756
|
+
cdef long ctx_prec
|
|
757
|
+
if ctx is not None:
|
|
758
|
+
ctx_prec = self._check_ZZ_pContext(ctx)
|
|
759
|
+
if ctx_prec * self.prime_pow.e < absprec:
|
|
760
|
+
absprec = ctx_prec * self.prime_pow.e
|
|
761
|
+
if ZZ_pX_IsZero(poly[0]):
|
|
762
|
+
self._set_inexact_zero(absprec)
|
|
763
|
+
return 0
|
|
764
|
+
cdef long val = 0, index = 0
|
|
765
|
+
ZZ_pX_min_val_coeff(val, index, poly[0], self.prime_pow.pow_ZZ_tmp(1)[0])
|
|
766
|
+
if self.prime_pow.e == 1:
|
|
767
|
+
self._set_prec_both_with_ordp(val, absprec, relprec) #restores context
|
|
768
|
+
else:
|
|
769
|
+
self._set_prec_both_with_ordp(val * self.prime_pow.e + index, absprec, relprec) # restores context
|
|
770
|
+
if self.absprec != 0:
|
|
771
|
+
ZZ_pX_conv_modulus(self.value, poly[0], self.prime_pow.get_context_capdiv(self.absprec).x)
|
|
772
|
+
|
|
773
|
+
cdef bint _set_prec_abs(self, long absprec) except -1:
|
|
774
|
+
"""
|
|
775
|
+
Safely set the absolute precision of ``self`` to ``absprec``.
|
|
776
|
+
|
|
777
|
+
Returns ``True`` iff ``self.absprec`` was reset.
|
|
778
|
+
|
|
779
|
+
Note that this will wipe out anything in ``self.value``. Be
|
|
780
|
+
careful resetting ``self.value`` directly: if you set it to a
|
|
781
|
+
different modulus, NTL may have problems. The safest way to
|
|
782
|
+
reset ``self.value`` to a different modulus is::
|
|
783
|
+
|
|
784
|
+
self.prime_pow.restore_context_capdiv(self.absprec)
|
|
785
|
+
cdef ZZ_pX_c tmp = self.value
|
|
786
|
+
self._set_prec_abs(new_abs_prec)
|
|
787
|
+
ZZ_pX_conv_modulus(self.value, tmp, self.prime_pow.get_context_capdiv(self.absprec).x)
|
|
788
|
+
|
|
789
|
+
If you want to speed up this process and you're decreasing
|
|
790
|
+
precision, you may be able to just set ``self.absprec`` and
|
|
791
|
+
``ZZ_pX_conv_modulus``. I haven't looked into how NTL will be
|
|
792
|
+
have in this case well enough to know if your program will
|
|
793
|
+
segfault in this case or not.
|
|
794
|
+
|
|
795
|
+
TESTS::
|
|
796
|
+
|
|
797
|
+
sage: R = ZpCA(5,5)
|
|
798
|
+
sage: S.<x> = ZZ[]
|
|
799
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
800
|
+
sage: W.<w> = R.ext(f)
|
|
801
|
+
sage: W(70, 13) # indirect doctest
|
|
802
|
+
4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
|
|
803
|
+
"""
|
|
804
|
+
if absprec < 0:
|
|
805
|
+
raise ValueError("absprec must be nonnegative")
|
|
806
|
+
if self.absprec == absprec:
|
|
807
|
+
return False
|
|
808
|
+
if absprec > 0:
|
|
809
|
+
self.prime_pow.restore_context_capdiv(absprec)
|
|
810
|
+
self.value = ZZ_pX_c()
|
|
811
|
+
self.absprec = absprec
|
|
812
|
+
return True
|
|
813
|
+
|
|
814
|
+
cdef bint _set_prec_both(self, long absprec, long relprec) except -1:
|
|
815
|
+
raise TypeError("use _set_prec_both_with_ord")
|
|
816
|
+
|
|
817
|
+
cdef bint _set_prec_both_with_ordp(self, long ordp, long absprec, long relprec) except -1:
|
|
818
|
+
"""
|
|
819
|
+
Set the absolute precision of ``self`` to the minimum of ``absprec``
|
|
820
|
+
and ``ordp + relprec``.
|
|
821
|
+
|
|
822
|
+
Note that this will wipe out anything in ``self.value``. Be
|
|
823
|
+
careful resetting ``self.value`` directly: if you set it to a
|
|
824
|
+
different modulus, NTL may have problems. The safest way to
|
|
825
|
+
reset ``self.value`` to a different modulus is::
|
|
826
|
+
|
|
827
|
+
self.prime_pow.restore_context_capdiv(self.absprec)
|
|
828
|
+
cdef ZZ_pX_c tmp = self.value
|
|
829
|
+
self._set_prec_abs(new_abs_prec)
|
|
830
|
+
ZZ_pX_conv_modulus(self.value, tmp, self.prime_pow.get_context_capdiv(self.relprec).x)
|
|
831
|
+
|
|
832
|
+
You may be able to just set ``self.absprec`` and
|
|
833
|
+
``ZZ_pX_conv_modulus`` if you're decreasing precision. I'm not
|
|
834
|
+
sure.
|
|
835
|
+
|
|
836
|
+
TESTS::
|
|
837
|
+
|
|
838
|
+
sage: R = ZpCA(5,5)
|
|
839
|
+
sage: S.<x> = ZZ[]
|
|
840
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
841
|
+
sage: W.<w> = R.ext(f)
|
|
842
|
+
sage: W(70, relprec=3) # indirect doctest
|
|
843
|
+
4*w^5 + 3*w^7 + O(w^8)
|
|
844
|
+
"""
|
|
845
|
+
if absprec <= ordp + relprec:
|
|
846
|
+
self._set_prec_abs(absprec)
|
|
847
|
+
else:
|
|
848
|
+
self._set_prec_abs(ordp + relprec)
|
|
849
|
+
|
|
850
|
+
cdef pAdicZZpXCAElement _new_c(self, long absprec):
|
|
851
|
+
"""
|
|
852
|
+
Return a new element with the same parent as ``self`` and
|
|
853
|
+
absolute precision ``absprec``.
|
|
854
|
+
|
|
855
|
+
EXAMPLES::
|
|
856
|
+
|
|
857
|
+
sage: R = ZpCA(5,5)
|
|
858
|
+
sage: S.<x> = ZZ[]
|
|
859
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
860
|
+
sage: W.<w> = R.ext(f)
|
|
861
|
+
sage: w^5 + 1 # indirect doctest
|
|
862
|
+
1 + w^5 + O(w^25)
|
|
863
|
+
"""
|
|
864
|
+
cdef pAdicZZpXCAElement ans = pAdicZZpXCAElement.__new__(pAdicZZpXCAElement)
|
|
865
|
+
ans._parent = self._parent
|
|
866
|
+
ans.prime_pow = self.prime_pow
|
|
867
|
+
ans.absprec = absprec
|
|
868
|
+
if absprec > 0:
|
|
869
|
+
self.prime_pow.restore_context_capdiv(absprec)
|
|
870
|
+
elif absprec < 0:
|
|
871
|
+
raise ValueError("absprec must be positive")
|
|
872
|
+
return ans
|
|
873
|
+
|
|
874
|
+
def __reduce__(self):
|
|
875
|
+
"""
|
|
876
|
+
Pickles ``self``.
|
|
877
|
+
|
|
878
|
+
EXAMPLES::
|
|
879
|
+
|
|
880
|
+
sage: R = Qp(5,5)
|
|
881
|
+
sage: S.<x> = ZZ[]
|
|
882
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
883
|
+
sage: W.<w> = R.ext(f)
|
|
884
|
+
sage: z = (1 + w)^5 - 1
|
|
885
|
+
sage: loads(dumps(z)) == z
|
|
886
|
+
True
|
|
887
|
+
"""
|
|
888
|
+
cdef Integer absprec
|
|
889
|
+
absprec = PY_NEW(Integer)
|
|
890
|
+
mpz_set_si(absprec.value, self.absprec)
|
|
891
|
+
if self.absprec == 0:
|
|
892
|
+
return make_ZZpXCAElement, (self.parent(), None, absprec, 0)
|
|
893
|
+
self.prime_pow.restore_context_capdiv(self.absprec)
|
|
894
|
+
cdef ntl_ZZ_pX holder = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
|
|
895
|
+
holder.c = self.prime_pow.get_context_capdiv(self.absprec)
|
|
896
|
+
holder.x = self.value
|
|
897
|
+
return make_ZZpXCAElement, (self.parent(), holder, absprec, 0)
|
|
898
|
+
|
|
899
|
+
cdef int _cmp_units(left, pAdicGenericElement right) except -2:
|
|
900
|
+
"""
|
|
901
|
+
For units ``left`` and ``right``, returns 0 if they are equal up to
|
|
902
|
+
the lesser of the two precisions, or 1 if they are not.
|
|
903
|
+
|
|
904
|
+
EXAMPLES::
|
|
905
|
+
|
|
906
|
+
sage: R = ZpCA(5,5)
|
|
907
|
+
sage: S.<x> = ZZ[]
|
|
908
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
909
|
+
sage: W.<w> = R.ext(f)
|
|
910
|
+
sage: w == 1 # indirect doctest
|
|
911
|
+
False
|
|
912
|
+
sage: y = 1 + w + O(w^7)
|
|
913
|
+
sage: z = 1 + w + w^10 + O(w^13)
|
|
914
|
+
sage: y == z
|
|
915
|
+
True
|
|
916
|
+
"""
|
|
917
|
+
# This function needs improvement. In particular, there are a lot of
|
|
918
|
+
# speed improvements to be had, and it should be changed so that it
|
|
919
|
+
# returns 1 only half the time (and -1 the other half) when left and
|
|
920
|
+
# right are not equal.
|
|
921
|
+
cdef pAdicZZpXCAElement diff = <pAdicZZpXCAElement> (left - right)
|
|
922
|
+
if diff._is_inexact_zero():
|
|
923
|
+
return 0
|
|
924
|
+
# for now, just return 1
|
|
925
|
+
return 1
|
|
926
|
+
|
|
927
|
+
def __invert__(self):
|
|
928
|
+
"""
|
|
929
|
+
Return the inverse of ``self``.
|
|
930
|
+
|
|
931
|
+
EXAMPLES::
|
|
932
|
+
|
|
933
|
+
sage: R = ZpCA(5,5)
|
|
934
|
+
sage: S.<x> = ZZ[]
|
|
935
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
936
|
+
sage: W.<w> = R.ext(f)
|
|
937
|
+
sage: z = (1 + w)^5
|
|
938
|
+
sage: y = ~z; y # indirect doctest
|
|
939
|
+
1 + 4*w^5 + 4*w^6 + 3*w^7 + w^8 + 2*w^10 + w^11 + w^12 + 2*w^14 + 3*w^16 + 3*w^17 + 4*w^18 + 4*w^19 + 2*w^20 + 2*w^21 + 4*w^22 + 3*w^23 + 3*w^24 + O(w^25)
|
|
940
|
+
sage: y.parent()
|
|
941
|
+
5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
942
|
+
sage: z = z - 1
|
|
943
|
+
sage: ~z
|
|
944
|
+
w^-5 + 4*w^-4 + 4*w^-3 + 4*w^-2 + 2*w^-1 + 1 + w + 4*w^2 + 4*w^3 + 4*w^4 + w^5 + w^6 + w^7 + 4*w^8 + 4*w^9 + 2*w^10 + w^11 + 2*w^12 + 4*w^13 + 4*w^14 + O(w^15)
|
|
945
|
+
"""
|
|
946
|
+
return ~self.to_fraction_field()
|
|
947
|
+
|
|
948
|
+
cpdef pAdicZZpXCRElement to_fraction_field(self):
|
|
949
|
+
"""
|
|
950
|
+
Return ``self`` cast into the fraction field of ``self.parent()``.
|
|
951
|
+
|
|
952
|
+
EXAMPLES::
|
|
953
|
+
|
|
954
|
+
sage: R = ZpCA(5,5)
|
|
955
|
+
sage: S.<x> = ZZ[]
|
|
956
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
957
|
+
sage: W.<w> = R.ext(f)
|
|
958
|
+
sage: z = (1 + w)^5; z
|
|
959
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
960
|
+
sage: y = z.to_fraction_field(); y # indirect doctest
|
|
961
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
962
|
+
sage: y.parent()
|
|
963
|
+
5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
964
|
+
"""
|
|
965
|
+
cdef pAdicZZpXCRElement ans = pAdicZZpXCRElement.__new__(pAdicZZpXCRElement)
|
|
966
|
+
ans._parent = self._parent.fraction_field()
|
|
967
|
+
ans.prime_pow = ans._parent.prime_pow
|
|
968
|
+
ans.ordp = 0
|
|
969
|
+
ans.relprec = -self.absprec
|
|
970
|
+
if self.absprec != 0:
|
|
971
|
+
self.prime_pow.restore_context_capdiv(self.absprec)
|
|
972
|
+
ans.unit = self.value
|
|
973
|
+
return ans
|
|
974
|
+
|
|
975
|
+
cdef pAdicZZpXCAElement _lshift_c(self, long n):
|
|
976
|
+
"""
|
|
977
|
+
Multiply ``self`` by the uniformizer raised to the power ``n``. If
|
|
978
|
+
``n`` is negative, right shifts by ``-n``.
|
|
979
|
+
|
|
980
|
+
EXAMPLES::
|
|
981
|
+
|
|
982
|
+
sage: R = ZpCA(5,5)
|
|
983
|
+
sage: S.<x> = ZZ[]
|
|
984
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
985
|
+
sage: W.<w> = R.ext(f)
|
|
986
|
+
sage: z = (1 + w)^5
|
|
987
|
+
sage: z
|
|
988
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
989
|
+
sage: z << 17 # indirect doctest
|
|
990
|
+
w^17 + w^22 + w^23 + 2*w^24 + O(w^25)
|
|
991
|
+
sage: z << (-1)
|
|
992
|
+
w^4 + w^5 + 2*w^6 + 4*w^7 + 3*w^9 + w^11 + 4*w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^19 + w^20 + 4*w^23 + O(w^24)
|
|
993
|
+
"""
|
|
994
|
+
self._rshift_c(-n)
|
|
995
|
+
|
|
996
|
+
def __lshift__(pAdicZZpXCAElement self, shift):
|
|
997
|
+
"""
|
|
998
|
+
Multiply ``self`` by the uniformizer raised to the power ``n``. If
|
|
999
|
+
``n`` is negative, right shifts by ``-n``.
|
|
1000
|
+
|
|
1001
|
+
EXAMPLES::
|
|
1002
|
+
|
|
1003
|
+
sage: R = ZpCA(5,5)
|
|
1004
|
+
sage: S.<x> = ZZ[]
|
|
1005
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1006
|
+
sage: W.<w> = R.ext(f)
|
|
1007
|
+
sage: z = (1 + w)^5
|
|
1008
|
+
sage: z
|
|
1009
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
1010
|
+
sage: z << 17 # indirect doctest
|
|
1011
|
+
w^17 + w^22 + w^23 + 2*w^24 + O(w^25)
|
|
1012
|
+
sage: z << (-1)
|
|
1013
|
+
w^4 + w^5 + 2*w^6 + 4*w^7 + 3*w^9 + w^11 + 4*w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^19 + w^20 + 4*w^23 + O(w^24)
|
|
1014
|
+
"""
|
|
1015
|
+
cdef pAdicZZpXCAElement ans
|
|
1016
|
+
if not isinstance(shift, Integer):
|
|
1017
|
+
shift = Integer(shift)
|
|
1018
|
+
if mpz_fits_slong_p((<Integer>shift).value) == 0:
|
|
1019
|
+
if mpz_sgn((<Integer>shift).value) > 0:
|
|
1020
|
+
ans = self._new_c(self.prime_pow.ram_prec_cap)
|
|
1021
|
+
else:
|
|
1022
|
+
ans = self._new_c(0)
|
|
1023
|
+
return ans
|
|
1024
|
+
return self._rshift_c(-mpz_get_si((<Integer>shift).value))
|
|
1025
|
+
|
|
1026
|
+
cdef pAdicZZpXCAElement _rshift_c(self, long n):
|
|
1027
|
+
"""
|
|
1028
|
+
Divide ``self`` by the uniformizer raised to the power ``n``. If
|
|
1029
|
+
parent is not a field, throws away the nonpositive part of
|
|
1030
|
+
the series expansion. If ``n`` is negative, left shifts by ``-n``.
|
|
1031
|
+
|
|
1032
|
+
EXAMPLES::
|
|
1033
|
+
|
|
1034
|
+
sage: R = ZpCA(5,5,print_mode='digits')
|
|
1035
|
+
sage: S.<x> = ZZ[]
|
|
1036
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1037
|
+
sage: W.<w> = R.ext(f)
|
|
1038
|
+
sage: z = (1 + w)^5
|
|
1039
|
+
sage: for m in range(26): repr(z >> m) # indirect doctest
|
|
1040
|
+
'...4001400444441030421100001'
|
|
1041
|
+
'...400140044444103042110000'
|
|
1042
|
+
'...40014004444410304211000'
|
|
1043
|
+
'...4001400444441030421100'
|
|
1044
|
+
'...400140044444103042110'
|
|
1045
|
+
'...40014004444410304211'
|
|
1046
|
+
'...4001400444441030421'
|
|
1047
|
+
'...400140044444103042'
|
|
1048
|
+
'...40014004444410304'
|
|
1049
|
+
'...4001400444441030'
|
|
1050
|
+
'...400140044444103'
|
|
1051
|
+
'...40014004444410'
|
|
1052
|
+
'...4001400444441'
|
|
1053
|
+
'...400140044444'
|
|
1054
|
+
'...40014004444'
|
|
1055
|
+
'...4001400444'
|
|
1056
|
+
'...400140044'
|
|
1057
|
+
'...40014004'
|
|
1058
|
+
'...4001400'
|
|
1059
|
+
'...400140'
|
|
1060
|
+
'...40014'
|
|
1061
|
+
'...4001'
|
|
1062
|
+
'...400'
|
|
1063
|
+
'...40'
|
|
1064
|
+
'...4'
|
|
1065
|
+
'...'
|
|
1066
|
+
sage: repr(z >> (-4))
|
|
1067
|
+
'...4004444410304211000010000'
|
|
1068
|
+
"""
|
|
1069
|
+
cdef long absprec
|
|
1070
|
+
if n == 0:
|
|
1071
|
+
return self
|
|
1072
|
+
elif n > self.absprec: # we do these checks first in case adding would cause an overflow
|
|
1073
|
+
absprec = 0
|
|
1074
|
+
elif n < self.absprec - self.prime_pow.ram_prec_cap:
|
|
1075
|
+
absprec = self.prime_pow.ram_prec_cap
|
|
1076
|
+
else:
|
|
1077
|
+
absprec = self.absprec - n
|
|
1078
|
+
cdef pAdicZZpXCAElement ans
|
|
1079
|
+
if absprec > 0:
|
|
1080
|
+
ans = self._new_c(absprec)
|
|
1081
|
+
if n > -self.prime_pow.ram_prec_cap: # the result might not be zero.
|
|
1082
|
+
if self.prime_pow.e == 1:
|
|
1083
|
+
if n > 0:
|
|
1084
|
+
ZZ_pX_right_pshift(ans.value, self.value, self.prime_pow.pow_ZZ_tmp(n)[0], self.prime_pow.get_context(ans.absprec).x)
|
|
1085
|
+
else:
|
|
1086
|
+
ZZ_pX_left_pshift(ans.value, self.value, self.prime_pow.pow_ZZ_tmp(-n)[0], self.prime_pow.get_context(ans.absprec).x)
|
|
1087
|
+
else:
|
|
1088
|
+
self.prime_pow.eis_shift_capdiv(&ans.value, &self.value, n, ans.absprec)
|
|
1089
|
+
else:
|
|
1090
|
+
ans = self._new_c(0)
|
|
1091
|
+
return ans
|
|
1092
|
+
|
|
1093
|
+
def __rshift__(pAdicZZpXCAElement self, shift):
|
|
1094
|
+
"""
|
|
1095
|
+
Divide ``self`` by the uniformizer raised to the power ``n``. If
|
|
1096
|
+
parent is not a field, throws away the nonpositive part of
|
|
1097
|
+
the series expansion. If ``n`` is negative, left shifts by ``-n``.
|
|
1098
|
+
|
|
1099
|
+
EXAMPLES::
|
|
1100
|
+
|
|
1101
|
+
sage: R = ZpCA(5,5)
|
|
1102
|
+
sage: S.<x> = ZZ[]
|
|
1103
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1104
|
+
sage: W.<w> = R.ext(f)
|
|
1105
|
+
sage: z = (1 + w)^5
|
|
1106
|
+
sage: z
|
|
1107
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
1108
|
+
sage: z >> (6) # indirect doctest
|
|
1109
|
+
1 + 2*w + 4*w^2 + 3*w^4 + w^6 + 4*w^7 + 4*w^8 + 4*w^9 + 4*w^10 + 4*w^11 + 4*w^14 + w^15 + 4*w^18 + O(w^19)
|
|
1110
|
+
sage: z >> (-4)
|
|
1111
|
+
w^4 + w^9 + w^10 + 2*w^11 + 4*w^12 + 3*w^14 + w^16 + 4*w^17 + 4*w^18 + 4*w^19 + 4*w^20 + 4*w^21 + 4*w^24 + O(w^25)
|
|
1112
|
+
"""
|
|
1113
|
+
cdef pAdicZZpXCAElement ans
|
|
1114
|
+
if not isinstance(shift, Integer):
|
|
1115
|
+
shift = Integer(shift)
|
|
1116
|
+
if mpz_fits_slong_p((<Integer>shift).value) == 0:
|
|
1117
|
+
if mpz_sgn((<Integer>shift).value) < 0:
|
|
1118
|
+
ans = self._new_c(self.prime_pow.ram_prec_cap)
|
|
1119
|
+
else:
|
|
1120
|
+
ans = self._new_c(0)
|
|
1121
|
+
return ans
|
|
1122
|
+
return self._rshift_c(mpz_get_si((<Integer>shift).value))
|
|
1123
|
+
|
|
1124
|
+
cpdef _neg_(self):
|
|
1125
|
+
"""
|
|
1126
|
+
Return ``-self``.
|
|
1127
|
+
|
|
1128
|
+
EXAMPLES::
|
|
1129
|
+
|
|
1130
|
+
sage: R = ZpCA(5,5)
|
|
1131
|
+
sage: S.<x> = ZZ[]
|
|
1132
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1133
|
+
sage: W.<w> = R.ext(f)
|
|
1134
|
+
sage: z = (1 + w)^5; z
|
|
1135
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
1136
|
+
sage: -z # indirect doctest
|
|
1137
|
+
4 + 3*w^5 + 4*w^6 + w^7 + w^8 + w^9 + w^10 + w^11 + 2*w^12 + 4*w^13 + 4*w^15 + 3*w^16 + w^17 + 2*w^18 + 3*w^19 + 2*w^21 + 4*w^23 + 4*w^24 + O(w^25)
|
|
1138
|
+
sage: y = z + (-z); y
|
|
1139
|
+
O(w^25)
|
|
1140
|
+
sage: -y
|
|
1141
|
+
O(w^25)
|
|
1142
|
+
"""
|
|
1143
|
+
cdef pAdicZZpXCAElement ans = self._new_c(self.absprec)
|
|
1144
|
+
if self.absprec != 0:
|
|
1145
|
+
self.prime_pow.restore_context_capdiv(self.absprec)
|
|
1146
|
+
ZZ_pX_negate(ans.value, self.value)
|
|
1147
|
+
return ans
|
|
1148
|
+
|
|
1149
|
+
# / 1 + \alpha^p \pi_K^{p \lambda} mod \mathfrak{p}_K^{p \lambda + 1} if 1 \le \lambda < \frac{e_K}{p-1}
|
|
1150
|
+
# (1 + \alpha \pi^{\lambda})^p \equiv { 1 + (\alpha^p - \epsilon \alpha) \pi_K^{p \lambda} mod \mathfrak{p}_K^{p \lambda + 1} if \lambda = \frac{e_K}{p-1}
|
|
1151
|
+
# \ 1 - \epsilon \alpha \pi_K^{\lambda + e} mod \mathfrak{p}_K^{\lambda + e + 1} if \lambda > \frac{e_K}{p-1}
|
|
1152
|
+
|
|
1153
|
+
def __pow__(pAdicZZpXCAElement self, _right, m): # m ignored
|
|
1154
|
+
r"""
|
|
1155
|
+
Compute ``self^right``.
|
|
1156
|
+
|
|
1157
|
+
Note: when right is divisible by `p` then one can get more
|
|
1158
|
+
precision than expected.
|
|
1159
|
+
|
|
1160
|
+
Lemma 2.1 (Constructing Class Fields over Local Fields,
|
|
1161
|
+
Sebastian Pauli): Let `\alpha` be in `\mathcal{O}_K`. Let
|
|
1162
|
+
|
|
1163
|
+
.. MATH::
|
|
1164
|
+
|
|
1165
|
+
p = -\pi_K^{e_K} \epsilon
|
|
1166
|
+
|
|
1167
|
+
be the factorization of `p` where `\epsilon` is a unit. Then
|
|
1168
|
+
the `p`-th power of `1 + \alpha \pi_K^{\lambda}` satisfies
|
|
1169
|
+
|
|
1170
|
+
.. MATH::
|
|
1171
|
+
|
|
1172
|
+
(1 + \alpha \pi^{\lambda})^p \equiv \left{ \begin{array}{lll}
|
|
1173
|
+
1 + \alpha^p \pi_K^{p \lambda} & \mod \mathfrak{p}_K^{p \lambda + 1} & \mbox{if $1 \le \lambda < \frac{e_K}{p-1}$} \\
|
|
1174
|
+
1 + (\alpha^p - \epsilon \alpha) \pi_K^{p \lambda} & \mod \mathfrak{p}_K^{p \lambda + 1} & \mbox{if $\lambda = \frac{e_K}{p-1}$} \\
|
|
1175
|
+
1 - \epsilon \alpha \pi_K^{\lambda + e} & \mod \mathfrak{p}_K^{\lambda + e + 1} & \mbox{if $\lambda > \frac{e_K}{p-1}$}
|
|
1176
|
+
\end{array} \right.
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
So if right is divisible by `p^k` we can multiply the relative
|
|
1180
|
+
precision by `p` until we exceed `e/(p-1)`, then add `e` until
|
|
1181
|
+
we have done a total of `k` things: the precision of the
|
|
1182
|
+
result can therefore be greater than the precision of ``self``.
|
|
1183
|
+
|
|
1184
|
+
There is also the issue of `p`-adic exponents, and determining
|
|
1185
|
+
how the precision of the exponent affects the precision of the
|
|
1186
|
+
result.
|
|
1187
|
+
|
|
1188
|
+
In computing `(a + O(\pi^k))^{b + O(p^m)}`, one needs that the
|
|
1189
|
+
reduction of `a` mod `\pi` is in the prime field `\GF{p}` (so
|
|
1190
|
+
that the `p^m` power of the Teichmuller part is constant as
|
|
1191
|
+
`m` increases). Given this restriction, we can factor out the
|
|
1192
|
+
Teichmuller part and use the above lemma to find the first
|
|
1193
|
+
spot where
|
|
1194
|
+
|
|
1195
|
+
.. MATH::
|
|
1196
|
+
|
|
1197
|
+
(1 + \alpha \pi^{\lambda})^{p^m}
|
|
1198
|
+
|
|
1199
|
+
differs from 1. We compare this with the precision bound
|
|
1200
|
+
given by computing `(a + O(\pi^k))^b` and take the lesser of
|
|
1201
|
+
the two.
|
|
1202
|
+
|
|
1203
|
+
In order to do this we need to compute the valuation of ``(self
|
|
1204
|
+
/ self.parent().teichmuller(self)) - 1``.
|
|
1205
|
+
|
|
1206
|
+
EXAMPLES::
|
|
1207
|
+
|
|
1208
|
+
sage: R = ZpCA(5,5)
|
|
1209
|
+
sage: S.<x> = ZZ[]
|
|
1210
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1211
|
+
sage: W.<w> = R.ext(f)
|
|
1212
|
+
sage: (1 + w)^5 # indirect doctest
|
|
1213
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
|
|
1214
|
+
sage: (1 + w + O(w^19))^5
|
|
1215
|
+
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + O(w^24)
|
|
1216
|
+
sage: (1 + O(w))^5
|
|
1217
|
+
1 + O(w^5)
|
|
1218
|
+
sage: (1 + w + O(w^3))^25
|
|
1219
|
+
1 + w^10 + w^11 + 4*w^12 + O(w^13)
|
|
1220
|
+
sage: (3 + 2*w + w^2 + O(w^6))^(15 + O(125))
|
|
1221
|
+
2 + 4*w^6 + w^7 + 3*w^8 + 3*w^9 + 4*w^10 + O(w^11)
|
|
1222
|
+
sage: (3 + 2*w + w^2 + O(w^6))^(15 + O(25))
|
|
1223
|
+
2 + 4*w^6 + w^7 + 3*w^8 + 3*w^9 + O(w^10)
|
|
1224
|
+
sage: (3 + w^2 + O(w^6))^(15+O(25))
|
|
1225
|
+
2 + w^5 + 4*w^7 + w^9 + 3*w^10 + O(w^11)
|
|
1226
|
+
sage: R = ZpCA(2, 10)
|
|
1227
|
+
sage: S.<x> = ZZ[]
|
|
1228
|
+
sage: f = x^34 + 18*x^5 - 72*x^3 + 2
|
|
1229
|
+
sage: W.<w> = R.ext(f)
|
|
1230
|
+
sage: (1+w+O(w^2))^8
|
|
1231
|
+
1 + w^8 + O(w^16)
|
|
1232
|
+
sage: (1+w+O(w^2))^16
|
|
1233
|
+
1 + w^16 + O(w^32)
|
|
1234
|
+
sage: (1+w+O(w^2))^32
|
|
1235
|
+
1 + w^32 + w^50 + w^55 + w^60 + O(w^64)
|
|
1236
|
+
sage: (1+w+O(w^2))^64
|
|
1237
|
+
1 + w^64 + w^66 + w^71 + w^76 + w^81 + w^84 + w^86 + w^91 + w^94 + w^96 + O(w^98)
|
|
1238
|
+
sage: U.<a> = Zq(17^4, 6, print_mode='val-unit'); b = (a^3-a+14)^-6; b
|
|
1239
|
+
12003242 + 4839703*a + 2697351*a^2 + 11717046*a^3 + O(17^6)
|
|
1240
|
+
sage: b*(a^3-a+14)^6
|
|
1241
|
+
1 + O(17^6)
|
|
1242
|
+
"""
|
|
1243
|
+
cdef Integer right
|
|
1244
|
+
cdef bint padic_exp
|
|
1245
|
+
cdef long exp_prec
|
|
1246
|
+
cdef long exp_val
|
|
1247
|
+
cdef long ans_relprec, ans_ordp
|
|
1248
|
+
cdef long self_ordp = self.valuation_c()
|
|
1249
|
+
cdef long self_relprec = self.absprec - self_ordp
|
|
1250
|
+
cdef long threshold # e / (p-1)
|
|
1251
|
+
cdef mpz_t tmp, tmp2
|
|
1252
|
+
if mpz_fits_slong_p(self.prime_pow.prime.value) == 0:
|
|
1253
|
+
threshold = 0
|
|
1254
|
+
else:
|
|
1255
|
+
threshold = self.prime_pow.e / (mpz_get_si(self.prime_pow.prime.value) - 1)
|
|
1256
|
+
cdef Integer base_level
|
|
1257
|
+
cdef pAdicZZpXCAElement ans
|
|
1258
|
+
cdef long i
|
|
1259
|
+
if self._is_inexact_zero():
|
|
1260
|
+
# If an integer exponent, return an inexact zero of valuation right * self_ordp. Otherwise raise an error.
|
|
1261
|
+
if isinstance(_right, int):
|
|
1262
|
+
_right = Integer(_right)
|
|
1263
|
+
if isinstance(_right, Integer):
|
|
1264
|
+
mpz_init_set_si(tmp, self_ordp)
|
|
1265
|
+
mpz_mul(tmp, tmp, (<Integer>_right).value)
|
|
1266
|
+
if mpz_cmp_si(tmp, self.prime_pow.ram_prec_cap) >= 0:
|
|
1267
|
+
ans = self._new_c(self.prime_pow.ram_prec_cap)
|
|
1268
|
+
elif mpz_sgn(tmp) <= 0:
|
|
1269
|
+
ans = self._new_c(0)
|
|
1270
|
+
else:
|
|
1271
|
+
ans = self._new_c(mpz_get_si(tmp))
|
|
1272
|
+
mpz_clear(tmp)
|
|
1273
|
+
return ans
|
|
1274
|
+
elif isinstance(_right, Rational) or (isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime)):
|
|
1275
|
+
raise ValueError("need more precision")
|
|
1276
|
+
else:
|
|
1277
|
+
raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
|
|
1278
|
+
if isinstance(_right, int):
|
|
1279
|
+
_right = Integer(_right)
|
|
1280
|
+
cdef pAdicZZpXCAElement unit
|
|
1281
|
+
if isinstance(_right, Integer):
|
|
1282
|
+
right = <Integer> _right
|
|
1283
|
+
if right < 0 and self_ordp > 0:
|
|
1284
|
+
return self.to_fraction_field()**right
|
|
1285
|
+
if right == 0:
|
|
1286
|
+
# return 1 to maximum precision
|
|
1287
|
+
ans = self._new_c(self.prime_pow.ram_prec_cap)
|
|
1288
|
+
ZZ_pX_SetCoeff_long(ans.value, 0, 1)
|
|
1289
|
+
return ans
|
|
1290
|
+
padic_exp = False
|
|
1291
|
+
exp_val = _right.valuation(self.prime_pow.prime) ##
|
|
1292
|
+
elif isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime):
|
|
1293
|
+
if self_ordp != 0:
|
|
1294
|
+
raise ValueError("in order to raise to a p-adic exponent, base must be a unit")
|
|
1295
|
+
right = Integer(_right)
|
|
1296
|
+
padic_exp = True
|
|
1297
|
+
exp_prec = _right.precision_absolute() ##
|
|
1298
|
+
exp_val = _right.valuation() ##
|
|
1299
|
+
if exp_val < 0:
|
|
1300
|
+
raise NotImplementedError("negative valuation exponents not yet supported")
|
|
1301
|
+
# checks to see if the residue of self's unit is in the prime field.
|
|
1302
|
+
if self.prime_pow.e == 1:
|
|
1303
|
+
unit = self.unit_part()
|
|
1304
|
+
for i from 1 <= i <= ZZ_pX_deg(unit.value):
|
|
1305
|
+
if not ZZ_divide_test(ZZ_p_rep(ZZ_pX_coeff(unit.value, i)), self.prime_pow.pow_ZZ_tmp(1)[0]):
|
|
1306
|
+
raise ValueError("in order to raise to a p-adic exponent, base must reduce to an element of F_p mod the uniformizer")
|
|
1307
|
+
# compute the "level"
|
|
1308
|
+
teich_part = self.parent().teichmuller(self)
|
|
1309
|
+
base_level = (self / teich_part - 1).valuation() ##
|
|
1310
|
+
elif isinstance(_right, Rational):
|
|
1311
|
+
raise NotImplementedError
|
|
1312
|
+
else:
|
|
1313
|
+
raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
|
|
1314
|
+
# Now we compute the increased relprec due to the exponent having positive p-adic valuation
|
|
1315
|
+
if exp_val > 0:
|
|
1316
|
+
mpz_init_set_si(tmp, self_relprec)
|
|
1317
|
+
while mpz_cmp_si(tmp, threshold) <= 0 and exp_val > 0:
|
|
1318
|
+
mpz_mul(tmp, tmp, self.prime_pow.prime.value)
|
|
1319
|
+
exp_val -= 1
|
|
1320
|
+
if exp_val > 0:
|
|
1321
|
+
mpz_init_set_si(tmp2, self.prime_pow.e)
|
|
1322
|
+
mpz_addmul_ui(tmp, tmp2, exp_val)
|
|
1323
|
+
mpz_clear(tmp2)
|
|
1324
|
+
if mpz_cmp_si(tmp, self.prime_pow.ram_prec_cap) > 0:
|
|
1325
|
+
ans_relprec = self.prime_pow.ram_prec_cap
|
|
1326
|
+
else:
|
|
1327
|
+
ans_relprec = mpz_get_si(tmp)
|
|
1328
|
+
mpz_clear(tmp)
|
|
1329
|
+
else:
|
|
1330
|
+
ans_relprec = self_relprec
|
|
1331
|
+
# Now we compute the limit on relprec due to a non-infinite precision on the exponent.
|
|
1332
|
+
if padic_exp:
|
|
1333
|
+
if exp_prec > 0:
|
|
1334
|
+
# I can freely change base_level, so I use it in place of tmp above.
|
|
1335
|
+
while mpz_cmp_si(base_level.value, threshold) <= 0 and exp_prec > 0:
|
|
1336
|
+
mpz_mul(base_level.value, base_level.value, self.prime_pow.prime.value)
|
|
1337
|
+
exp_prec -= 1
|
|
1338
|
+
if exp_prec > 0:
|
|
1339
|
+
mpz_init_set_si(tmp2, self.prime_pow.e)
|
|
1340
|
+
mpz_addmul_ui(base_level.value, tmp2, exp_prec)
|
|
1341
|
+
mpz_clear(tmp2)
|
|
1342
|
+
if mpz_cmp_si(base_level.value, ans_relprec) < 0:
|
|
1343
|
+
ans_relprec = mpz_get_si(base_level.value)
|
|
1344
|
+
else:
|
|
1345
|
+
return self._new_c(0)
|
|
1346
|
+
if self_ordp == 0:
|
|
1347
|
+
ans_ordp = 0
|
|
1348
|
+
else:
|
|
1349
|
+
mpz_init_set(tmp, right.value)
|
|
1350
|
+
mpz_mul_si(tmp, tmp, self_ordp)
|
|
1351
|
+
if mpz_cmp_si(tmp, self.prime_pow.ram_prec_cap) >= 0:
|
|
1352
|
+
return self._new_c(self.prime_pow.ram_prec_cap)
|
|
1353
|
+
# we already checked for negative tmp above
|
|
1354
|
+
ans_ordp = mpz_get_si(tmp)
|
|
1355
|
+
mpz_clear(tmp)
|
|
1356
|
+
if ans_ordp >= self.prime_pow.ram_prec_cap:
|
|
1357
|
+
return self._new_c(self.prime_pow.ram_prec_cap)
|
|
1358
|
+
cdef ntl_ZZ rZZ = ntl_ZZ.__new__(ntl_ZZ)
|
|
1359
|
+
mpz_to_ZZ(&rZZ.x, right.value)
|
|
1360
|
+
if ans_ordp + ans_relprec <= self.prime_pow.ram_prec_cap:
|
|
1361
|
+
ans = self._new_c(ans_ordp + ans_relprec) # restores context
|
|
1362
|
+
else:
|
|
1363
|
+
ans = self._new_c(self.prime_pow.ram_prec_cap) # restores context
|
|
1364
|
+
cdef ZZ_pX_c self_value
|
|
1365
|
+
sig_on()
|
|
1366
|
+
if ans.absprec != self.absprec:
|
|
1367
|
+
ZZ_pX_conv_modulus(self_value, self.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
|
|
1368
|
+
if mpz_sgn(right.value) < 0: # only happens when self.ordp == 0
|
|
1369
|
+
if self.prime_pow.e == 1:
|
|
1370
|
+
ZZ_pX_InvMod_newton_unram(ans.value, self_value, self.prime_pow.get_modulus(ans.absprec)[0], self.prime_pow.get_context(ans.absprec).x, self.prime_pow.get_context(1).x)
|
|
1371
|
+
else:
|
|
1372
|
+
ZZ_pX_InvMod_newton_ram(ans.value, self_value, self.prime_pow.get_modulus_capdiv(ans.absprec)[0], self.prime_pow.get_context_capdiv(ans.absprec).x)
|
|
1373
|
+
ZZ_negate(rZZ.x, rZZ.x)
|
|
1374
|
+
ZZ_pX_PowerMod_pre(ans.value, ans.value, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.absprec)[0])
|
|
1375
|
+
else:
|
|
1376
|
+
ZZ_pX_PowerMod_pre(ans.value, self_value, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.absprec)[0])
|
|
1377
|
+
else:
|
|
1378
|
+
if mpz_sgn(right.value) < 0: # only happens when self.ordp == 0
|
|
1379
|
+
if self.prime_pow.e == 1:
|
|
1380
|
+
ZZ_pX_InvMod_newton_unram(ans.value, self.value, self.prime_pow.get_modulus(ans.absprec)[0], self.prime_pow.get_context(ans.absprec).x, self.prime_pow.get_context(1).x)
|
|
1381
|
+
else:
|
|
1382
|
+
ZZ_pX_InvMod_newton_ram(ans.value, self.value, self.prime_pow.get_modulus_capdiv(ans.absprec)[0], self.prime_pow.get_context_capdiv(ans.absprec).x)
|
|
1383
|
+
ZZ_negate(rZZ.x, rZZ.x)
|
|
1384
|
+
ZZ_pX_PowerMod_pre(ans.value, ans.value, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.absprec)[0])
|
|
1385
|
+
else:
|
|
1386
|
+
ZZ_pX_PowerMod_pre(ans.value, self.value, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.absprec)[0])
|
|
1387
|
+
sig_off()
|
|
1388
|
+
return ans
|
|
1389
|
+
|
|
1390
|
+
cpdef _add_(self, _right):
|
|
1391
|
+
"""
|
|
1392
|
+
Compute the sum of ``self`` and ``right``.
|
|
1393
|
+
|
|
1394
|
+
EXAMPLES::
|
|
1395
|
+
|
|
1396
|
+
sage: R = ZpCA(5,5)
|
|
1397
|
+
sage: S.<x> = ZZ[]
|
|
1398
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1399
|
+
sage: W.<w> = R.ext(f)
|
|
1400
|
+
sage: (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)) - 69 # indirect doctest
|
|
1401
|
+
1 + O(w^13)
|
|
1402
|
+
sage: -69 + (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13))
|
|
1403
|
+
1 + O(w^13)
|
|
1404
|
+
sage: y = (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13))
|
|
1405
|
+
sage: y - 70
|
|
1406
|
+
O(w^13)
|
|
1407
|
+
sage: y + 0
|
|
1408
|
+
4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
|
|
1409
|
+
"""
|
|
1410
|
+
cdef pAdicZZpXCAElement right = <pAdicZZpXCAElement>_right
|
|
1411
|
+
cdef pAdicZZpXCAElement ans
|
|
1412
|
+
cdef ZZ_pX_c tmpP
|
|
1413
|
+
if self.absprec == 0 or right.absprec == 0:
|
|
1414
|
+
return self._new_c(0)
|
|
1415
|
+
elif self.absprec == right.absprec:
|
|
1416
|
+
ans = self._new_c(self.absprec)
|
|
1417
|
+
ZZ_pX_add(ans.value, self.value, right.value)
|
|
1418
|
+
elif self.absprec < right.absprec:
|
|
1419
|
+
ans = self._new_c(self.absprec)
|
|
1420
|
+
ZZ_pX_conv_modulus(tmpP, right.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
|
|
1421
|
+
ZZ_pX_add(ans.value, self.value, tmpP)
|
|
1422
|
+
else:
|
|
1423
|
+
ans = self._new_c(right.absprec)
|
|
1424
|
+
ZZ_pX_conv_modulus(tmpP, self.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
|
|
1425
|
+
ZZ_pX_add(ans.value, tmpP, right.value)
|
|
1426
|
+
return ans
|
|
1427
|
+
|
|
1428
|
+
cpdef _sub_(self, _right):
|
|
1429
|
+
"""
|
|
1430
|
+
Return the difference of ``self`` and ``right``.
|
|
1431
|
+
|
|
1432
|
+
EXAMPLES::
|
|
1433
|
+
|
|
1434
|
+
sage: R = ZpCA(5,5)
|
|
1435
|
+
sage: S.<x> = ZZ[]
|
|
1436
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1437
|
+
sage: W.<w> = R.ext(f)
|
|
1438
|
+
sage: a = W(329)
|
|
1439
|
+
sage: b = W(111)
|
|
1440
|
+
sage: a - b # indirect doctest
|
|
1441
|
+
3 + 3*w^5 + w^7 + 2*w^9 + 3*w^10 + 4*w^11 + 2*w^13 + 2*w^14 + w^15 + 4*w^16 + 2*w^18 + 3*w^19 + 2*w^20 + 3*w^21 + w^22 + w^24 + O(w^25)
|
|
1442
|
+
sage: W(218)
|
|
1443
|
+
3 + 3*w^5 + w^7 + 2*w^9 + 3*w^10 + 4*w^11 + 2*w^13 + 2*w^14 + w^15 + 4*w^16 + 2*w^18 + 3*w^19 + 2*w^20 + 3*w^21 + w^22 + w^24 + O(w^25)
|
|
1444
|
+
sage: a - O(w^14)
|
|
1445
|
+
4 + 3*w^10 + 2*w^12 + O(w^14)
|
|
1446
|
+
sage: a - 0
|
|
1447
|
+
4 + 3*w^10 + 2*w^12 + w^14 + 2*w^15 + w^16 + 3*w^17 + 3*w^18 + w^19 + 2*w^21 + 4*w^22 + w^23 + 4*w^24 + O(w^25)
|
|
1448
|
+
sage: O(w^14) - a
|
|
1449
|
+
1 + 4*w^5 + 3*w^7 + w^9 + w^10 + 2*w^11 + w^12 + w^13 + O(w^14)
|
|
1450
|
+
"""
|
|
1451
|
+
cdef pAdicZZpXCAElement right = <pAdicZZpXCAElement>_right
|
|
1452
|
+
cdef pAdicZZpXCAElement ans
|
|
1453
|
+
cdef ZZ_pX_c tmpP
|
|
1454
|
+
if self.absprec == 0 or right.absprec == 0:
|
|
1455
|
+
return self._new_c(0)
|
|
1456
|
+
elif self.absprec == right.absprec:
|
|
1457
|
+
ans = self._new_c(self.absprec)
|
|
1458
|
+
ZZ_pX_sub(ans.value, self.value, right.value)
|
|
1459
|
+
elif self.absprec < right.absprec:
|
|
1460
|
+
ans = self._new_c(self.absprec)
|
|
1461
|
+
ZZ_pX_conv_modulus(tmpP, right.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
|
|
1462
|
+
ZZ_pX_sub(ans.value, self.value, tmpP)
|
|
1463
|
+
else:
|
|
1464
|
+
ans = self._new_c(right.absprec)
|
|
1465
|
+
ZZ_pX_conv_modulus(tmpP, self.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
|
|
1466
|
+
ZZ_pX_sub(ans.value, tmpP, right.value)
|
|
1467
|
+
return ans
|
|
1468
|
+
|
|
1469
|
+
cpdef _mul_(self, _right):
|
|
1470
|
+
"""
|
|
1471
|
+
Return the product of ``self`` and ``right``.
|
|
1472
|
+
|
|
1473
|
+
EXAMPLES::
|
|
1474
|
+
|
|
1475
|
+
sage: R = ZpCA(5,5)
|
|
1476
|
+
sage: S.<x> = ZZ[]
|
|
1477
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1478
|
+
sage: W.<w> = R.ext(f)
|
|
1479
|
+
sage: a = W(329)
|
|
1480
|
+
sage: b = W(111)
|
|
1481
|
+
sage: a*b # indirect doctest
|
|
1482
|
+
4 + 3*w^5 + w^7 + 2*w^9 + 4*w^11 + 3*w^12 + 2*w^13 + w^14 + 2*w^15 + 3*w^16 + 4*w^17 + 4*w^18 + 2*w^19 + 2*w^21 + 4*w^22 + 2*w^23 + w^24 + O(w^25)
|
|
1483
|
+
sage: a * 0
|
|
1484
|
+
O(w^25)
|
|
1485
|
+
sage: a * O(w^14)
|
|
1486
|
+
O(w^14)
|
|
1487
|
+
"""
|
|
1488
|
+
cdef pAdicZZpXCAElement right = <pAdicZZpXCAElement>_right
|
|
1489
|
+
cdef pAdicZZpXCAElement ans
|
|
1490
|
+
cdef ZZ_pX_c self_adapted, right_adapted
|
|
1491
|
+
cdef long self_ordp = self.valuation_c()
|
|
1492
|
+
cdef long right_ordp = right.valuation_c()
|
|
1493
|
+
cdef long ans_ordp = self_ordp + right_ordp
|
|
1494
|
+
if ans_ordp >= self.prime_pow.ram_prec_cap:
|
|
1495
|
+
return self._new_c(self.prime_pow.ram_prec_cap)
|
|
1496
|
+
if self._is_inexact_zero() or right._is_inexact_zero():
|
|
1497
|
+
return self._new_c(ans_ordp)
|
|
1498
|
+
cdef long self_relprec = self.absprec - self_ordp
|
|
1499
|
+
cdef long right_relprec = right.absprec - right_ordp
|
|
1500
|
+
cdef long ans_absprec
|
|
1501
|
+
if self_relprec <= right_relprec:
|
|
1502
|
+
ans_absprec = ans_ordp + self_relprec
|
|
1503
|
+
else:
|
|
1504
|
+
ans_absprec = ans_ordp + right_relprec
|
|
1505
|
+
if ans_absprec > self.prime_pow.ram_prec_cap:
|
|
1506
|
+
ans_absprec = self.prime_pow.ram_prec_cap
|
|
1507
|
+
ans = self._new_c(ans_absprec) # restores the context
|
|
1508
|
+
if self.absprec == ans_absprec and right.absprec == ans_absprec:
|
|
1509
|
+
ZZ_pX_MulMod_pre(ans.value, self.value, right.value, self.prime_pow.get_modulus_capdiv(ans_absprec)[0])
|
|
1510
|
+
elif self.absprec == ans_absprec:
|
|
1511
|
+
ZZ_pX_conv_modulus(right_adapted, right.value, self.prime_pow.get_context_capdiv(ans_absprec).x)
|
|
1512
|
+
ZZ_pX_MulMod_pre(ans.value, self.value, right_adapted, self.prime_pow.get_modulus_capdiv(ans_absprec)[0])
|
|
1513
|
+
elif right.absprec == ans_absprec:
|
|
1514
|
+
ZZ_pX_conv_modulus(self_adapted, self.value, self.prime_pow.get_context_capdiv(ans_absprec).x)
|
|
1515
|
+
ZZ_pX_MulMod_pre(ans.value, self_adapted, right.value, self.prime_pow.get_modulus_capdiv(ans_absprec)[0])
|
|
1516
|
+
else:
|
|
1517
|
+
ZZ_pX_conv_modulus(self_adapted, self.value, self.prime_pow.get_context_capdiv(ans_absprec).x)
|
|
1518
|
+
ZZ_pX_conv_modulus(right_adapted, right.value, self.prime_pow.get_context_capdiv(ans_absprec).x)
|
|
1519
|
+
ZZ_pX_MulMod_pre(ans.value, self_adapted, right_adapted, self.prime_pow.get_modulus_capdiv(ans_absprec)[0])
|
|
1520
|
+
return ans
|
|
1521
|
+
|
|
1522
|
+
cpdef _div_(self, right):
|
|
1523
|
+
"""
|
|
1524
|
+
Return the quotient of ``self`` by ``right``.
|
|
1525
|
+
|
|
1526
|
+
EXAMPLES::
|
|
1527
|
+
|
|
1528
|
+
sage: R = ZpCA(5,5)
|
|
1529
|
+
sage: S.<x> = ZZ[]
|
|
1530
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1531
|
+
sage: W.<w> = R.ext(f)
|
|
1532
|
+
sage: W(14) / W(125) # indirect doctest
|
|
1533
|
+
4*w^-15 + w^-13 + 3*w^-11 + 2*w^-10 + 3*w^-9 + 4*w^-8 + 4*w^-7 + 3*w^-6 + O(w^-5)
|
|
1534
|
+
sage: 1 / w
|
|
1535
|
+
w^-1 + O(w^23)
|
|
1536
|
+
sage: W.<w> = R.ext(x^20 - 165*x + 5)
|
|
1537
|
+
sage: a = (1 + w)^25 - 1
|
|
1538
|
+
sage: b = (1 + w)^5 - 1
|
|
1539
|
+
sage: c = (1 + w)^20 + (1 + w)^15 + (1 + w)^10 + (1 + w)^5 + 1
|
|
1540
|
+
sage: d = a / b; d == c
|
|
1541
|
+
True
|
|
1542
|
+
sage: d.precision_absolute()
|
|
1543
|
+
95
|
|
1544
|
+
sage: c.precision_absolute()
|
|
1545
|
+
100
|
|
1546
|
+
sage: 1 / a == ~a
|
|
1547
|
+
True
|
|
1548
|
+
"""
|
|
1549
|
+
return self.to_fraction_field() * (~right)
|
|
1550
|
+
|
|
1551
|
+
def _integer_(self, Z=None):
|
|
1552
|
+
r"""
|
|
1553
|
+
Return an integer congruent to this element modulo
|
|
1554
|
+
`\pi`^``self.absolute_precision()``, if possible.
|
|
1555
|
+
|
|
1556
|
+
EXAMPLES::
|
|
1557
|
+
|
|
1558
|
+
sage: # needs sage.libs.flint
|
|
1559
|
+
sage: ZZ(ZqCA(125,names='a')(-1)) # indirect doctest
|
|
1560
|
+
95367431640624
|
|
1561
|
+
sage: R = ZpCA(5); S.<x> = ZZ[]; f = x^5 + 25*x^3 - 5; W.<w> = R.ext(f)
|
|
1562
|
+
sage: ZZ(W(-1))
|
|
1563
|
+
95367431640624
|
|
1564
|
+
sage: ZZ(W(0))
|
|
1565
|
+
0
|
|
1566
|
+
sage: ZZ(W(0,7))
|
|
1567
|
+
0
|
|
1568
|
+
sage: ZZ(w)
|
|
1569
|
+
Traceback (most recent call last):
|
|
1570
|
+
...
|
|
1571
|
+
ValueError: this element not well approximated by an integer
|
|
1572
|
+
sage: ZZ(W(5))
|
|
1573
|
+
5
|
|
1574
|
+
"""
|
|
1575
|
+
cdef Integer ans
|
|
1576
|
+
cdef ZZ_c tmp_z
|
|
1577
|
+
if ZZ_pX_deg(self.value) > 0:
|
|
1578
|
+
raise ValueError("this element not well approximated by an integer")
|
|
1579
|
+
ans = PY_NEW(Integer)
|
|
1580
|
+
tmp_z = ZZ_p_rep(ZZ_pX_ConstTerm(self.value))
|
|
1581
|
+
ZZ_to_mpz(ans.value, &tmp_z)
|
|
1582
|
+
return ans
|
|
1583
|
+
|
|
1584
|
+
def __copy__(self):
|
|
1585
|
+
"""
|
|
1586
|
+
Return a copy of ``self``.
|
|
1587
|
+
|
|
1588
|
+
EXAMPLES::
|
|
1589
|
+
|
|
1590
|
+
sage: R = ZpCA(5,5)
|
|
1591
|
+
sage: S.<x> = ZZ[]
|
|
1592
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1593
|
+
sage: W.<w> = R.ext(f)
|
|
1594
|
+
sage: b = W(45, 17); b
|
|
1595
|
+
4*w^5 + 3*w^7 + w^9 + w^10 + 2*w^11 + w^12 + w^13 + 3*w^14 + w^16 + O(w^17)
|
|
1596
|
+
sage: c = copy(b); c
|
|
1597
|
+
4*w^5 + 3*w^7 + w^9 + w^10 + 2*w^11 + w^12 + w^13 + 3*w^14 + w^16 + O(w^17)
|
|
1598
|
+
sage: c is b
|
|
1599
|
+
False
|
|
1600
|
+
"""
|
|
1601
|
+
cdef pAdicZZpXCAElement ans = self._new_c(self.absprec) # restores context
|
|
1602
|
+
ans.value = self.value
|
|
1603
|
+
return ans
|
|
1604
|
+
|
|
1605
|
+
def is_zero(self, absprec=None):
|
|
1606
|
+
r"""
|
|
1607
|
+
Return whether the valuation of ``self`` is at least ``absprec``.
|
|
1608
|
+
|
|
1609
|
+
If ``absprec`` is ``None``, returns if ``self`` is indistinguishable
|
|
1610
|
+
from zero.
|
|
1611
|
+
|
|
1612
|
+
If ``self`` is an inexact zero of valuation less than ``absprec``,
|
|
1613
|
+
raises a :exc:`PrecisionError`.
|
|
1614
|
+
|
|
1615
|
+
EXAMPLES::
|
|
1616
|
+
|
|
1617
|
+
sage: R = ZpCA(5,5)
|
|
1618
|
+
sage: S.<x> = ZZ[]
|
|
1619
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1620
|
+
sage: W.<w> = R.ext(f)
|
|
1621
|
+
sage: O(w^189).is_zero()
|
|
1622
|
+
True
|
|
1623
|
+
sage: W(0).is_zero()
|
|
1624
|
+
True
|
|
1625
|
+
sage: a = W(675)
|
|
1626
|
+
sage: a.is_zero()
|
|
1627
|
+
False
|
|
1628
|
+
sage: a.is_zero(7)
|
|
1629
|
+
True
|
|
1630
|
+
sage: a.is_zero(21)
|
|
1631
|
+
False
|
|
1632
|
+
"""
|
|
1633
|
+
cdef bint ans
|
|
1634
|
+
cdef long aprec
|
|
1635
|
+
if absprec is None:
|
|
1636
|
+
ans = ZZ_pX_IsZero(self.value)
|
|
1637
|
+
else:
|
|
1638
|
+
if not isinstance(absprec, Integer):
|
|
1639
|
+
absprec = Integer(absprec)
|
|
1640
|
+
if mpz_fits_slong_p((<Integer>absprec).value) == 0:
|
|
1641
|
+
if mpz_sgn((<Integer>absprec).value) < 0:
|
|
1642
|
+
ans = True
|
|
1643
|
+
elif ZZ_pX_IsZero(self.value):
|
|
1644
|
+
raise PrecisionError("not enough precision to determine if element is zero")
|
|
1645
|
+
else:
|
|
1646
|
+
ans = False
|
|
1647
|
+
else:
|
|
1648
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
1649
|
+
if ZZ_pX_IsZero(self.value) and aprec > self.absprec:
|
|
1650
|
+
raise PrecisionError("not enough precision to determine if element is zero")
|
|
1651
|
+
else:
|
|
1652
|
+
ans = (self.valuation_c() >= aprec)
|
|
1653
|
+
return ans
|
|
1654
|
+
|
|
1655
|
+
cpdef ntl_ZZ_pX _ntl_rep(self):
|
|
1656
|
+
"""
|
|
1657
|
+
Return an ``ntl_ZZ_pX`` that holds the value of ``self``.
|
|
1658
|
+
|
|
1659
|
+
EXAMPLES::
|
|
1660
|
+
|
|
1661
|
+
sage: R = ZpCA(5,5)
|
|
1662
|
+
sage: S.<x> = ZZ[]
|
|
1663
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1664
|
+
sage: W.<w> = R.ext(f)
|
|
1665
|
+
sage: a = W(566); b = W(209)
|
|
1666
|
+
sage: c = a + b; c._ntl_rep() # indirect doctest
|
|
1667
|
+
[775]
|
|
1668
|
+
"""
|
|
1669
|
+
if self.absprec == 0:
|
|
1670
|
+
raise ValueError("self has 0 absolute precision")
|
|
1671
|
+
self.prime_pow.restore_context_capdiv(self.absprec)
|
|
1672
|
+
cdef ntl_ZZ_pX ans = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
|
|
1673
|
+
ans.c = self.prime_pow.get_context_capdiv(self.absprec)
|
|
1674
|
+
ans.x = self.value
|
|
1675
|
+
return ans
|
|
1676
|
+
|
|
1677
|
+
cpdef _ntl_rep_abs(self):
|
|
1678
|
+
"""
|
|
1679
|
+
Return a pair ``(f, 0)`` where ``f = self._ntl_rep()``.
|
|
1680
|
+
|
|
1681
|
+
EXAMPLES::
|
|
1682
|
+
|
|
1683
|
+
sage: R = ZpCA(5,5)
|
|
1684
|
+
sage: S.<x> = ZZ[]
|
|
1685
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1686
|
+
sage: W.<w> = R.ext(f)
|
|
1687
|
+
sage: a = W(566); b = W(209)
|
|
1688
|
+
sage: c = a + b; c._ntl_rep_abs()
|
|
1689
|
+
([775], 0)
|
|
1690
|
+
sage: c
|
|
1691
|
+
w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + w^20 + 2*w^21 + 3*w^22 + w^23 + w^24 + O(w^25)
|
|
1692
|
+
sage: c._ntl_rep_abs()
|
|
1693
|
+
([775], 0)
|
|
1694
|
+
"""
|
|
1695
|
+
return self._ntl_rep(), Integer(0)
|
|
1696
|
+
|
|
1697
|
+
def _polynomial_list(self, pad=False):
|
|
1698
|
+
"""
|
|
1699
|
+
Return the coefficient list for a polynomial over the base ring
|
|
1700
|
+
yielding this element.
|
|
1701
|
+
|
|
1702
|
+
INPUT:
|
|
1703
|
+
|
|
1704
|
+
- ``pad`` -- whether to pad the result with zeros of the appropriate precision
|
|
1705
|
+
|
|
1706
|
+
EXAMPLES::
|
|
1707
|
+
|
|
1708
|
+
sage: R.<x> = ZZ[]
|
|
1709
|
+
sage: W.<w> = ZpCA(5).extension(x^3 - 5)
|
|
1710
|
+
sage: (1 + w + O(w^11))._polynomial_list()
|
|
1711
|
+
[1 + O(5^4), 1 + O(5^4)]
|
|
1712
|
+
sage: (1 + w + O(w^11))._polynomial_list(pad=True)
|
|
1713
|
+
[1 + O(5^4), 1 + O(5^4), O(5^3)]
|
|
1714
|
+
sage: W(0)._polynomial_list()
|
|
1715
|
+
[]
|
|
1716
|
+
sage: W(0)._polynomial_list(pad=True)
|
|
1717
|
+
[O(5^20), O(5^20), O(5^20)]
|
|
1718
|
+
sage: W(O(w^7))._polynomial_list()
|
|
1719
|
+
[]
|
|
1720
|
+
sage: W(O(w^7))._polynomial_list(pad=True)
|
|
1721
|
+
[O(5^3), O(5^2), O(5^2)]
|
|
1722
|
+
"""
|
|
1723
|
+
R = self.base_ring()
|
|
1724
|
+
if self.is_zero():
|
|
1725
|
+
L = []
|
|
1726
|
+
else:
|
|
1727
|
+
L = [Integer(c) for c in self._ntl_rep().list()]
|
|
1728
|
+
if pad:
|
|
1729
|
+
n = self.parent().degree()
|
|
1730
|
+
L.extend([R.zero()] * (n - len(L)))
|
|
1731
|
+
e = self.parent().e()
|
|
1732
|
+
if e == 1:
|
|
1733
|
+
return [R(c, self.absprec) for c in L]
|
|
1734
|
+
else:
|
|
1735
|
+
return [R(c, (self.absprec - i - 1) // e + 1) for i, c in enumerate(L)]
|
|
1736
|
+
|
|
1737
|
+
def polynomial(self, var='x'):
|
|
1738
|
+
"""
|
|
1739
|
+
Return a polynomial over the base ring that yields this element
|
|
1740
|
+
when evaluated at the generator of the parent.
|
|
1741
|
+
|
|
1742
|
+
INPUT:
|
|
1743
|
+
|
|
1744
|
+
- ``var`` -- string, the variable name for the polynomial
|
|
1745
|
+
|
|
1746
|
+
EXAMPLES::
|
|
1747
|
+
|
|
1748
|
+
sage: S.<x> = ZZ[]
|
|
1749
|
+
sage: W.<w> = ZpCA(5).extension(x^2 - 5)
|
|
1750
|
+
sage: (w + W(5, 7)).polynomial()
|
|
1751
|
+
(1 + O(5^3))*x + 5 + O(5^4)
|
|
1752
|
+
"""
|
|
1753
|
+
R = self.base_ring()
|
|
1754
|
+
S = R[var]
|
|
1755
|
+
return S(self._polynomial_list())
|
|
1756
|
+
|
|
1757
|
+
cdef ZZ_p_c _const_term(self) noexcept:
|
|
1758
|
+
"""
|
|
1759
|
+
Return the constant term of ``self.value``.
|
|
1760
|
+
|
|
1761
|
+
EXAMPLES::
|
|
1762
|
+
|
|
1763
|
+
sage: R = ZpCA(5,5)
|
|
1764
|
+
sage: S.<x> = R[]
|
|
1765
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1766
|
+
sage: W.<w> = R.ext(f)
|
|
1767
|
+
sage: a = W(566)
|
|
1768
|
+
sage: a._const_term_test() # indirect doctest
|
|
1769
|
+
566
|
|
1770
|
+
"""
|
|
1771
|
+
return ZZ_pX_ConstTerm(self.value)
|
|
1772
|
+
|
|
1773
|
+
def is_equal_to(self, right, absprec=None):
|
|
1774
|
+
"""
|
|
1775
|
+
Return whether ``self`` is equal to ``right`` modulo
|
|
1776
|
+
``self.uniformizer()^absprec``.
|
|
1777
|
+
|
|
1778
|
+
If ``absprec`` is ``None``, returns if ``self`` is equal to ``right`` modulo
|
|
1779
|
+
the lower of their two precisions.
|
|
1780
|
+
|
|
1781
|
+
EXAMPLES::
|
|
1782
|
+
|
|
1783
|
+
sage: R = ZpCA(5,5)
|
|
1784
|
+
sage: S.<x> = ZZ[]
|
|
1785
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1786
|
+
sage: W.<w> = R.ext(f)
|
|
1787
|
+
sage: a = W(47); b = W(47 + 25)
|
|
1788
|
+
sage: a.is_equal_to(b)
|
|
1789
|
+
False
|
|
1790
|
+
sage: a.is_equal_to(b, 7)
|
|
1791
|
+
True
|
|
1792
|
+
"""
|
|
1793
|
+
# Should be sped up later
|
|
1794
|
+
return (self - right).is_zero(absprec)
|
|
1795
|
+
|
|
1796
|
+
cpdef pAdicZZpXCAElement lift_to_precision(self, absprec=None):
|
|
1797
|
+
"""
|
|
1798
|
+
Return a ``pAdicZZpXCAElement`` congruent to ``self`` but with
|
|
1799
|
+
absolute precision at least ``absprec``.
|
|
1800
|
+
|
|
1801
|
+
INPUT:
|
|
1802
|
+
|
|
1803
|
+
- ``absprec`` -- (default: ``None``) the absolute precision of
|
|
1804
|
+
the result. If ``None``, lifts to the maximum precision
|
|
1805
|
+
allowed.
|
|
1806
|
+
|
|
1807
|
+
.. NOTE::
|
|
1808
|
+
|
|
1809
|
+
If setting ``absprec`` that high would violate the
|
|
1810
|
+
precision cap, raises a precision error.
|
|
1811
|
+
|
|
1812
|
+
Note that the new digits will not necessarily be zero.
|
|
1813
|
+
|
|
1814
|
+
EXAMPLES::
|
|
1815
|
+
|
|
1816
|
+
sage: R = ZpCA(5,5)
|
|
1817
|
+
sage: S.<x> = ZZ[]
|
|
1818
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1819
|
+
sage: W.<w> = R.ext(f)
|
|
1820
|
+
sage: a = W(345, 17); a
|
|
1821
|
+
4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + O(w^17)
|
|
1822
|
+
sage: b = a.lift_to_precision(19); b # indirect doctest
|
|
1823
|
+
4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + w^17 + 2*w^18 + O(w^19)
|
|
1824
|
+
sage: c = a.lift_to_precision(24); c
|
|
1825
|
+
4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + w^17 + 2*w^18 + 4*w^19 + 4*w^20 + 2*w^21 + 4*w^23 + O(w^24)
|
|
1826
|
+
sage: a._ntl_rep()
|
|
1827
|
+
[345]
|
|
1828
|
+
sage: b._ntl_rep()
|
|
1829
|
+
[345]
|
|
1830
|
+
sage: c._ntl_rep()
|
|
1831
|
+
[345]
|
|
1832
|
+
sage: a.lift_to_precision().precision_absolute() == W.precision_cap()
|
|
1833
|
+
True
|
|
1834
|
+
"""
|
|
1835
|
+
cdef pAdicZZpXCAElement ans
|
|
1836
|
+
cdef long aprec
|
|
1837
|
+
if absprec is not None and not isinstance(absprec, Integer):
|
|
1838
|
+
absprec = Integer(absprec)
|
|
1839
|
+
if absprec is None:
|
|
1840
|
+
aprec = self.prime_pow.ram_prec_cap
|
|
1841
|
+
elif mpz_fits_slong_p((<Integer>absprec).value) == 0:
|
|
1842
|
+
if mpz_sgn((<Integer>absprec).value) < 0:
|
|
1843
|
+
return self
|
|
1844
|
+
else:
|
|
1845
|
+
raise PrecisionError("precision higher than allowed by the precision cap")
|
|
1846
|
+
else:
|
|
1847
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
1848
|
+
if aprec > self.prime_pow.ram_prec_cap:
|
|
1849
|
+
raise PrecisionError("precision higher than allowed by the precision cap")
|
|
1850
|
+
if aprec <= self.absprec:
|
|
1851
|
+
return self
|
|
1852
|
+
ans = self._new_c(aprec) # restores context
|
|
1853
|
+
ZZ_pX_conv_modulus(ans.value, self.value, self.prime_pow.get_context_capdiv(aprec).x)
|
|
1854
|
+
return ans
|
|
1855
|
+
|
|
1856
|
+
def expansion(self, n=None, lift_mode='simple'):
|
|
1857
|
+
"""
|
|
1858
|
+
Return a list giving a series representation of ``self``.
|
|
1859
|
+
|
|
1860
|
+
- If ``lift_mode == 'simple'`` or ``'smallest'``, the returned
|
|
1861
|
+
list will consist of integers (in the Eisenstein case) or a
|
|
1862
|
+
list of lists of integers (in the unramified case).
|
|
1863
|
+
``self`` can be reconstructed as a sum of elements of the
|
|
1864
|
+
list times powers of the uniformiser (in the Eisenstein
|
|
1865
|
+
case), or as a sum of powers of `p` times polynomials in the
|
|
1866
|
+
generator (in the unramified case).
|
|
1867
|
+
|
|
1868
|
+
+ If ``lift_mode == 'simple'``, all integers will be in the
|
|
1869
|
+
interval `[0,p-1]`
|
|
1870
|
+
|
|
1871
|
+
+ If ``lift_mod == 'smallest'`` they will be in the
|
|
1872
|
+
interval `[(1-p)/2, p/2]`.
|
|
1873
|
+
|
|
1874
|
+
- If ``lift_mode == 'teichmuller'``, returns a list of
|
|
1875
|
+
``pAdicZZpXCAElements``, all of which are Teichmuller
|
|
1876
|
+
representatives and such that ``self`` is the sum of that
|
|
1877
|
+
list times powers of the uniformizer.
|
|
1878
|
+
|
|
1879
|
+
INPUT:
|
|
1880
|
+
|
|
1881
|
+
- ``n`` -- integer (default: ``None``); if given, returns the
|
|
1882
|
+
corresponding entry in the expansion
|
|
1883
|
+
|
|
1884
|
+
EXAMPLES::
|
|
1885
|
+
|
|
1886
|
+
sage: R = ZpCA(5,5)
|
|
1887
|
+
sage: S.<x> = ZZ[]
|
|
1888
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1889
|
+
sage: W.<w> = R.ext(f)
|
|
1890
|
+
sage: y = W(775, 19); y
|
|
1891
|
+
w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
|
|
1892
|
+
sage: (y>>9).expansion()
|
|
1893
|
+
[0, 1, 0, 4, 0, 2, 1, 2, 4, 1]
|
|
1894
|
+
sage: (y>>9).expansion(lift_mode='smallest')
|
|
1895
|
+
[0, 1, 0, -1, 0, 2, 1, 2, 0, 1]
|
|
1896
|
+
sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19)
|
|
1897
|
+
w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
|
|
1898
|
+
sage: g = x^3 + 3*x + 3
|
|
1899
|
+
|
|
1900
|
+
sage: # needs sage.libs.flint
|
|
1901
|
+
sage: A.<a> = R.ext(g)
|
|
1902
|
+
sage: y = 75 + 45*a + 1200*a^2; y
|
|
1903
|
+
4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
|
|
1904
|
+
sage: E = y.expansion(); E
|
|
1905
|
+
5-adic expansion of 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
|
|
1906
|
+
sage: list(E)
|
|
1907
|
+
[[], [0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1]]
|
|
1908
|
+
sage: list(y.expansion(lift_mode='smallest'))
|
|
1909
|
+
[[], [0, -1], [-2, 2, -2], [1], [0, 0, 2]]
|
|
1910
|
+
sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2)
|
|
1911
|
+
4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
|
|
1912
|
+
sage: W(0).expansion()
|
|
1913
|
+
[]
|
|
1914
|
+
sage: list(A(0,4).expansion())
|
|
1915
|
+
[]
|
|
1916
|
+
|
|
1917
|
+
Check that :issue:`25879` has been resolved::
|
|
1918
|
+
|
|
1919
|
+
sage: K = ZpCA(3,5)
|
|
1920
|
+
sage: R.<a> = K[]
|
|
1921
|
+
sage: L.<a> = K.extension(a^2 - 3)
|
|
1922
|
+
sage: a.residue()
|
|
1923
|
+
0
|
|
1924
|
+
"""
|
|
1925
|
+
if lift_mode == 'teichmuller':
|
|
1926
|
+
zero = self.parent()(0)
|
|
1927
|
+
elif self.prime_pow.e == 1:
|
|
1928
|
+
zero = []
|
|
1929
|
+
else:
|
|
1930
|
+
zero = Integer(0)
|
|
1931
|
+
ordp = self.valuation()
|
|
1932
|
+
if isinstance(n, slice):
|
|
1933
|
+
return self.slice(n.start, n.stop, n.step)
|
|
1934
|
+
elif n is not None:
|
|
1935
|
+
if self.is_zero() or n < ordp:
|
|
1936
|
+
return zero
|
|
1937
|
+
elif n >= self.absprec:
|
|
1938
|
+
raise PrecisionError
|
|
1939
|
+
if self.is_zero():
|
|
1940
|
+
return []
|
|
1941
|
+
if lift_mode == 'simple':
|
|
1942
|
+
ulist = self.ext_p_list(pos=True)
|
|
1943
|
+
elif lift_mode == 'smallest':
|
|
1944
|
+
ulist = self.ext_p_list(pos=False)
|
|
1945
|
+
elif lift_mode == 'teichmuller':
|
|
1946
|
+
if n is None:
|
|
1947
|
+
ulist = self.teichmuller_expansion()
|
|
1948
|
+
else:
|
|
1949
|
+
return self.teichmuller_expansion(n)
|
|
1950
|
+
else:
|
|
1951
|
+
raise ValueError("lift mode must be one of 'simple', 'smallest' or 'teichmuller'")
|
|
1952
|
+
if n is not None:
|
|
1953
|
+
try:
|
|
1954
|
+
return ulist[n - ordp]
|
|
1955
|
+
except IndexError:
|
|
1956
|
+
return zero
|
|
1957
|
+
return [zero] * ordp + ulist
|
|
1958
|
+
|
|
1959
|
+
def matrix_mod_pn(self):
|
|
1960
|
+
r"""
|
|
1961
|
+
Return the matrix of right multiplication by the element on
|
|
1962
|
+
the power basis `1, x, x^2, \ldots, x^{d-1}` for this
|
|
1963
|
+
extension field. Thus the *rows* of this matrix give the
|
|
1964
|
+
images of each of the `x^i`. The entries of the matrices are
|
|
1965
|
+
``IntegerMod`` elements, defined modulo ``p^(self.absprec() / e)``.
|
|
1966
|
+
|
|
1967
|
+
EXAMPLES::
|
|
1968
|
+
|
|
1969
|
+
sage: R = ZpCA(5,5)
|
|
1970
|
+
sage: S.<x> = ZZ[]
|
|
1971
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
1972
|
+
sage: W.<w> = R.ext(f)
|
|
1973
|
+
sage: a = (3+w)^7
|
|
1974
|
+
sage: a.matrix_mod_pn() # needs sage.geometry.polyhedron
|
|
1975
|
+
[2757 333 1068 725 2510]
|
|
1976
|
+
[ 50 1507 483 318 725]
|
|
1977
|
+
[ 500 50 3007 2358 318]
|
|
1978
|
+
[1590 1375 1695 1032 2358]
|
|
1979
|
+
[2415 590 2370 2970 1032]
|
|
1980
|
+
"""
|
|
1981
|
+
from sage.matrix.constructor import matrix
|
|
1982
|
+
# this may be the wrong precision when ram_prec_cap is not divisible by e.
|
|
1983
|
+
R = IntegerModRing(self.prime_pow.pow_Integer(self.prime_pow.capdiv(self.absprec)))
|
|
1984
|
+
n = self.prime_pow.deg
|
|
1985
|
+
L = []
|
|
1986
|
+
cdef ntl_ZZ_pX cur = <ntl_ZZ_pX>self._ntl_rep()
|
|
1987
|
+
cur.c.restore_c()
|
|
1988
|
+
cdef ZZ_pX_Modulus_c* m = self.prime_pow.get_modulus_capdiv(self.absprec)
|
|
1989
|
+
cdef ZZ_pX_c x
|
|
1990
|
+
ZZ_pX_SetX(x)
|
|
1991
|
+
cdef Py_ssize_t i
|
|
1992
|
+
zero = int(0)
|
|
1993
|
+
for i in range(n):
|
|
1994
|
+
curlist = cur.list()
|
|
1995
|
+
L.extend(curlist + [zero]*(n - len(curlist)))
|
|
1996
|
+
ZZ_pX_MulMod_pre(cur.x, cur.x, x, m[0])
|
|
1997
|
+
return matrix(R, n, n, L)
|
|
1998
|
+
|
|
1999
|
+
# def matrix(self, base=None):
|
|
2000
|
+
# """
|
|
2001
|
+
# If base is None, return the matrix of right multiplication by
|
|
2002
|
+
# the element on the power basis `1, x, x^2, \ldots, x^{d-1}`
|
|
2003
|
+
# for this extension field. Thus the \emph{rows} of this matrix
|
|
2004
|
+
# give the images of each of the `x^i`.
|
|
2005
|
+
|
|
2006
|
+
# If base is not None, then base must be either a field that
|
|
2007
|
+
# embeds in the parent of self or a morphism to the parent of
|
|
2008
|
+
# self, in which case this function returns the matrix of
|
|
2009
|
+
# multiplication by self on the power basis, where we view the
|
|
2010
|
+
# parent field as a field over base.
|
|
2011
|
+
|
|
2012
|
+
# INPUT:
|
|
2013
|
+
|
|
2014
|
+
# - ``base`` -- field or morphism
|
|
2015
|
+
# """
|
|
2016
|
+
# raise NotImplementedError
|
|
2017
|
+
|
|
2018
|
+
# def multiplicative_order(self, prec=None):
|
|
2019
|
+
# """
|
|
2020
|
+
# Returns the multiplicative order of ``self``, ie the smallest
|
|
2021
|
+
# positive `n` so that there is an exact `p`-adic element congruent
|
|
2022
|
+
# to ``self`` modulo ``self``'s precision that is an `n`-th root of unity.
|
|
2023
|
+
|
|
2024
|
+
# Note: unlike the case for Qp and Zp, it is possible to have
|
|
2025
|
+
# non-teichmuller elements with finite orders. This can happen
|
|
2026
|
+
# only if (p-1) divides the ramification index (see the
|
|
2027
|
+
# documentation on __pow__).
|
|
2028
|
+
|
|
2029
|
+
# INPUT:
|
|
2030
|
+
|
|
2031
|
+
# - self -- a `p`-adic element
|
|
2032
|
+
# - ``prec`` -- integer
|
|
2033
|
+
|
|
2034
|
+
# OUTPUT: integer; the multiplicative order of self
|
|
2035
|
+
# """
|
|
2036
|
+
# raise NotImplementedError
|
|
2037
|
+
|
|
2038
|
+
def teichmuller_expansion(self, n=None):
|
|
2039
|
+
r"""
|
|
2040
|
+
Return a list [`a_0`, `a_1`,..., `a_n`] such that:
|
|
2041
|
+
|
|
2042
|
+
- `a_i^q = a_i`
|
|
2043
|
+
- ``self.unit_part()`` = `\sum_{i = 0}^n a_i \pi^i`, where `\pi` is a
|
|
2044
|
+
uniformizer of self.parent()
|
|
2045
|
+
- if `a_i \ne 0`, the absolute precision of `a_i` is
|
|
2046
|
+
``self.precision_relative() - i``
|
|
2047
|
+
|
|
2048
|
+
INPUT:
|
|
2049
|
+
|
|
2050
|
+
- ``n`` -- integer (default: ``None``); if given, returns the
|
|
2051
|
+
corresponding entry in the expansion
|
|
2052
|
+
|
|
2053
|
+
EXAMPLES::
|
|
2054
|
+
|
|
2055
|
+
sage: R.<a> = Zq(5^4,4)
|
|
2056
|
+
sage: E = a.teichmuller_expansion(); E
|
|
2057
|
+
5-adic expansion of a + O(5^4) (teichmuller)
|
|
2058
|
+
sage: list(E)
|
|
2059
|
+
[a + (2*a^3 + 2*a^2 + 3*a + 4)*5 + (4*a^3 + 3*a^2 + 3*a + 2)*5^2 + (4*a^2 + 2*a + 2)*5^3 + O(5^4),
|
|
2060
|
+
(3*a^3 + 3*a^2 + 2*a + 1) + (a^3 + 4*a^2 + 1)*5 + (a^2 + 4*a + 4)*5^2 + O(5^3),
|
|
2061
|
+
(4*a^3 + 2*a^2 + a + 1) + (2*a^3 + 2*a^2 + 2*a + 4)*5 + O(5^2),
|
|
2062
|
+
(a^3 + a^2 + a + 4) + O(5)]
|
|
2063
|
+
sage: sum([c * 5^i for i, c in enumerate(E)])
|
|
2064
|
+
a + O(5^4)
|
|
2065
|
+
sage: all(c^625 == c for c in E)
|
|
2066
|
+
True
|
|
2067
|
+
|
|
2068
|
+
sage: S.<x> = ZZ[]
|
|
2069
|
+
sage: f = x^3 - 98*x + 7
|
|
2070
|
+
sage: W.<w> = ZpCA(7,3).ext(f)
|
|
2071
|
+
sage: b = (1+w)^5; L = b.teichmuller_expansion(); L
|
|
2072
|
+
[1 + O(w^9), 5 + 5*w^3 + w^6 + 4*w^7 + O(w^8), 3 + 3*w^3 + O(w^7),
|
|
2073
|
+
3 + 3*w^3 + O(w^6), O(w^5), 4 + 5*w^3 + O(w^4), 3 + O(w^3), 6 + O(w^2), 6 + O(w)]
|
|
2074
|
+
sage: sum([w^i*L[i] for i in range(9)]) == b
|
|
2075
|
+
True
|
|
2076
|
+
sage: all(L[i]^(7^3) == L[i] for i in range(9))
|
|
2077
|
+
True
|
|
2078
|
+
|
|
2079
|
+
sage: L = W(3).teichmuller_expansion(); L
|
|
2080
|
+
[3 + 3*w^3 + w^7 + O(w^9), O(w^8), O(w^7), 4 + 5*w^3 + O(w^6), O(w^5),
|
|
2081
|
+
O(w^4), 3 + O(w^3), 6 + O(w^2)]
|
|
2082
|
+
sage: sum([w^i*L[i] for i in range(len(L))])
|
|
2083
|
+
3 + O(w^9)
|
|
2084
|
+
"""
|
|
2085
|
+
cdef long ordp = self.valuation_c()
|
|
2086
|
+
cdef long rp = self.absprec - ordp
|
|
2087
|
+
cdef long goal
|
|
2088
|
+
if n is not None:
|
|
2089
|
+
goal = self.absprec - n
|
|
2090
|
+
cdef pAdicZZpXCAElement v
|
|
2091
|
+
if n is None:
|
|
2092
|
+
L = []
|
|
2093
|
+
if rp == 0:
|
|
2094
|
+
return L
|
|
2095
|
+
elif n < ordp:
|
|
2096
|
+
return self.parent()(0)
|
|
2097
|
+
elif n >= self.absprec:
|
|
2098
|
+
raise PrecisionError
|
|
2099
|
+
else:
|
|
2100
|
+
v = self._new_c(rp)
|
|
2101
|
+
cdef pAdicZZpXCAElement u = self.unit_part()
|
|
2102
|
+
if u is self:
|
|
2103
|
+
u = self.__copy__()
|
|
2104
|
+
while not ZZ_pX_IsZero(u.value):
|
|
2105
|
+
v = self._new_c(rp)
|
|
2106
|
+
self.prime_pow.teichmuller_set_c(&v.value, &u.value, rp)
|
|
2107
|
+
if n is None:
|
|
2108
|
+
L.append(v)
|
|
2109
|
+
elif rp == goal:
|
|
2110
|
+
return v
|
|
2111
|
+
if rp == 1:
|
|
2112
|
+
break
|
|
2113
|
+
ZZ_pX_sub(u.value, u.value, v.value)
|
|
2114
|
+
rp -= 1
|
|
2115
|
+
if self.prime_pow.e == 1:
|
|
2116
|
+
ZZ_pX_right_pshift(u.value, u.value, self.prime_pow.pow_ZZ_tmp(1)[0], self.prime_pow.get_context(rp).x)
|
|
2117
|
+
else:
|
|
2118
|
+
self.prime_pow.eis_shift_capdiv(&u.value, &u.value, 1, rp)
|
|
2119
|
+
if n is None:
|
|
2120
|
+
return L
|
|
2121
|
+
else:
|
|
2122
|
+
return self.parent()(0, rp)
|
|
2123
|
+
|
|
2124
|
+
def _teichmuller_set_unsafe(self):
|
|
2125
|
+
"""
|
|
2126
|
+
Set this element to the Teichmuller representative with the
|
|
2127
|
+
same residue.
|
|
2128
|
+
|
|
2129
|
+
.. WARNING::
|
|
2130
|
+
|
|
2131
|
+
This function modifies the element, which is not safe.
|
|
2132
|
+
Elements are supposed to be immutable.
|
|
2133
|
+
|
|
2134
|
+
EXAMPLES::
|
|
2135
|
+
|
|
2136
|
+
sage: R = ZpCA(11,5)
|
|
2137
|
+
sage: S.<x> = ZZ[]
|
|
2138
|
+
sage: f = x^5 + 33*x^3 - 121*x^2 - 77
|
|
2139
|
+
sage: W.<w> = R.ext(f)
|
|
2140
|
+
sage: y = W.teichmuller(3, 19); y # indirect doctest
|
|
2141
|
+
3 + 9*w^10 + 3*w^13 + 3*w^15 + 9*w^16 + 3*w^17 + w^18 + O(w^19)
|
|
2142
|
+
sage: y^11 == y
|
|
2143
|
+
True
|
|
2144
|
+
sage: g = x^3 + 9*x^2 + 7
|
|
2145
|
+
|
|
2146
|
+
sage: # needs sage.libs.flint
|
|
2147
|
+
sage: A.<a> = R.ext(g)
|
|
2148
|
+
sage: b = A.teichmuller(1 + 2*a - a^2); b
|
|
2149
|
+
(10*a^2 + 2*a + 1) + (4*a^2 + 7)*11 + (5*a^2 + a + 3)*11^2 + (a^2 + 9*a + 6)*11^3 + (7*a^2 + 2*a + 3)*11^4 + O(11^5)
|
|
2150
|
+
sage: b^1331 == b
|
|
2151
|
+
True
|
|
2152
|
+
|
|
2153
|
+
TESTS:
|
|
2154
|
+
|
|
2155
|
+
Check that :issue:`22083` has been resolved::
|
|
2156
|
+
|
|
2157
|
+
sage: R.<a> = ZpCA(2).extension(x^2 - 2)
|
|
2158
|
+
sage: R.teichmuller(a)
|
|
2159
|
+
O(a^40)
|
|
2160
|
+
"""
|
|
2161
|
+
if self.absprec == 0:
|
|
2162
|
+
raise ValueError("not enough precision known")
|
|
2163
|
+
elif self.valuation_c() > 0:
|
|
2164
|
+
self._set_inexact_zero(self.prime_pow.ram_prec_cap)
|
|
2165
|
+
else:
|
|
2166
|
+
self.prime_pow.teichmuller_set_c(&self.value, &self.value, self.absprec)
|
|
2167
|
+
|
|
2168
|
+
# def padded_list(self, n, lift_mode='simple'):
|
|
2169
|
+
# """
|
|
2170
|
+
# Returns a list of coefficients of pi starting with `pi^0` up to
|
|
2171
|
+
# `pi^n` exclusive (padded with zeros if needed)
|
|
2172
|
+
|
|
2173
|
+
# """
|
|
2174
|
+
# raise NotImplementedError
|
|
2175
|
+
|
|
2176
|
+
def precision_absolute(self):
|
|
2177
|
+
"""
|
|
2178
|
+
Return the absolute precision of ``self``, ie the power of the
|
|
2179
|
+
uniformizer modulo which this element is defined.
|
|
2180
|
+
|
|
2181
|
+
EXAMPLES::
|
|
2182
|
+
|
|
2183
|
+
sage: R = ZpCA(5,5)
|
|
2184
|
+
sage: S.<x> = ZZ[]
|
|
2185
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
2186
|
+
sage: W.<w> = R.ext(f)
|
|
2187
|
+
sage: a = W(75, 19); a
|
|
2188
|
+
3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
|
|
2189
|
+
sage: a.valuation()
|
|
2190
|
+
10
|
|
2191
|
+
sage: a.precision_absolute()
|
|
2192
|
+
19
|
|
2193
|
+
sage: a.precision_relative()
|
|
2194
|
+
9
|
|
2195
|
+
sage: a.unit_part()
|
|
2196
|
+
3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
|
|
2197
|
+
"""
|
|
2198
|
+
cdef Integer ans = PY_NEW(Integer)
|
|
2199
|
+
mpz_set_si(ans.value, self.absprec)
|
|
2200
|
+
return ans
|
|
2201
|
+
|
|
2202
|
+
def precision_relative(self):
|
|
2203
|
+
"""
|
|
2204
|
+
Return the relative precision of ``self``, ie the power of
|
|
2205
|
+
the uniformizer modulo which the unit part of ``self`` is
|
|
2206
|
+
defined.
|
|
2207
|
+
|
|
2208
|
+
EXAMPLES::
|
|
2209
|
+
|
|
2210
|
+
sage: R = ZpCA(5,5)
|
|
2211
|
+
sage: S.<x> = ZZ[]
|
|
2212
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
2213
|
+
sage: W.<w> = R.ext(f)
|
|
2214
|
+
sage: a = W(75, 19); a
|
|
2215
|
+
3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
|
|
2216
|
+
sage: a.valuation()
|
|
2217
|
+
10
|
|
2218
|
+
sage: a.precision_absolute()
|
|
2219
|
+
19
|
|
2220
|
+
sage: a.precision_relative()
|
|
2221
|
+
9
|
|
2222
|
+
sage: a.unit_part()
|
|
2223
|
+
3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
|
|
2224
|
+
"""
|
|
2225
|
+
cdef Integer ans = PY_NEW(Integer)
|
|
2226
|
+
mpz_set_ui(ans.value, self.absprec - self.valuation_c())
|
|
2227
|
+
return ans
|
|
2228
|
+
|
|
2229
|
+
# def residue(self, n):
|
|
2230
|
+
# """
|
|
2231
|
+
# Reduces this element modulo pi^n.
|
|
2232
|
+
# """
|
|
2233
|
+
# raise NotImplementedError
|
|
2234
|
+
|
|
2235
|
+
cdef long valuation_c(self) noexcept:
|
|
2236
|
+
"""
|
|
2237
|
+
Return the valuation of ``self``.
|
|
2238
|
+
|
|
2239
|
+
EXAMPLES::
|
|
2240
|
+
|
|
2241
|
+
sage: R = ZpCA(5,5)
|
|
2242
|
+
sage: S.<x> = ZZ[]
|
|
2243
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
2244
|
+
sage: W.<w> = R.ext(f)
|
|
2245
|
+
sage: a = W(75, 19); a
|
|
2246
|
+
3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
|
|
2247
|
+
sage: a.valuation() # indirect doctest
|
|
2248
|
+
10
|
|
2249
|
+
sage: a.precision_absolute()
|
|
2250
|
+
19
|
|
2251
|
+
sage: a.precision_relative()
|
|
2252
|
+
9
|
|
2253
|
+
sage: a.unit_part()
|
|
2254
|
+
3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
|
|
2255
|
+
"""
|
|
2256
|
+
if ZZ_pX_IsZero(self.value):
|
|
2257
|
+
return self.absprec
|
|
2258
|
+
cdef long minval = 0, mini = 0, val
|
|
2259
|
+
ZZ_pX_min_val_coeff(minval, mini, self.value, self.prime_pow.pow_ZZ_tmp(1)[0])
|
|
2260
|
+
if self.prime_pow.e == 1:
|
|
2261
|
+
if minval <= self.absprec:
|
|
2262
|
+
return minval
|
|
2263
|
+
else:
|
|
2264
|
+
return self.absprec
|
|
2265
|
+
else:
|
|
2266
|
+
val = minval * self.prime_pow.e + mini
|
|
2267
|
+
if val <= self.absprec:
|
|
2268
|
+
return val
|
|
2269
|
+
else:
|
|
2270
|
+
return self.absprec
|
|
2271
|
+
|
|
2272
|
+
cpdef pAdicZZpXCAElement unit_part(self):
|
|
2273
|
+
"""
|
|
2274
|
+
Return the unit part of ``self``, ie ``self / uniformizer^(self.valuation())``.
|
|
2275
|
+
|
|
2276
|
+
EXAMPLES::
|
|
2277
|
+
|
|
2278
|
+
sage: R = ZpCA(5,5)
|
|
2279
|
+
sage: S.<x> = ZZ[]
|
|
2280
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
2281
|
+
sage: W.<w> = R.ext(f)
|
|
2282
|
+
sage: a = W(75, 19); a
|
|
2283
|
+
3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
|
|
2284
|
+
sage: a.valuation()
|
|
2285
|
+
10
|
|
2286
|
+
sage: a.precision_absolute()
|
|
2287
|
+
19
|
|
2288
|
+
sage: a.precision_relative()
|
|
2289
|
+
9
|
|
2290
|
+
sage: a.unit_part()
|
|
2291
|
+
3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
|
|
2292
|
+
"""
|
|
2293
|
+
return self._rshift_c(self.valuation_c())
|
|
2294
|
+
|
|
2295
|
+
cdef ext_p_list(self, bint pos):
|
|
2296
|
+
"""
|
|
2297
|
+
Return a list of integers (in the Eisenstein case) or a list
|
|
2298
|
+
of lists of integers (in the unramified case). ``self`` can
|
|
2299
|
+
be reconstructed as a sum of elements of the list times powers
|
|
2300
|
+
of the uniformizer (in the Eisenstein case), or as a sum of
|
|
2301
|
+
powers of `p` times polynomials in the generator (in the
|
|
2302
|
+
unramified case).
|
|
2303
|
+
|
|
2304
|
+
If ``pos`` is ``True``, all integers will be in the interval
|
|
2305
|
+
`[0,p-1]`, otherwise they will be in the range
|
|
2306
|
+
`[(1-p)/2,p/2]`.
|
|
2307
|
+
|
|
2308
|
+
Note that zeros are truncated from the returned list, so you
|
|
2309
|
+
must use the ``valuation()`` function to completely recover
|
|
2310
|
+
``self``.
|
|
2311
|
+
|
|
2312
|
+
EXAMPLES::
|
|
2313
|
+
|
|
2314
|
+
sage: R = ZpCA(5,5)
|
|
2315
|
+
sage: S.<x> = ZZ[]
|
|
2316
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
2317
|
+
sage: W.<w> = R.ext(f)
|
|
2318
|
+
sage: y = W(775, 19); y
|
|
2319
|
+
w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
|
|
2320
|
+
sage: y._ext_p_list(True)
|
|
2321
|
+
[1, 0, 4, 0, 2, 1, 2, 4, 1]
|
|
2322
|
+
sage: y._ext_p_list(False)
|
|
2323
|
+
[1, 0, -1, 0, 2, 1, 2, 0, 1]
|
|
2324
|
+
sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19)
|
|
2325
|
+
w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
|
|
2326
|
+
sage: g = x^3 + 3*x + 3
|
|
2327
|
+
|
|
2328
|
+
sage: # needs sage.libs.flint
|
|
2329
|
+
sage: A.<a> = R.ext(g)
|
|
2330
|
+
sage: y = 75 + 45*a + 1200*a^2; y
|
|
2331
|
+
4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
|
|
2332
|
+
sage: y._ext_p_list(True)
|
|
2333
|
+
[[0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1]]
|
|
2334
|
+
sage: y._ext_p_list(False)
|
|
2335
|
+
[[0, -1], [-2, 2, -2], [1], [0, 0, 2]]
|
|
2336
|
+
sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2)
|
|
2337
|
+
4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
|
|
2338
|
+
"""
|
|
2339
|
+
return self.ext_p_list_precs(pos, self.absprec)
|
|
2340
|
+
|
|
2341
|
+
|
|
2342
|
+
def make_ZZpXCAElement(parent, value, absprec, version):
|
|
2343
|
+
"""
|
|
2344
|
+
For pickling. Makes a ``pAdicZZpXCAElement`` with given ``parent``, ``value``, ``absprec``.
|
|
2345
|
+
|
|
2346
|
+
EXAMPLES::
|
|
2347
|
+
|
|
2348
|
+
sage: from sage.rings.padics.padic_ZZ_pX_CA_element import make_ZZpXCAElement
|
|
2349
|
+
sage: R = ZpCA(5,5)
|
|
2350
|
+
sage: S.<x> = ZZ[]
|
|
2351
|
+
sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
|
|
2352
|
+
sage: W.<w> = R.ext(f)
|
|
2353
|
+
sage: make_ZZpXCAElement(W, ntl.ZZ_pX([3,2,4],5^3),13,0)
|
|
2354
|
+
3 + 2*w + 4*w^2 + O(w^13)
|
|
2355
|
+
"""
|
|
2356
|
+
cdef pAdicZZpXCAElement ans
|
|
2357
|
+
cdef ZZ_pX_c poly
|
|
2358
|
+
if version == 0:
|
|
2359
|
+
ans = pAdicZZpXCAElement(parent, [], empty = True)
|
|
2360
|
+
if mpz_sgn((<Integer>absprec).value) == 0:
|
|
2361
|
+
ans._set_inexact_zero(0)
|
|
2362
|
+
else:
|
|
2363
|
+
ans.prime_pow.restore_context_capdiv(mpz_get_si((<Integer>absprec).value))
|
|
2364
|
+
poly = (<ntl_ZZ_pX>value).x
|
|
2365
|
+
ans._set(&poly, mpz_get_si((<Integer>absprec).value))
|
|
2366
|
+
return ans
|
|
2367
|
+
else:
|
|
2368
|
+
raise ValueError("unknown unpickling version")
|