diff --git a/src/sage/libs/ntl/ntl_ZZ_p.pyx b/src/sage/libs/ntl/ntl_ZZ_p.pyx index 82ab0ff1fd1..d97ca5734f8 100644 --- a/src/sage/libs/ntl/ntl_ZZ_p.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_p.pyx @@ -414,6 +414,34 @@ cdef class ntl_ZZ_p: ZZ_p_modulus( &r.x, &self.x ) return r + def lift_centered(self): + """ + Compute a representative of ``self`` in `(-n/2 , n/2]` as an + ``ntl.ZZ object``. + + OUTPUT: + + - An ``ntl.ZZ`` object `r` such that `-n/2 < r <= n/2` and `Mod(r, n) == self`. + + EXAMPLES:: + + sage: x = ntl.ZZ_p(8, 18) + sage: x.lift_centered() + 8 + sage: type(x.lift()) + + sage: x = ntl.ZZ_p(12, 18) + sage: x.lift_centered() + -6 + sage: type(x.lift()) + + """ + cdef ntl_ZZ r = self.lift() + cdef ntl_ZZ m = self.modulus() + if r*2 > m: + r -= m + return r + def _integer_(self, ZZ=None): """ Return a lift of self as a Sage integer. diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 984c1896d8c..6148b2fab16 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1174,7 +1174,7 @@ cdef class Matrix(matrix1.Matrix): d = R(self._pari_().matdet()) else: # Lift to ZZ and compute there. - d = R(self.apply_map(lambda x : x.centerlift()).det()) + d = R(self.apply_map(lambda x : x.lift_centered()).det()) self.cache('det', d) return d diff --git a/src/sage/rings/arith.py b/src/sage/rings/arith.py index 63a6b34ecfe..50964562af9 100644 --- a/src/sage/rings/arith.py +++ b/src/sage/rings/arith.py @@ -2184,6 +2184,38 @@ def rational_reconstruction(a, m, algorithm='fast'): else: raise ValueError("unknown algorithm") +def lift_centered(p): + r""" + Compute a representative of the element `p` mod `n` in `(-n/2 , n/2]` + + INPUT: + + - ``p`` -- an integer mod `n` + + OUTPUT: + + - An integer `r` in `\ZZ` such that `-n/2 < r \leq n/2` + + For specific classes, check the `p.lift_centered` attribute. + + EXAMPLES:: + + sage: p = Mod(2,4) + sage: lift_centered(p) + 2 + sage: p = Mod(3,4) + sage: lift_centered(p) + -1 + """ + try: + return ZZ(p.lift_centered()) + except(AttributeError): + pass + r = p.lift() + if r*2 > p.modulus(): + r -= p.modulus() + return ZZ(r) + def _rational_reconstruction_python(a,m): """ Internal fallback function for rational_reconstruction; see diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index ebc2af42c76..27750477b31 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -723,28 +723,28 @@ cdef class IntegerMod_abstract(FiniteRingElement): """ return self - def centerlift(self): + def lift_centered(self): r""" Lift ``self`` to an integer `i` such that `n/2 < i <= n/2` (where `n` denotes the modulus). EXAMPLES:: - sage: Mod(0,5).centerlift() + sage: Mod(0,5).lift_centered() 0 - sage: Mod(1,5).centerlift() + sage: Mod(1,5).lift_centered() 1 - sage: Mod(2,5).centerlift() + sage: Mod(2,5).lift_centered() 2 - sage: Mod(3,5).centerlift() + sage: Mod(3,5).lift_centered() -2 - sage: Mod(4,5).centerlift() + sage: Mod(4,5).lift_centered() -1 - sage: Mod(50,100).centerlift() + sage: Mod(50,100).lift_centered() 50 - sage: Mod(51,100).centerlift() + sage: Mod(51,100).lift_centered() -49 - sage: Mod(-1,3^100).centerlift() + sage: Mod(-1,3^100).lift_centered() -1 """ n = self.modulus()