Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" ntl_lzz_p.pyx
Wraps NTL's zz_p type for SAGE
NOTE: This file is essentially useless. While we provide this wrapper for consistency, this should never be used in *production* code, i.e. anything intended to be fast. The reason for this is simple: this is a wrapper for a Python interface to the zz_p type, which is just a long! Any speed gains you get from working with longs will be TOTALLY destroyed by the overhead of having a wrapper.
AUTHORS: - Craig Citro """
#***************************************************************************** # Copyright (C) 2005 William Stein <wstein@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
from __future__ import absolute_import, division
from cysignals.signals cimport sig_on, sig_off
include 'misc.pxi' include 'decl.pxi' from sage.libs.gmp.mpz cimport *
from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer from sage.rings.integer_ring cimport IntegerRing_class
from sage.rings.finite_rings.integer_mod cimport IntegerMod_gmp, IntegerMod_int, IntegerMod_int64
from sage.libs.ntl.ntl_lzz_pContext import ntl_zz_pContext from sage.libs.ntl.ntl_lzz_pContext cimport ntl_zz_pContext_class from sage.arith.power cimport generic_power_pos
ZZ_sage = IntegerRing()
############################################################################## # # zz_pX -- polynomials over the integers modulo p, p small # ##############################################################################
cdef class ntl_zz_p(object): r""" The class \class{zz_p} implements arithmetic modulo $p$, for p smaller than a machine word.
NOTE: This type is provided mostly for completeness, and shouldn't be used in any production code. """ # See ntl_zz_p.pxd for definition of data members def __init__(self, a=0, modulus=None): """ EXAMPLES::
sage: f = ntl.zz_p(5,7) sage: f 5 sage: g = ntl.zz_p(int(-5),7) sage: g 2 """ raise ValueError("You must specify a modulus.")
else:
#self.c.restore_c() ## This was done in __new__
else: raise ValueError("Mismatched modulus for converting to zz_p.")
if (self.c.p == (<IntegerMod_int64>a).__modulus.int64): ## this is slow self.x = (<IntegerMod_int64>a).ivalue else: raise ValueError("Mismatched modulus for converting to zz_p.")
if (p_sage == (<IntegerMod_gmp>a).__modulus.sageInteger): ## this is slow self.x = mpz_get_si((<IntegerMod_gmp>a).value) else: raise ValueError("Mismatched modulus for converting to zz_p.")
## we're lucky that python int is no larger than long else: a = Integer(a) self.x = mpz_get_si((<Integer>a).value)%self.c.p
def __cinit__(self, v=None, modulus=None): #################### WARNING ################### ## Before creating a zz_p, you must create a ## ## zz_pContext, and restore it. In Python, ## ## the error checking in __init__ will prevent## ## you from constructing a zz_p ## ## inappropriately. However, from Cython, you## ## could do r = ntl_zz_p.__new__(ntl_zz_p) without ## first restoring a zz_pContext, which could ## ## have unfortunate consequences. See _new ## ## defined below for an example of the right ## ## way to short-circuit __init__ (or just call## ## _new in your own code). ## ################################################ elif isinstance(modulus, long): self.c = <ntl_zz_pContext_class>ntl_zz_pContext(modulus) else: try: modulus = int(modulus) except Exception: raise ValueError("%s is not a valid modulus." % modulus) self.c = <ntl_zz_pContext_class>ntl_zz_pContext(modulus)
## now that we've determined the modulus, set that modulus.
cdef ntl_zz_p _new(self): """ Quick and dirty zz_p object creation.
EXAMPLES: sage: x = ntl.zz_p(23,75) sage: y = x*x ## indirect doctest """ cdef ntl_zz_p y
def __reduce__(self): """ For pickling.
TESTS: sage: f = ntl.zz_p(16,244) sage: loads(dumps(f)) == f True """
def __repr__(self): """ Return the string representation of self.
EXAMPLES::
sage: ntl.zz_p(3,79).__repr__() '3' """
def __add__(ntl_zz_p self, other): """ EXAMPLES: sage: ntl.zz_p(5,23) + ntl.zz_p(6,23) 11 """ cdef ntl_zz_p y other = ntl_zz_p(other, modulus=self.c)
def __sub__(ntl_zz_p self, other): """ EXAMPLES: sage: ntl.zz_p(5,23) - ntl.zz_p(6,23) 22 """ cdef ntl_zz_p y other = ntl_zz_p(other, modulus=self.c) raise ValueError("arithmetic operands must have the same modulus.")
def __mul__(ntl_zz_p self, other): """ EXAMPLES: sage: ntl.zz_p(5,23) * ntl.zz_p(6,23) 7 """ cdef ntl_zz_p y other = ntl_zz_p(other, modulus=self.c) raise ValueError("arithmetic operands must have the same modulus.")
def __truediv__(ntl_zz_p self, other): """ EXAMPLES: sage: ntl.zz_p(5,23) / ntl.zz_p(2,23) 14 """ cdef ntl_zz_p q other = ntl_zz_p(other, modulus=self.c) raise ValueError("arithmetic operands must have the same modulus.")
def __div__(self, other):
def __pow__(ntl_zz_p self, long n, ignored): """ Return the n-th nonnegative power of self.
EXAMPLES::
sage: g = ntl.zz_p(5, 13) sage: g ^ 10 12 sage: g ^ (-1) 8 sage: g ^ (-5) 8 sage: g ^ 0 1 sage: z = ntl.zz_p(0, 13) sage: z ^ 0 1 sage: z ^ 1 0 sage: z ^ (-1) Traceback (most recent call last): ... ZeroDivisionError: inverse does not exist """
cdef ntl_zz_p y else:
def __neg__(self): """ Return the negative of self.
EXAMPLES: sage: f = ntl.zz_p(5,234) sage: -f ## indirect doctest 229 """ cdef ntl_zz_p y
def __richcmp__(ntl_zz_p self, other, int op): """ Compare self to other.
EXAMPLES::
sage: f = ntl.zz_p(3,20) sage: g = ntl.zz_p(2,20) sage: h = ntl.zz_p(3,60) sage: f == g False sage: f == f True sage: f == h True sage: f == 3 True """
raise TypeError("integers mod p are not ordered")
cdef ntl_zz_p b
def __int__(self): """ Return self as an int.
EXAMPLES: sage: ntl.zz_p(3,next_prime(100)).__int__() 3 sage: int(ntl.zz_p(3,next_prime(100))) 3 sage: type(int(ntl.zz_p(3,next_prime(100)))) <... 'int'> """
def square(self): """ Return f*f.
EXAMPLES: sage: f = ntl.zz_p(15,23) sage: f*f 18 """ cdef ntl_zz_p y y = self._new() self.c.restore_c() zz_p_sqr(y.x, self.x) return y
def is_zero(self): """ Return True exactly if this element is 0.
EXAMPLES: sage: f = ntl.zz_p(0,20) sage: f.is_zero() True sage: f = ntl.zz_p(1,20) sage: f.is_zero() False """
def is_one(self): """ Return True exactly if this element is 1.
EXAMPLES: sage: f = ntl.zz_p(1,11) sage: f.is_one() True sage: f = ntl.zz_p(5,11) sage: f.is_one() False """
def clear(self): """ Reset this element to 0.
EXAMPLES: sage: x = ntl.zz_p(5,102) ; x 5 sage: x.clear() ; x 0 """
def make_zz_p(val, context): """ For unpickling.
TESTS: sage: f = ntl.zz_p(1, 12) sage: loads(dumps(f)) == f True """ |