Ticket #4302: polynomial_gf2x.patch
File polynomial_gf2x.patch, 46.0 KB (added by , 14 years ago) |
---|
-
sage/libs/ntl/ntl_GF2X.pyx
# HG changeset patch # User Martin Albrecht <malb@informatik.uni-bremen.de> # Date 1224185877 -7200 # Node ID 9203a9b3ec2aa88bb050a84ac26bfed1f418fd4a # Parent 85bf25beff4fb6e3af81e175b055fee82167c566 implement polynomials over GF(2) via GF2X and introduce polynomial templates also implemented native modular polynomial composition over GF(2) via libM4RI. diff -r 85bf25beff4f -r 9203a9b3ec2a sage/libs/ntl/ntl_GF2X.pyx
a b 23 23 24 24 from ntl_ZZ import unpickle_class_value 25 25 from ntl_GF2 cimport ntl_GF2 26 26 27 27 28 ############################################################################## 28 29 # … … 123 124 from sage.rings.finite_field_givaro import FiniteField_givaroElement 124 125 from sage.rings.finite_field_ntl_gf2e import FiniteField_ntl_gf2eElement 125 126 from sage.rings.ring import FiniteField 126 from sage.rings.polynomial.polynomial_ modn_dense_ntl import Polynomial_dense_mod_p127 from sage.rings.polynomial.polynomial_gf2x import Polynomial_GF2X 127 128 128 129 cdef long _x 129 130 … … 141 142 if PY_TYPE_CHECK(x, Integer): 142 143 #binary repr, reversed, and "["..."]" added 143 144 x="["+x.binary()[::-1].replace(""," ")+"]" 144 elif PY_TYPE_CHECK(x, Polynomial_ dense_mod_p):145 x=x.ntl_ZZ_pX()145 elif PY_TYPE_CHECK(x, Polynomial_GF2X): 146 x = x.list() # this is slow but cimport leads to circular imports 146 147 elif PY_TYPE_CHECK(x, FiniteField): 147 148 if x.characteristic() == 2: 148 149 x= list(x.modulus()) -
new file sage/libs/ntl/ntl_GF2X_decl.pxd
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/libs/ntl/ntl_GF2X_decl.pxd
- + 1 from sage.libs.ntl.ntl_GF2_decl cimport GF2_c 2 from sage.libs.ntl.ntl_ZZ_decl cimport ZZ_c 3 4 cdef extern from "ntl_wrap.h": 5 ctypedef struct GF2X_c "struct GF2X": 6 pass 7 8 long *GF2XHexOutput_c "(&GF2X::HexOutput)" # work-around for Cython bug 9 10 GF2X_c* GF2X_new "New<GF2X>"() 11 GF2X_c* GF2X_construct "Construct<GF2X>"(void *mem) 12 void GF2X_destruct "Destruct<GF2X>"(GF2X_c *mem) 13 void GF2X_delete "Delete<GF2X>"(GF2X_c *mem) 14 void GF2X_from_str "_from_str<GF2X>"(GF2X_c* dest, char* s) 15 object GF2X_to_PyString "_to_PyString<GF2X>"(GF2X_c *x) 16 int GF2X_equal "_equal<GF2X>"(GF2X_c x, GF2X_c y) 17 int GF2X_IsOne "IsOne"(GF2X_c x) 18 int GF2X_IsZero "IsZero"(GF2X_c x) 19 int GF2X_IsX "IsX"(GF2X_c x) 20 21 void GF2X_add "add"( GF2X_c x, GF2X_c a, GF2X_c b) 22 void GF2X_sub "sub"( GF2X_c x, GF2X_c a, GF2X_c b) 23 void GF2X_mul "mul"( GF2X_c x, GF2X_c a, GF2X_c b) 24 void GF2X_negate "negate"(GF2X_c x, GF2X_c a) 25 void GF2X_power "power"(GF2X_c t, GF2X_c x, long e) 26 long GF2X_deg "deg"(GF2X_c x) 27 28 void GF2X_conv_long "conv" (GF2X_c x, long a) 29 void GF2X_conv_GF2 "conv" (GF2X_c x, GF2_c a) 30 31 void GF2X_LeftShift "LeftShift"( GF2X_c r, GF2X_c a, long offset) 32 void GF2X_RightShift "RightShift"( GF2X_c r, GF2X_c a, long offset) 33 34 void GF2X_DivRem "DivRem"(GF2X_c q, GF2X_c r, GF2X_c a, GF2X_c b) 35 void GF2X_div "div" (GF2X_c q, GF2X_c a, GF2X_c b) 36 void GF2X_rem "rem" (GF2X_c r, GF2X_c a, GF2X_c b) 37 long GF2X_divide "divide"(GF2X_c q, GF2X_c a, GF2X_c b) 38 39 void GF2X_GCD "GCD" (GF2X_c r, GF2X_c a, GF2X_c b) 40 void GF2X_XGCD "XGCD" (GF2X_c r, GF2X_c s, GF2X_c t, GF2X_c a, GF2X_c b) 41 42 void GF2XFromBytes(GF2X_c a, unsigned char *p, long n) 43 void BytesFromGF2X "BytesFromGF2X" (unsigned char *p, GF2X_c a, long n) 44 45 GF2_c GF2X_coeff "coeff"(GF2X_c a, long i) 46 GF2_c GF2X_LeadCoeff "LeadCoeff"(GF2X_c a) 47 GF2_c GF2X_ConstTerm "ConstTerm"(GF2X_c a) 48 void GF2X_SetCoeff "SetCoeff"(GF2X_c x, long i, GF2_c a) 49 void GF2X_SetCoeff_long "SetCoeff"(GF2X_c x, long i, long a) 50 51 GF2X_c GF2X_diff "diff"(GF2X_c a) 52 GF2X_c GF2X_reverse "reverse"(GF2X_c a, long hi) 53 54 long GF2X_weight "weight"(GF2X_c a) 55 long GF2X_NumBits "NumBits" (GF2X_c a) 56 long GF2X_NumBytes "NumBytes"(GF2X_c a) 57 58 #### GF2XFactoring 59 void GF2X_BuildSparseIrred "BuildSparseIrred" (GF2X_c f, long n) 60 void GF2X_BuildRandomIrred "BuildRandomIrred" (GF2X_c f, GF2X_c g) 61 62 #### GF2XModulus_c 63 ctypedef struct GF2XModulus_c "struct GF2XModulus": 64 pass 65 66 GF2XModulus_c* GF2XModulus_new "New<GF2XModulus>"() 67 GF2XModulus_c* GF2XModulus_construct "Construct<GF2XModulus>"(void *mem) 68 void GF2XModulus_destruct "Destruct<GF2XModulus>"(GF2XModulus_c *mem) 69 void GF2XModulus_delete "Delete<GF2XModulus>"(GF2XModulus_c *mem) 70 void GF2XModulus_from_str "_from_str<GF2XModulus>"(GF2XModulus_c* dest, char* s) 71 void GF2XModulus_build "build"(GF2XModulus_c F, GF2X_c f) # MUST be called before using the modulus 72 long GF2XModulus_deg "deg"(GF2XModulus_c F) 73 74 75 GF2X_c GF2XModulus_GF2X "GF2X" (GF2XModulus_c m) 76 77 GF2X_c GF2X_IrredPolyMod "IrredPolyMod" (GF2X_c g, GF2XModulus_c F) 78 79 void GF2X_MulMod_pre "MulMod"(GF2X_c x, GF2X_c a, GF2X_c b, GF2XModulus_c F) 80 void GF2X_SqrMod_pre "SqrMod"(GF2X_c x, GF2X_c a, GF2XModulus_c F) 81 void GF2X_PowerMod_pre "PowerMod"(GF2X_c x, GF2X_c a, ZZ_c e, GF2XModulus_c F) 82 void GF2X_PowerMod_long_pre "PowerMod"(GF2X_c x, GF2X_c a, long e, GF2XModulus_c F) 83 void GF2X_PowerXMod_pre "PowerXMod"(GF2X_c x, ZZ_c e, GF2XModulus_c F) 84 void GF2X_PowerXMod_long_pre "PowerXMod"(GF2X_c x, long e, GF2XModulus_c F) 85 void GF2X_PowerXPlusAMod_pre "PowerXPlusAMod"(GF2X_c x, GF2_c a, GF2_c e, GF2XModulus_c F) 86 void GF2X_PowerXPlusAMod_long_pre "PowerXPlusAMod"(GF2X_c x, GF2_c a, long e, GF2XModulus_c F) 87 88 89 # x = g(h) mod f; deg(h) < n 90 void GF2X_CompMod "CompMod"(GF2X_c x, GF2X_c g, GF2X_c h, GF2XModulus_c F) 91 # xi = gi(h) mod f (i=1,2), deg(h) < n. 92 void GF2X_Comp2Mod "Comp2Mod"(GF2X_c x1, GF2X_c x2, GF2X_c g1, GF2X_c g2, GF2X_c h, GF2XModulus_c F) 93 94 # xi = gi(h) mod f (i=1,2,3), deg(h) < n. 95 void GF2X_CompMod3 "Comp2Mod"(GF2X_c x1, GF2X_c x2, GF2X_c x3, GF2X_c g1, GF2X_c g2, GF2X_c g3, GF2X_c h, GF2XModulus_c F) -
new file sage/libs/ntl/ntl_GF2X_linkage.pxi
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/libs/ntl/ntl_GF2X_linkage.pxi
- + 1 r""" 2 Linkage for arithmetic with NTL's GF2X elements. 3 4 This file provides the backend for \class{Polynomial_GF2X} via 5 templating. 6 7 AUTHOR: 8 -- Martin Albrecht (2008-10): initial version 9 """ 10 #***************************************************************************** 11 # Copyright (C) 2008 Martin Albrecht <M.R.Albrecht@rhul.ac.uk> 12 # 13 # Distributed under the terms of the GNU General Public License (GPL) 14 # http://www.gnu.org/licenses/ 15 #***************************************************************************** 16 17 from sage.libs.ntl.ntl_GF2_decl cimport *, GF2_c 18 from sage.libs.ntl.ntl_GF2X_decl cimport *, GF2X_c, GF2XModulus_c 19 20 cdef int celement_construct(GF2X_c *e, parent): 21 """ 22 EXAMPLE: 23 sage: P.<x> = GF(2)[] 24 """ 25 GF2X_construct(e) 26 27 cdef int celement_destruct(GF2X_c *e, parent): 28 """ 29 EXAMPLE: 30 sage: P.<x> = GF(2)[] 31 sage: del x 32 """ 33 GF2X_destruct(e) 34 35 cdef int celement_gen(GF2X_c *e, long i, parent) except -2: 36 """ 37 EXAMPLE: 38 sage: P.<x> = GF(2)[] 39 """ 40 cdef unsigned char g = 2 41 GF2XFromBytes(e[0], <unsigned char *>(&g), 1) 42 43 cdef object celement_repr(GF2X_c *e, parent): 44 """ 45 We ignore NTL's printing. 46 47 EXAMPLE: 48 sage: P.<x> = GF(2)[] 49 sage: x 50 x 51 """ 52 #return GF2X_to_PyString(e) 53 raise NotImplementedError 54 55 cdef inline int celement_set(GF2X_c* res, GF2X_c* a, parent) except -2: 56 """ 57 EXAMPLE: 58 sage: P.<x> = GF(2)[] 59 sage: y = x; y 60 x 61 """ 62 res[0] = a[0] 63 64 cdef inline int celement_set_si(GF2X_c* res, long i, parent) except -2: 65 """ 66 EXAMPLE: 67 sage: P.<x> = GF(2)[] 68 sage: P(0) 69 0 70 sage: P(2) 71 0 72 sage: P(1) 73 1 74 """ 75 GF2X_conv_long(res[0], i) 76 77 cdef inline long celement_get_si(GF2X_c* res, parent) except -2: 78 raise NotImplementedError 79 80 cdef inline bint celement_is_zero(GF2X_c* a, parent) except -2: 81 """ 82 EXAMPLE: 83 sage: P.<x> = GF(2)[] 84 sage: bool(x), x.is_zero() 85 (True, False) 86 sage: bool(P(0)), P(0).is_zero() 87 (False, True) 88 """ 89 return GF2X_IsZero(a[0]) 90 91 cdef inline bint celement_is_one(GF2X_c *a, parent) except -2: 92 """ 93 EXAMPLE: 94 sage: P.<x> = GF(2)[] 95 sage: x.is_one() 96 False 97 sage: P(1).is_one() 98 True 99 """ 100 return GF2X_IsOne(a[0]) 101 102 cdef inline bint celement_equal(GF2X_c *a, GF2X_c *b, parent) except -2: 103 """ 104 EXAMPLE: 105 sage: P.<x> = GF(2)[] 106 sage: x == x 107 True 108 sage: y = x; x == y 109 True 110 sage: x^2 + 1 == x^2 + x 111 False 112 """ 113 return GF2X_equal(a[0], b[0]) 114 115 cdef inline int celement_cmp(GF2X_c *a, GF2X_c *b, parent) except -2: 116 """ 117 EXAMPLE: 118 sage: P.<x> = GF(2)[] 119 sage: x != 1 120 True 121 sage: x < 1 122 False 123 sage: x > 1 124 True 125 """ 126 cdef bint t 127 cdef long diff 128 diff = GF2X_NumBits(a[0]) - GF2X_NumBits(b[0]) 129 if diff > 0: 130 return 1 131 elif diff == 0: 132 t = GF2X_equal(a[0], b[0]) 133 return not t 134 else: 135 return -1 136 137 cdef inline long celement_hash(GF2X_c *a, parent) except -2: 138 """ 139 EXAMPLE: 140 sage: P.<x> = GF(2)[] 141 sage: {x:1} 142 {x: 1} 143 """ 144 cdef long _hex = GF2XHexOutput_c[0] 145 GF2XHexOutput_c[0] = 1 146 s = GF2X_to_PyString(a) 147 GF2XHexOutput_c[0] = _hex 148 return hash(s) 149 150 cdef long celement_len(GF2X_c *a, parent) except -2: 151 """ 152 EXAMPLE: 153 sage: P.<x> = GF(2)[] 154 sage: len(x) 155 2 156 sage: len(x+1) 157 2 158 """ 159 return int(GF2X_NumBits(a[0])) 160 161 cdef inline int celement_add(GF2X_c *res, GF2X_c *a, GF2X_c *b, parent) except -2: 162 """ 163 EXAMPLE: 164 sage: P.<x> = GF(2)[] 165 sage: x + 1 166 x + 1 167 """ 168 GF2X_add(res[0], a[0], b[0]) 169 170 cdef inline int celement_sub(GF2X_c* res, GF2X_c* a, GF2X_c* b, parent) except -2: 171 """ 172 EXAMPLE: 173 sage: P.<x> = GF(2)[] 174 sage: x - 1 175 x + 1 176 """ 177 GF2X_sub(res[0], a[0], b[0]) 178 179 cdef inline int celement_neg(GF2X_c* res, GF2X_c* a, parent) except -2: 180 """ 181 EXAMPLE: 182 sage: P.<x> = GF(2)[] 183 sage: -x 184 x 185 """ 186 res[0] = a[0] 187 188 cdef inline int celement_mul(GF2X_c* res, GF2X_c* a, GF2X_c* b, parent) except -2: 189 """ 190 EXAMPLE: 191 sage: P.<x> = GF(2)[] 192 sage: x*(x+1) 193 x^2 + x 194 """ 195 GF2X_mul(res[0], a[0], b[0]) 196 197 cdef inline int celement_div(GF2X_c* res, GF2X_c* a, GF2X_c* b, parent) except -2: 198 """ 199 EXAMPLE: 200 sage: P.<x> = GF(2)[] 201 """ 202 return GF2X_divide(res[0], a[0], b[0]) 203 204 cdef inline int celement_floordiv(GF2X_c* res, GF2X_c* a, GF2X_c* b, parent) except -2: 205 """ 206 EXAMPLE: 207 sage: P.<x> = GF(2)[] 208 sage: x//(x + 1) 209 1 210 sage: (x + 1)//x 211 1 212 """ 213 GF2X_div(res[0], a[0], b[0]) 214 215 cdef inline int celement_mod(GF2X_c* res, GF2X_c* a, GF2X_c* b, parent) except -2: 216 """ 217 EXAMPLE: 218 sage: P.<x> = GF(2)[] 219 sage: (x^2 + 1) % x^2 220 1 221 """ 222 GF2X_rem(res[0], a[0], b[0]) 223 224 cdef inline int celement_quorem(GF2X_c* q, GF2X_c* r, GF2X_c* a, GF2X_c* b, parent) except -2: 225 """ 226 EXAMPLE: 227 sage: P.<x> = GF(2)[] 228 sage: f = x^2 + x + 1 229 sage: f.quo_rem(x + 1) 230 (x, 1) 231 """ 232 GF2X_DivRem(q[0], r[0], a[0], b[0]) 233 234 cdef inline int celement_inv(GF2X_c* res, GF2X_c* a, parent) except -2: 235 """ 236 We ignore NTL here and use the fraction field constructor. 237 238 EXAMPLE: 239 sage: P.<x> = GF(2)[] 240 """ 241 raise NotImplementedError 242 243 cdef inline int celement_pow(GF2X_c* res, GF2X_c* x, long e, GF2X_c *modulus, parent) except -2: 244 """ 245 EXAMPLE: 246 sage: P.<x> = GF(2)[] 247 sage: x^1000 248 x^1000 249 sage: (x+1)^2 250 x^2 + 1 251 sage: (x+1)^(-2) 252 1/(x^2 + 1) 253 sage: f = x^9 + x^7 + x^6 + x^5 + x^4 + x^2 + x 254 sage: h = x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + 1 255 sage: (f^2) % h 256 x^9 + x^8 + x^7 + x^5 + x^3 257 sage: pow(f, 2, h) 258 x^9 + x^8 + x^7 + x^5 + x^3 259 """ 260 cdef GF2XModulus_c mod 261 262 if modulus == NULL: 263 if GF2X_IsX(x[0]): 264 GF2X_LeftShift(res[0], x[0], e - 1) 265 else: 266 do_sig = GF2X_deg(x[0]) > 1e5 267 if do_sig: _sig_on 268 GF2X_power(res[0], x[0], e) 269 if do_sig: _sig_off 270 else: 271 GF2XModulus_build(mod, modulus[0]) 272 273 do_sig = GF2X_deg(x[0]) > 1e5 274 if do_sig: _sig_on 275 GF2X_PowerMod_long_pre(res[0], x[0], e, mod) 276 if do_sig: _sig_off 277 278 cdef inline int celement_gcd(GF2X_c* res, GF2X_c* a, GF2X_c *b, parent) except -2: 279 """ 280 EXAMPLE: 281 sage: P.<x> = GF(2)[] 282 sage: f = x*(x+1) 283 sage: f.gcd(x+1) 284 x + 1 285 sage: f.gcd(x^2) 286 x 287 """ 288 GF2X_GCD(res[0], a[0], b[0]) -
new file sage/libs/ntl/ntl_GF2_decl.pxd
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/libs/ntl/ntl_GF2_decl.pxd
- + 1 cdef extern from "ntl_wrap.h": 2 ctypedef struct GF2_c "struct GF2": 3 pass 4 5 GF2_c* GF2_new "New<GF2>"() 6 GF2_c* GF2_construct "Construct<GF2>"(void *mem) 7 void GF2_destruct "Destruct<GF2>"(GF2_c *mem) 8 void GF2_delete "Delete<GF2>"(GF2_c *mem) 9 void GF2_from_str "_from_str<GF2>"(GF2_c* dest, char* s) 10 object GF2_to_PyString "_to_PyString<GF2>"(GF2_c *x) 11 int GF2_equal "_equal<GF2>"(GF2_c x, GF2_c y) 12 int GF2_IsOne "IsOne"(GF2_c x) 13 int GF2_IsZero "IsZero"(GF2_c x) 14 15 void GF2_add "add"( GF2_c x, GF2_c a, GF2_c b) 16 void GF2_sub "sub"( GF2_c x, GF2_c a, GF2_c b) 17 void GF2_mul "mul"( GF2_c x, GF2_c a, GF2_c b) 18 void GF2_div "div"( GF2_c x, GF2_c a, GF2_c b) 19 void GF2_negate "negate"(GF2_c x, GF2_c a) 20 void GF2_power "power"(GF2_c t, GF2_c x, long e) 21 long GF2_deg "deg"(GF2_c x) 22 23 void GF2_conv_long "conv" (GF2_c x, long i) 24 long GF2_conv_to_long "rep" (GF2_c x) -
sage/matrix/matrix_mod2_dense.pyx
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/matrix/matrix_mod2_dense.pyx
a b 1403 1403 gdImageDestroy(im) 1404 1404 return unpickle_matrix_mod2_dense_v1, (r,c, data, size) 1405 1405 1406 1407 1406 # Used for hashing 1408 1407 cdef int i, k 1409 1408 cdef unsigned long parity_table[256] … … 1565 1564 gdImageDestroy(im) 1566 1565 fclose(out) 1567 1566 1568 1569 1570 1571 1567 # This is basically test code, do not call it will break Sage's 1572 1568 # assumptions about matrices (malb). 1573 1569 -
sage/rings/polynomial/polynomial_element.pyx
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/rings/polynomial/polynomial_element.pyx
a b 986 986 return RingElement.__div__(self, right) 987 987 988 988 989 def __pow__(self, right, dummy):989 def __pow__(self, right, modulus): 990 990 """ 991 991 EXAMPLES: 992 992 sage: R.<x> = ZZ[] … … 997 997 x^3 - 3*x^2 + 3*x - 1 998 998 """ 999 999 if self.degree() <= 0: 1000 r eturnself.parent()(self[0]**right)1001 if right < 0:1002 r eturn(~self)**(-right)1003 if (<Polynomial>self)._is_gen: # special case x**n should be faster!1000 r = self.parent()(self[0]**right) 1001 elif right < 0: 1002 r = (~self)**(-right) 1003 elif (<Polynomial>self) == self.parent().gen(): # special case x**n should be faster! 1004 1004 P = self.parent() 1005 1005 R = P.base_ring() 1006 1006 if P.is_sparse(): 1007 1007 v = {right:R(1)} 1008 1008 else: 1009 1009 v = [R(0)]*right + [R(1)] 1010 return self.parent()(v, check=False) 1011 return generic_power(self, right) 1010 r = self.parent()(v, check=False) 1011 else: 1012 r = generic_power(self, right) 1013 if modulus: 1014 return r % modulus 1015 else: 1016 return r 1012 1017 1013 1018 def _pow(self, right): 1014 1019 # TODO: fit __pow__ into the arithmetic structure … … 1016 1021 return self.parent()(self[0]**right) 1017 1022 if right < 0: 1018 1023 return (~self)**(-right) 1019 if (<Polynomial>self) ._is_gen: # special case x**n should be faster!1024 if (<Polynomial>self) == self.parent().gen(): # special case x**n should be faster! 1020 1025 v = [0]*right + [1] 1021 1026 return self.parent()(v, check=True) 1022 1027 return generic_power(self, right) … … 2188 2193 pari.set_real_precision(n) # restore precision 2189 2194 return Factorization(F, unit) 2190 2195 2196 def lcm(self, other): 2197 """ 2198 Let f and g be two polynomials. Then this function 2199 returns the monic least common multiple of f and g. 2200 """ 2201 f = self*other 2202 g = self.gcd(other) 2203 q = f//g 2204 return ~(q.leading_coefficient())*q 2205 2191 2206 def _lcm(self, other): 2192 2207 """ 2193 2208 Let f and g be two polynomials. Then this function … … 2197 2212 g = self.gcd(other) 2198 2213 q = f//g 2199 2214 return ~(q.leading_coefficient())*q # make monic (~ is inverse in python) 2215 2216 def is_primitive(self): 2217 """ 2218 Identifies whether a polynomial is primitive. 2219 A polynomial can only be primitive if it is irreducible. 2220 2221 EXAMPLES: 2222 sage: R.<x> = GF(2)['x'] 2223 sage: f = x^4+x^3+x^2+x+1 2224 sage: f.is_irreducible(), f.is_primitive() 2225 (True, False) 2226 sage: f = x^3+x+1 2227 sage: f.is_irreducible(), f.is_primitive() 2228 (True, True) 2229 sage: R.<x> = GF(3)[] 2230 sage: f = x^3-x+1 2231 sage: f.is_irreducible(), f.is_primitive() 2232 (True, True) 2233 sage: f = x^2+1 2234 sage: f.is_irreducible(), f.is_primitive() 2235 (True, False) 2236 sage: R.<x> = GF(5)[] 2237 sage: f = x^2+x+1 2238 sage: f.is_primitive() 2239 False 2240 sage: f = x^2-x+2 2241 sage: f.is_primitive() 2242 True 2243 """ 2244 if not self.is_irreducible(): 2245 return False 2246 p = self.parent().characteristic() 2247 n = p ** self.degree() - 1 2248 y = self.parent().quo(self).gen() 2249 for d in n.prime_divisors(): 2250 if ( y ** (n//d) ) == 1: 2251 return False 2252 return True 2200 2253 2201 2254 def is_constant(self): 2202 2255 """ -
new file sage/rings/polynomial/polynomial_gf2x.pxd
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/rings/polynomial/polynomial_gf2x.pxd
- + 1 from sage.libs.ntl.ntl_GF2X_decl cimport GF2X_c 2 3 ctypedef GF2X_c celement 4 5 include "polynomial_template_header.pxi" 6 7 cdef class Polynomial_GF2X(Polynomial_template): 8 pass 9 -
new file sage/rings/polynomial/polynomial_gf2x.pyx
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/rings/polynomial/polynomial_gf2x.pyx
- + 1 """ 2 Univariate Polynomials over GF(2) via NTL's GF2X. 3 4 AUTHOR: 5 -- Martin Albrecht (2008-10) initial implementation 6 """ 7 8 include "../../libs/ntl/ntl_GF2X_linkage.pxi" 9 10 include "polynomial_template.pxi" 11 12 from sage.libs.all import pari 13 14 #ctypedef unsigned long long word "word" 15 16 from sage.matrix.matrix_mod2_dense cimport mzd_write_bit, mzd_read_bit, Matrix_mod2_dense, word 17 18 cdef class Polynomial_GF2X(Polynomial_template): 19 """ 20 Univariate Polynomials over GF(2) via NTL's GF2X. 21 22 EXAMPLE: 23 sage: P.<x> = GF(2)[] 24 sage: x^3 + x^2 + 1 25 x^3 + x^2 + 1 26 """ 27 def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): 28 """ 29 Create a new univariate polynomials over GF(2). 30 31 EXAMPLE: 32 sage: P.<x> = GF(2)[] 33 sage: x^3 + x^2 + 1 34 x^3 + x^2 + 1 35 """ 36 try: 37 if x.parent() is parent.base_ring() or x.parent() == parent.base_ring(): 38 x = int(x) 39 except AttributeError: 40 pass 41 Polynomial_template.__init__(self, parent, x, check, is_gen, construct) 42 43 def __getitem__(self, int i): 44 """ 45 EXAMPLE: 46 sage: P.<x> = GF(2)[] 47 sage: f = x^3 + x^2 + 1; f 48 x^3 + x^2 + 1 49 sage: f[0] 50 1 51 sage: f[1] 52 0 53 """ 54 cdef long c 55 if 0 <= i < GF2X_NumBits(self.x): 56 c = GF2_conv_to_long(GF2X_coeff(self.x, i)) 57 return self._parent.base_ring()(c) 58 59 def _pari_(self, variable=None): 60 """ 61 EXAMPLE: 62 sage: P.<x> = GF(2)[] 63 sage: f = x^3 + x^2 + 1 64 sage: pari(f) 65 Mod(1, 2)*x^3 + Mod(1, 2)*x^2 + Mod(1, 2) 66 """ 67 #TODO: put this in a superclass 68 parent = self._parent 69 if variable is None: 70 variable = parent.variable_name() 71 return pari(self.list()).Polrev(variable) * pari(1).Mod(2) 72 73 def modular_composition(Polynomial_GF2X self, Polynomial_GF2X g, Polynomial_GF2X h, algorithm=None): 74 """ 75 Compute f(g) % h. 76 77 Both implementations Use Brent-Kung's Algorithm 2.1 (Fast 78 Algorithms for Manipulation Formal Power Series, JACM 1978) 79 80 INPUT: 81 g -- a polynomial 82 h -- a polynomial 83 algorithm -- either 'native' or 'ntl' (default: 'native') 84 85 EXAMPLE: 86 sage: P.<x> = GF(2)[] 87 sage: r = 279 88 sage: f = x^r + x +1 89 sage: g = x^r 90 sage: g.modular_composition(g, f) == g(g) % f 91 True 92 93 AUTHORS: 94 -- Paul Zimmermann (2008-10) initial implementation 95 -- Martin Albrecht (2008-10) performance improvements 96 """ 97 if g.parent() is not self.parent() or h.parent() is not self.parent(): 98 raise TypeError("Parents of the first three parameters must match.") 99 100 from sage.misc.misc import verbose, cputime 101 from sage.calculus.calculus import ceil 102 from sage.matrix.constructor import Matrix 103 from sage.rings.all import FiniteField as GF 104 105 cdef Polynomial_GF2X res 106 cdef GF2XModulus_c modulus 107 GF2XModulus_build(modulus, (<Polynomial_GF2X>h).x) 108 109 res = <Polynomial_GF2X>PY_NEW(Polynomial_GF2X) 110 res._parent = self._parent 111 112 if algorithm == "ntl": 113 t = cputime() 114 _sig_on 115 GF2X_CompMod(res.x, self.x, g.x, modulus) 116 _sig_off 117 verbose("NTL %5.3f s"%cputime(t),level=1) 118 return res 119 120 cdef Py_ssize_t i, j, k, l, n, maxlength 121 cdef Matrix_mod2_dense F, G, H 122 123 cdef GF2X_c _f = (<Polynomial_GF2X>self).x 124 cdef GF2X_c _g = (<Polynomial_GF2X>g).x 125 cdef GF2X_c gpow, tt 126 GF2X_conv_long(gpow, 1) 127 128 maxlength = GF2X_NumBits(_f) 129 130 t = cputime() 131 132 n = h.degree() 133 134 k = ceil(Integer(n+1).sqrt_approx()) 135 l = ceil((self.degree() + 1) / k) 136 137 # we store all matrices transposed for performance reasons 138 G = <Matrix_mod2_dense>Matrix(GF(2), k, n) 139 140 # first compute g^j mod h, 2 <= j < k 141 for j in range(0, k): 142 for i from 0 <= i < GF2X_NumBits(gpow): 143 mzd_write_bit(G._entries, j, i, GF2_conv_to_long(GF2X_coeff(gpow, i))) 144 #gpow = (gpow * g) % h # we'll need g^k below 145 GF2X_MulMod_pre(gpow, gpow, _g, modulus) 146 verbose("G %d x %d %5.3f s"%(G.nrows(), G.ncols(),cputime(t)),level=1) 147 148 # split f in chunks of degree < k 149 t = cputime() 150 F = <Matrix_mod2_dense>Matrix(GF(2), l, k) 151 for j in range(0, l): 152 if j*k+k <= maxlength: 153 for i from j*k <= i < j*k+k: 154 mzd_write_bit(F._entries, j, i-j*k, GF2_conv_to_long(GF2X_coeff(_f, i))) 155 else: 156 for i from j*k <= i < maxlength: 157 mzd_write_bit(F._entries, j, i-j*k, GF2_conv_to_long(GF2X_coeff(_f, i))) 158 159 verbose("F %d x %d %5.3f s"%(F.nrows(), F.ncols(), cputime(t)),level=1) 160 161 t = cputime() 162 H = <Matrix_mod2_dense>(F * G) 163 verbose("H %d x %d %5.3f s"%(H.nrows(), H.ncols(), cputime(t)),level=1) 164 165 t = cputime() 166 # H is a n x l matrix now H[i,j] = sum(G[i,m]*F[m,j], 167 # m=0..k-1) = sum(g^m[i] * f[j*k+m], m=0..k-1) where g^m[i] is 168 # the coefficient of degree i in g^m and f[j*k+m] is the 169 # coefficient of degree j*k+m in f thus f[j*k+m]*g^m[i] should 170 # be multiplied by g^(j*k) gpow = (g^k) % h 171 172 GF2X_conv_long(res.x, 0) 173 j = l - 1 174 while j >= 0: 175 #res = (res * gpow) % h 176 GF2X_MulMod_pre(res.x, res.x, gpow, modulus) 177 178 # res = res + parent([H[j,i] for i in range(0,n)]) 179 GF2X_conv_long(tt, 0) 180 for i from 0<= i < n: 181 GF2X_SetCoeff_long(tt, i, mzd_read_bit(H._entries, j, i)) 182 GF2X_add(res.x, res.x, tt) 183 j = j - 1 184 185 verbose("Res %5.3f s"%cputime(t),level=1) 186 return res -
sage/rings/polynomial/polynomial_modn_dense_ntl.pyx
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/rings/polynomial/polynomial_modn_dense_ntl.pyx
a b 1684 1684 # self.parent()._ntl_set_modulus() 1685 1685 # F = [(self.parent()(f, construct=True), n) for f, n in M.ntl_ZZ_pX().factor(verbose)] 1686 1686 # return factorization.Factorization(F) 1687 1688 def is_primitive(self):1689 """1690 Identifies whether a polynomial is primitive.1691 A polynomial can only be primitive if it is irreducible.1692 1693 EXAMPLES:1694 sage: R.<x> = GF(2)['x']1695 sage: f = x^4+x^3+x^2+x+11696 sage: f.is_irreducible(), f.is_primitive()1697 (True, False)1698 sage: f = x^3+x+11699 sage: f.is_irreducible(), f.is_primitive()1700 (True, True)1701 sage: R.<x> = GF(3)[]1702 sage: f = x^3-x+11703 sage: f.is_irreducible(), f.is_primitive()1704 (True, True)1705 sage: f = x^2+11706 sage: f.is_irreducible(), f.is_primitive()1707 (True, False)1708 sage: R.<x> = GF(5)[]1709 sage: f = x^2+x+11710 sage: f.is_primitive()1711 False1712 sage: f = x^2-x+21713 sage: f.is_primitive()1714 True1715 """1716 if not self.is_irreducible():1717 return False1718 p = self.parent().characteristic()1719 n = p ** self.degree() - 11720 y = self.parent().quo(self).gen()1721 for d in n.prime_divisors():1722 if ( y ** (n//d) ) == 1:1723 return False1724 return True1725 -
sage/rings/polynomial/polynomial_ring.py
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/rings/polynomial/polynomial_ring.py
a b 1135 1135 raise TypeError,"Unable to coerce string" 1136 1136 elif hasattr(x, '_polynomial_'): 1137 1137 return x._polynomial_(self) 1138 return polynomial_modn_dense_ntl.Polynomial_dense_mod_p(self, x, check, is_gen,construct=construct) 1138 if self.modulus() == 2: 1139 import sage.rings.polynomial.polynomial_gf2x as polynomial_gf2x 1140 return polynomial_gf2x.Polynomial_GF2X(self, x, check, is_gen,construct=construct) 1141 else: 1142 return polynomial_modn_dense_ntl.Polynomial_dense_mod_p(self, x, check, is_gen,construct=construct) 1139 1143 1140 1144 1141 1145 def polygen(ring_or_element, name="x"): -
new file sage/rings/polynomial/polynomial_template.pxi
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/rings/polynomial/polynomial_template.pxi
- + 1 """ 2 Polynomial Template for C/C++ Library Interfaces 3 4 AUTHOR: 5 -- Robert Bradshaw (2008-10) original idea for templating 6 -- Martin Albrecht (2008-10) initial implementation 7 8 This file implements a simple templating engine for linking univariate 9 polynomials to their C/C++ library implementations. It requires a 10 'linkage' file which implements the \code{celement_} functions (see 11 \code{sage.libs.ntl.ntl_GF2X_linkage} for an example). Both parts are 12 then pluygged together by inclusion of the linkage file when 13 inheriting from this class. See 14 \code{sage.rings.polynomial.polynomial_gf2x} for an example. 15 16 We illustrate the generic glueing using univariate polynomials over 17 GF(2). 18 19 NOTE: 20 Implementations using this template MUST implement coercion from base 21 ring elements and \code{__getitem__}. See \code{Polynomial_GF2X} for an example. 22 """ 23 #***************************************************************************** 24 # Copyright (C) 2008 Martin Albrecht <M.R.Albrecht@rhul.ac.uk> 25 # Copyright (C) 2008 Robert Bradshaw 26 # 27 # Distributed under the terms of the GNU General Public License (GPL) 28 # http://www.gnu.org/licenses/ 29 #***************************************************************************** 30 31 include "../../ext/interrupt.pxi" 32 include "../../ext/stdsage.pxi" 33 34 from sage.rings.polynomial.polynomial_element cimport Polynomial 35 from sage.structure.element cimport ModuleElement, Element, RingElement 36 from sage.rings.integer cimport Integer 37 from sage.libs.all import pari_gen 38 39 def make_element(parent, args): 40 return parent(*args) 41 42 cdef class Polynomial_template(Polynomial): 43 def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): 44 """ 45 EXAMPLE: 46 sage: P.<x> = GF(2)[] 47 sage: P(0) 48 0 49 sage: P(GF(2)(1)) 50 1 51 sage: P(3) 52 1 53 sage: P([1,0,1]) 54 x^2 + 1 55 sage: P(map(GF(2),[1,0,1])) 56 x^2 + 1 57 """ 58 cdef celement gen, monomial, coeff 59 cdef Py_ssize_t deg 60 61 Polynomial.__init__(self, parent, is_gen=is_gen) 62 63 if is_gen: 64 celement_gen(&self.x, 0, parent) 65 66 elif PY_TYPE_CHECK(x, Polynomial_template): 67 try: 68 celement_set(&self.x, &(<Polynomial_template>x).x, parent) 69 except NotImplementedError: 70 raise TypeError("%s not understood."%x) 71 72 elif PY_TYPE_CHECK(x, int) or PY_TYPE_CHECK(x, Integer): 73 try: 74 celement_set_si(&self.x, int(x), parent) 75 except NotImplementedError: 76 raise TypeError("%s not understood."%x) 77 78 elif PY_TYPE_CHECK(x, list) or PY_TYPE_CHECK(x, tuple): 79 parent = (<Polynomial_template>self)._parent 80 81 celement_set_si(&self.x, 0, parent) 82 celement_gen(&gen, 0, parent) 83 84 deg = 0 85 for e in x: 86 # r += parent(e)*power 87 celement_pow(&monomial, &gen, deg, NULL, parent) 88 coeff = (<Polynomial_template>parent(e)).x 89 celement_mul(&monomial, &coeff, &monomial, parent) 90 celement_add(&self.x, &self.x, &monomial, parent) 91 deg += 1 92 93 elif PY_TYPE_CHECK(x, pari_gen): 94 k = (<Polynomial_template>self)._parent.base_ring() 95 x = [k(w) for w in x.Vecrev()] 96 Polynomial_template.__init__(self, parent, x, check=True, is_gen=False, construct=construct) 97 elif PY_TYPE_CHECK(x, Polynomial): 98 k = (<Polynomial_template>self)._parent.base_ring() 99 x = [k(w) for w in list(x)] 100 Polynomial_template.__init__(self, parent, x, check=True, is_gen=False, construct=construct) 101 else: 102 raise TypeError("Coercion from parent %s not supported."%x.parent()) 103 104 def __reduce__(self): 105 """ 106 EXAMPLE: 107 sage: P.<x> = GF(2)[] 108 sage: loads(dumps(x)) == x 109 True 110 """ 111 return make_element, ((<Polynomial_template>self)._parent, (self.list(), False, self.is_gen())) 112 113 def list(self): 114 """ 115 EXAMPLE: 116 sage: P.<x> = GF(2)[] 117 sage: x.list() 118 [0, 1] 119 sage: list(x) 120 [0, 1] 121 """ 122 cdef Py_ssize_t i 123 return [self[i] for i in range(celement_len(&self.x,(<Polynomial_template>self)._parent))] 124 125 def __cinit__(self): 126 """ 127 EXAMPLE: 128 sage: P.<x> = GF(2)[] 129 """ 130 celement_construct(&self.x, (<Polynomial_template>self)._parent) 131 132 def __dealloc__(self): 133 """ 134 EXAMPLE: 135 sage: P.<x> = GF(2)[] 136 sage: del x 137 """ 138 celement_destruct(&self.x, (<Polynomial_template>self)._parent) 139 140 cpdef ModuleElement _add_(self, ModuleElement right): 141 """ 142 EXAMPLE: 143 sage: P.<x> = GF(2)[] 144 sage: x + 1 145 x + 1 146 """ 147 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 148 r._parent = (<Polynomial_template>self)._parent 149 celement_add(&r.x, &(<Polynomial_template>self).x, &(<Polynomial_template>right).x, (<Polynomial_template>self)._parent) 150 return r 151 152 cpdef ModuleElement _sub_(self, ModuleElement right): 153 """ 154 EXAMPLE: 155 sage: P.<x> = GF(2)[] 156 sage: x - 1 157 x + 1 158 """ 159 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 160 r._parent = (<Polynomial_template>self)._parent 161 celement_add(&r.x, &(<Polynomial_template>self).x, &(<Polynomial_template>right).x, (<Polynomial_template>self)._parent) 162 return r 163 164 def __neg__(self): 165 """ 166 EXAMPLE: 167 sage: P.<x> = GF(2)[] 168 sage: -x 169 x 170 """ 171 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 172 r._parent = (<Polynomial_template>self)._parent 173 celement_neg(&r.x, &self.x, (<Polynomial_template>self)._parent) 174 return r 175 176 cpdef RingElement _mul_(self, RingElement right): 177 """ 178 EXAMPLE: 179 sage: P.<x> = GF(2)[] 180 sage: x*(x+1) 181 x^2 + x 182 """ 183 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 184 r._parent = (<Polynomial_template>self)._parent 185 celement_mul(&r.x, &(<Polynomial_template>self).x, &(<Polynomial_template>right).x, (<Polynomial_template>self)._parent) 186 return r 187 188 def gcd(self, Polynomial_template other): 189 """ 190 EXAMPLE: 191 sage: P.<x> = GF(2)[] 192 sage: f = x*(x+1) 193 sage: f.gcd(x+1) 194 x + 1 195 sage: f.gcd(x^2) 196 x 197 """ 198 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 199 r._parent = (<Polynomial_template>self)._parent 200 celement_gcd(&r.x, &(<Polynomial_template>self).x, &(<Polynomial_template>other).x, (<Polynomial_template>self)._parent) 201 return r 202 203 def __floordiv__(self, right): 204 """ 205 EXAMPLE: 206 sage: P.<x> = GF(2)[] 207 sage: x//(x + 1) 208 1 209 sage: (x + 1)//x 210 1 211 """ 212 right = (<Polynomial_template>self)._parent._coerce_(right) 213 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 214 r._parent = (<Polynomial_template>self)._parent 215 celement_floordiv(&r.x, &(<Polynomial_template>self).x, &(<Polynomial_template>right).x, (<Polynomial_template>self)._parent) 216 return r 217 218 def __mod__(self, other): 219 """ 220 EXAMPLE: 221 sage: P.<x> = GF(2)[] 222 sage: (x^2 + 1) % x^2 223 1 224 """ 225 other = (<Polynomial_template>self)._parent._coerce_(other) 226 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 227 r._parent = (<Polynomial_template>self)._parent 228 celement_mod(&r.x, &(<Polynomial_template>self).x, &(<Polynomial_template>other).x, (<Polynomial_template>self)._parent) 229 return r 230 231 def quo_rem(self, right): 232 """ 233 EXAMPLE: 234 sage: P.<x> = GF(2)[] 235 sage: f = x^2 + x + 1 236 sage: f.quo_rem(x + 1) 237 (x, 1) 238 """ 239 right = (<Polynomial_template>self)._parent._coerce_(right) 240 cdef Polynomial_template q = <Polynomial_template>PY_NEW(self.__class__) 241 q._parent = (<Polynomial_template>self)._parent 242 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 243 r._parent = (<Polynomial_template>self)._parent 244 celement_quorem(&q.x, &r.x, &(<Polynomial_template>self).x, &(<Polynomial_template>right).x, (<Polynomial_template>self)._parent) 245 return q,r 246 247 def __long__(self): 248 """ 249 EXAMPLE: 250 sage: P.<x> = GF(2)[] 251 sage: int(x) 252 Traceback (most recent call last): 253 ... 254 TypeError: cannot coerce nonconstant polynomial to int 255 256 sage: int(P(1)) 257 1 258 """ 259 if celement_len(&self.x, (<Polynomial_template>self)._parent) > 1: 260 raise ValueError("Cannot coerce polynomial with degree %d to integer."%(self.degree())) 261 return int(self[0]) 262 263 def __nonzero__(self): 264 """ 265 EXAMPLE: 266 sage: P.<x> = GF(2)[] 267 sage: bool(x), x.is_zero() 268 (True, False) 269 sage: bool(P(0)), P(0).is_zero() 270 (False, True) 271 """ 272 return not celement_is_zero(&self.x, (<Polynomial_template>self)._parent) 273 274 def __richcmp__(left, right, int op): 275 """ 276 EXAMPLE: 277 sage: P.<x> = GF(2)[] 278 sage: x != 1 279 True 280 sage: x < 1 281 False 282 sage: x > 1 283 True 284 """ 285 return (<Element>left)._richcmp(right, op) 286 287 cdef int _cmp_c_impl(left, Element right) except -2: 288 """ 289 EXAMPLE: 290 sage: P.<x> = GF(2)[] 291 """ 292 return celement_cmp(&(<Polynomial_template>left).x, &(<Polynomial_template>right).x, (<Polynomial_template>left)._parent) 293 294 def __hash__(self): 295 """ 296 EXAMPLE: 297 sage: P.<x> = GF(2)[] 298 sage: {x:1} 299 {x: 1} 300 """ 301 return celement_hash(&self.x, (<Polynomial_template>self)._parent) 302 303 def __len__(self): 304 """ 305 EXAMPLE: 306 sage: P.<x> = GF(2)[] 307 sage: P.<x> = GF(2)[] 308 sage: len(x) 309 2 310 sage: len(x+1) 311 2 312 """ 313 return celement_len(&self.x, (<Polynomial_template>self)._parent) 314 315 def __pow__(self, ee, modulus): 316 """ 317 EXAMPLE: 318 sage: P.<x> = GF(2)[] 319 sage: P.<x> = GF(2)[] 320 sage: x^1000 321 x^1000 322 sage: (x+1)^2 323 x^2 + 1 324 sage: (x+1)^(-2) 325 1/(x^2 + 1) 326 sage: f = x^9 + x^7 + x^6 + x^5 + x^4 + x^2 + x 327 sage: h = x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + 1 328 sage: (f^2) % h 329 x^9 + x^8 + x^7 + x^5 + x^3 330 sage: pow(f, 2, h) 331 x^9 + x^8 + x^7 + x^5 + x^3 332 """ 333 if not PY_TYPE_CHECK(self, Polynomial_template): 334 raise NotImplementedError("%s^%s not defined."%(ee,self)) 335 cdef bint recip = 0, do_sig 336 cdef long e = ee 337 if e != ee: 338 raise TypeError("Only integral powers defined.") 339 elif e < 0: 340 recip = 1 # delay because powering frac field elements is slow 341 e = -e 342 if not self: 343 if e == 0: 344 raise ArithmeticError, "0^0 is undefined." 345 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 346 r._parent = (<Polynomial_template>self)._parent 347 348 if modulus is None: 349 celement_pow(&r.x, &(<Polynomial_template>self).x, e, NULL, (<Polynomial_template>self)._parent) 350 else: 351 modulus = (<Polynomial_template>self)._parent._coerce_(modulus) 352 celement_pow(&r.x, &(<Polynomial_template>self).x, e, &(<Polynomial_template>modulus).x, (<Polynomial_template>self)._parent) 353 if recip: 354 return ~r 355 else: 356 return r 357 358 def is_gen(self): 359 """ 360 EXAMPLE: 361 sage: P.<x> = GF(2)[] 362 sage: x.is_gen() 363 True 364 sage: (x+1).is_gen() 365 False 366 """ 367 cdef celement gen 368 celement_gen(&gen, 0, (<Polynomial_template>self)._parent) 369 return celement_equal(&self.x, &gen, (<Polynomial_template>self)._parent) 370 371 def shift(self, int n): 372 """ 373 EXAMPLE: 374 sage: P.<x> = GF(2)[] 375 sage: f = x^3 + x^2 + 1 376 sage: f.shift(1) 377 x^4 + x^3 + x 378 sage: f.shift(-1) 379 x^2 + x 380 """ 381 cdef celement gen 382 cdef Polynomial_template r 383 if n == 0: 384 return self 385 386 parent = (<Polynomial_template>self)._parent 387 celement_gen(&gen, 0, parent) 388 celement_pow(&gen, &gen, abs(n), NULL, parent) 389 r = <Polynomial_template>PY_NEW(self.__class__) 390 r._parent = parent 391 392 if n > 0: 393 celement_mul(&r.x, &self.x, &gen, parent) 394 else: 395 celement_floordiv(&r.x, &self.x, &gen, parent) 396 return r 397 398 def __lshift__(self, int n): 399 """ 400 EXAMPLE: 401 sage: P.<x> = GF(2)[] 402 sage: f = x^3 + x^2 + 1 403 sage: f << 1 404 x^4 + x^3 + x 405 """ 406 if not PY_TYPE_CHECK(self, Polynomial_template): 407 raise TypeError("Cannot %s << %n."%(self, n)) 408 cdef celement gen 409 cdef Polynomial_template r 410 if n == 0: 411 return self 412 elif n < 0: 413 return self >> -n 414 415 parent = (<Polynomial_template>self)._parent 416 celement_gen(&gen, 0, parent) 417 celement_pow(&gen, &gen, n, NULL, parent) 418 r = <Polynomial_template>PY_NEW(self.__class__) 419 r._parent = parent 420 celement_mul(&r.x, &(<Polynomial_template>self).x, &gen, parent) 421 return r 422 423 def __rshift__(self, int n): 424 """ 425 EXAMPLE: 426 sage: P.<x> = GF(2)[] 427 """ 428 if not PY_TYPE_CHECK(self, Polynomial_template): 429 raise TypeError("Cannot %s >> %n."%(self, n)) 430 cdef celement gen 431 cdef Polynomial_template r 432 if n == 0: 433 return self 434 elif n < 0: 435 return self >> -n 436 437 parent = (<Polynomial_template>self)._parent 438 celement_gen(&gen, 0, parent) 439 celement_pow(&gen, &gen, n, NULL, parent) 440 r = <Polynomial_template>PY_NEW(self.__class__) 441 r._parent = parent 442 443 celement_floordiv(&r.x, &(<Polynomial_template>self).x, &gen, parent) 444 return r 445 446 def is_zero(self): 447 """ 448 EXAMPLE: 449 sage: P.<x> = GF(2)[] 450 """ 451 return celement_is_zero(&self.x, (<Polynomial_template>self)._parent) 452 453 def is_one(self): 454 """ 455 EXAMPLE: 456 sage: P.<x> = GF(2)[] 457 """ 458 return celement_is_one(&self.x, (<Polynomial_template>self)._parent) 459 460 def degree(self): 461 """ 462 EXAMPLE: 463 sage: P.<x> = GF(2)[] 464 """ 465 return Integer(celement_len(&self.x, (<Polynomial_template>self)._parent)-1) 466 467 def truncate(self, n): 468 """ 469 Returns this polynomial mod $x^n$. 470 471 EXAMPLES: 472 sage: R.<x> =GF(2)[] 473 sage: f = sum(x^n for n in range(10)); f 474 x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 475 sage: f.truncate(6) 476 x^5 + x^4 + x^3 + x^2 + x + 1 477 """ 478 if n < 0: 479 raise ValueError(" n must be >= 0.") 480 parent = (<Polynomial_template>self)._parent 481 cdef celement gen 482 celement_gen(&gen, 0, parent) 483 celement_pow(&gen, &gen, n, NULL, parent) 484 485 cdef Polynomial_template r = <Polynomial_template>PY_NEW(self.__class__) 486 r._parent = parent 487 celement_mod(&r.x, &self.x, &gen, parent) 488 return r -
new file sage/rings/polynomial/polynomial_template_header.pxi
diff -r 85bf25beff4f -r 9203a9b3ec2a sage/rings/polynomial/polynomial_template_header.pxi
- + 1 """ 2 Polynomial Template for C/C++ Library Interfaces 3 """ 4 5 from sage.rings.polynomial.polynomial_element cimport Polynomial 6 7 cdef class Polynomial_template(Polynomial): 8 cdef celement x 9 -
setup.py
diff -r 85bf25beff4f -r 9203a9b3ec2a setup.py
a b 917 917 language = 'c++', 918 918 include_dirs=debian_include_dirs + ['sage/libs/ntl/']), \ 919 919 920 Extension('sage.rings.polynomial.polynomial_gf2x', 921 sources = ['sage/rings/polynomial/polynomial_gf2x.pyx'], 922 libraries = ['ntl', 'stdc++', 'gmp'], 923 language = 'c++', 924 include_dirs=debian_include_dirs + ['sage/libs/ntl/']), \ 925 920 926 Extension('sage.rings.polynomial.polynomial_real_mpfr_dense', 921 927 sources = ['sage/rings/polynomial/polynomial_real_mpfr_dense.pyx'], 922 928 libraries = ['mpfr', 'gmp']), \