def __pow__(self, index): """ self ** index """ # special indices if index < 0: raise ValueError("negative index is not allowed.") elif index == 0: for c in self.itercoefficients(): if c: one = _ring.getRing(c).one break else: one = 1 return self.construct_with_default({0: one}) elif index == 1: return self elif index == 2: return self.square() # special polynomials if not self: return self elif len(self._coefficients) == 1: return self.construct_with_default([(d * index, c**index) for (d, c) in self]) # general power_product = self.construct_with_default({0: 1}) power_of_2 = self while index: if index & 1: power_product *= power_of_2 index //= 2 if index: power_of_2 = power_of_2.square() return power_product
def __contains__(self, element): """ Return True if an element is in the field. """ if ring.getRing(element).issubring(self): return True return False
def __pow__(self, index): """ self ** index """ # special indices if index < 0: raise ValueError("negative index is not allowed.") elif index == 0: for c in self.itercoefficients(): if c: one = _ring.getRing(c).one break else: one = 1 return self.construct_with_default({0: one}) elif index == 1: return self elif index == 2: return self.square() # special polynomials if not self: return self elif len(self._coefficients) == 1: return self.construct_with_default([(d*index, c**index) for (d, c) in self]) # general power_product = self.construct_with_default({0: 1}) power_of_2 = self while index: if index & 1: power_product *= power_of_2 index //= 2 if index: power_of_2 = power_of_2.square() return power_product
def __pow__(self, index): """ self ** index pow with three arguments is not supported by default. """ if index < 0: raise ValueError("negative index is not allowed.") elif index == 0: indices = (0, ) for i, c in self: if c: indices = (0, ) * len(i) one = _ring.getRing(c).one break else: one = 1 return self.construct_with_default({indices: one}) elif index == 1: return self elif index == 2: return self.square() # special polynomials if not self: return self elif len(self) == 1: return self.construct_with_default([(d * index, c**index) for (d, c) in self]) # general for i, c in self: if c: zero = (0, ) * len(i) one = _ring.getRing(c).one break power_product = self.construct_with_default({zero: one}) power_of_2 = self while index: if index & 1: power_product *= power_of_2 index //= 2 if index: power_of_2 = power_of_2.square() return power_product
def getCharPoly(self): """ Return the characteristic polynomial of self by compute products of (x-self^{(i)}). """ if not hasattr(self, "charpoly"): Conj = self.getApprox() P = uniutil.polynomial({0:-Conj[0], 1:1}, ring.getRing(Conj[0])) for i in range(1, self.degree): P *= uniutil.polynomial({0:-Conj[i], 1:1}, ring.getRing(Conj[i])) charcoeff = [] for i in range(self.degree + 1): if hasattr(P[i], "real"): charcoeff.append(int(math.floor(P[i].real + 0.5))) else: charcoeff.append(int(math.floor(P[i] + 0.5))) self.charpoly = charcoeff return self.charpoly
def __pow__(self, index): """ self ** index pow with three arguments is not supported by default. """ if index < 0: raise ValueError("negative index is not allowed.") elif index == 0: indices = (0,) for i, c in self: if c: indices = (0,) * len(i) one = _ring.getRing(c).one break else: one = 1 return self.construct_with_default({indices: one}) elif index == 1: return self elif index == 2: return self.square() # special polynomials if not self: return self elif len(self) == 1: return self.construct_with_default([(d*index, c**index) for (d, c) in self]) # general for i, c in self: if c: zero = (0,) * len(i) one = _ring.getRing(c).one break power_product = self.construct_with_default({zero: one}) power_of_2 = self while index: if index & 1: power_product *= power_of_2 index //= 2 if index: power_of_2 = power_of_2.square() return power_product
def _op(self, other, op): """ Do `self (op) other'. op must be a name of the special method for binary operation. """ if isinstance(other, ExtendedFieldElement): if other.field is self.field: result = self.field.modulus.mod(getattr(self.rep, op)(other.rep)) return self.__class__(result, self.field) else: fq1, fq2 = self.field, other.field emb1, emb2 = double_embeddings(fq1, fq2) return getattr(emb1(self), op)(emb2(other)) if self.field.hasaction(ring.getRing(other)): # cases for action ring elements embedded = self.field.getaction(ring.getRing(other))(other, self.field.one) result = self.field.modulus.mod(getattr(self.rep, op)(embedded.rep)) return self.__class__(result, self.field) else: return NotImplemented
def __contains__(self, element): """ `in' operator is provided for checking the element be in the ring. """ if element in self._coefficient_ring: return True elem_ring = ring.getRing(element) if elem_ring is not None and elem_ring.issubring(self): return True return False
def createElement(self, seed): """ Return an element in the ring made from seed. """ if ring.getRing(seed) == self: return seed elif not seed: return self._zero_polynomial() elif seed in self._coefficient_ring: return self._constant_polynomial(seed) else: return self._prepared_polynomial(seed)
def _op(self, other, op): """ Do `self (op) other'. op must be a name of the special method for binary operation. """ if isinstance(other, FiniteExtendedFieldElement): if other.field is self.field: result = self.field.modulus.mod( getattr(self.rep, op)(other.rep)) return self.__class__(result, self.field) else: fq1, fq2 = self.field, other.field emb1, emb2 = double_embeddings(fq1, fq2) return getattr(emb1(self), op)(emb2(other)) if self.field.hasaction(ring.getRing(other)): # cases for action ring elements embedded = self.field.getaction(ring.getRing(other))( other, self.field.one) result = self.field.modulus.mod( getattr(self.rep, op)(embedded.rep)) return self.__class__(result, self.field) else: return NotImplemented
def getRing(self): """ Return an object of a subclass of Ring, to which the element belongs. """ if self._coefficient_ring is None or self._ring is None: myring = None for c in self.itercoefficients(): cring = ring.getRing(c) if not myring or myring != cring and myring.issubring(cring): myring = cring elif not cring.issubring(myring): myring = myring.getCommonSuperring(cring) if not myring: myring = rational.theIntegerRing self.set_coefficient_ring(myring) return self._ring
def scalar_mul(self, scale): """ Return the result of scalar multiplication. """ keep_ring = True if "coeffring" in self._init_kwds: new_coeff = [] coeffring = self._init_kwds["coeffring"] for d, c in self: if c: scaled = c * scale if keep_ring and scaled not in coeffring: coeffring = coeffring.getCommonSuperring(_ring.getRing(scaled)) new_coeff.append((d, scaled)) self._init_kwds["coeffring"] = coeffring else: new_coeff = [(d, c * scale) for (d, c) in self if c] return self.construct_with_default(new_coeff)
def minpoly(firstterms): """ Return the minimal polynomial having at most degree n of of the linearly recurrent sequence whose first 2n terms are given. """ field = ring.getRing(firstterms[0]) r_0 = uniutil.polynomial({len(firstterms): field.one}, field) r_1 = uniutil.polynomial(enumerate(reversed(firstterms)), field) poly_ring = r_0.getRing() v_0 = poly_ring.zero v_1 = poly_ring.one n = len(firstterms) // 2 while n <= r_1.degree(): q, r = divmod(r_0, r_1) v_0, v_1 = v_1, v_0 - q * v_1 r_0, r_1 = r_1, r return v_1.scalar_mul(v_1.leading_coefficient().inverse())
def scalar_mul(self, scale): """ Return the result of scalar multiplication. """ keep_ring = True if "coeffring" in self._init_kwds: new_coeff = [] coeffring = self._init_kwds["coeffring"] for d, c in self: if c: scaled = c * scale if keep_ring and scaled not in coeffring: coeffring = coeffring.getCommonSuperring( _ring.getRing(scaled)) new_coeff.append((d, scaled)) self._init_kwds["coeffring"] = coeffring else: new_coeff = [(d, c * scale) for (d, c) in self if c] return self.construct_with_default(new_coeff)
def testFactor(self): factored = self.p.factor() self.assertTrue(isinstance(factored, list)) self.assertEqual(3, len(factored), str(factored)) for factor in factored: self.assertTrue(isinstance(factor, tuple)) self.assertEqual(2, len(factor)) self.assertTrue(isinstance(factor[1], (int, long))) product = self.p.__class__( [(0, ring.getRing(self.p.itercoefficients().next()).one)], coeffring=self.p.getCoefficientRing()) for factor, index in factored: product = product * factor**index self.assertEqual(self.p, product) # F2 case g_factor = self.g.factor() self.assertEqual(1, len(g_factor), g_factor) self.assertEqual(2, g_factor[0][1]) h_factor = self.h.factor() self.assertEqual(2, len(h_factor), h_factor)
def _format_term(self, term, varnames): """ Return formatted term string. 'term' is a tuple of indices and coefficient. """ if not term[1]: return "" if term[1] == ring.getRing(term[1]).one: powlist = [] else: powlist = [str(term[1])] for v, d in zip(varnames, term[0]): if d > 1: powlist.append("%s ** %d" % (v, d)) elif d == 1: powlist.append(v) if not powlist: # coefficient is plus/minus one and every variable has degree 0 return str(term[1]) return " * ".join(powlist)
def __pow__(self, index): """ self ** index No ternary powering is defined here, because there is no modulus operator defined. """ # special indices if index < 0: raise ValueError("negative index is not allowed.") elif index == 0: for c in self.itercoefficients(): if c: one = _ring.getRing(c).one break else: one = 1 return self.construct_with_default([(0, one)]) elif index == 1: return self elif index == 2: return self.square() # special polynomials if not self: return self elif len(self.sorted) == 1: return self.construct_with_default([(d * index, c**index) for (d, c) in self]) # general power_product = self.construct_with_default([(0, 1)]) power_of_2 = self while index: if index & 1: power_product *= power_of_2 index //= 2 if index: power_of_2 = power_of_2.square() return power_product
def reduce_groebner(gbasis, order): """ Return the reduced Groebner basis constructed from a Groebner basis. 1) lb(f) divides lb(g) => g is not in reduced Groebner basis 2) monic """ reduced_basis = [] lb_rel = dict([(order.leading_term(g)[0], g) for g in gbasis]) lbs = sorted([order.leading_term(g)[0] for g in gbasis])[::-1] for i, lbi in enumerate(lbs): for lbj in lbs[(len(lbs) - 1):i:-1]: if lbi == lbj.lcm(lbi): # divisor found break else: g = lb_rel[lbi] if g[lbi] != ring.getRing(g[lbi]).one: # make it monic g = g.scalar_mul(ring.inverse(g[lbi])) reduced_basis.append(g) return reduced_basis
def reduce_groebner(gbasis, order): """ Return the reduced Groebner basis constructed from a Groebner basis. 1) lb(f) divides lb(g) => g is not in reduced Groebner basis 2) monic """ reduced_basis = [] lb_rel = dict([(order.leading_term(g)[0], g) for g in gbasis]) lbs = sorted([order.leading_term(g)[0] for g in gbasis])[::-1] for i, lbi in enumerate(lbs): for lbj in lbs[(len(lbs) - 1) : i : -1]: if lbi == lbj.lcm(lbi): # divisor found break else: g = lb_rel[lbi] if g[lbi] != ring.getRing(g[lbi]).one: # make it monic g = g.scalar_mul(ring.inverse(g[lbi])) reduced_basis.append(g) return reduced_basis
def __pow__(self, index): """ self ** index No ternary powering is defined here, because there is no modulus operator defined. """ # special indices if index < 0: raise ValueError("negative index is not allowed.") elif index == 0: for c in self.itercoefficients(): if c: one = _ring.getRing(c).one break else: one = 1 return self.construct_with_default([(0, one)]) elif index == 1: return self elif index == 2: return self.square() # special polynomials if not self: return self elif len(self.sorted) == 1: return self.construct_with_default([(d*index, c**index) for (d, c) in self]) # general power_product = self.construct_with_default([(0, 1)]) power_of_2 = self while index: if index & 1: power_product *= power_of_2 index //= 2 if index: power_of_2 = power_of_2.square() return power_product
def __pow__(self, index): """ self ** index """ # special indeces if index < 0: raise ValueError("negative index is not allowed.") elif index == 0: zero, one = self.optype, 1 for d, c in self._data.iterterms(): zero = self.optype.op2(d, 0) if c: one = _ring.getRing(c).one break return self.__class__({zero: one}) elif index == 1: return self elif index == 2: return self.square() # special polynomials if not self: return self elif len(self._data) == 1: d = self.optype.op2(self._data.bases()[0], index) c = self._data.coefficients()[0] ** index return self.__class__([(d, c)]) # general power_product = self.__class__({0: 1}) power_of_2 = self while index: if index & 1: power_product *= power_of_2 index //= 2 if index: power_of_2 = power_of_2.square() return power_product
def testInt(self): Z = rational.theIntegerRing self.assertEqual(Z, ring.getRing(1)) self.assertEqual(Z, ring.getRing(1L)) self.assertEqual( rational.Integer(1).getRing(), ring.getRing(rational.Integer(1)))
def testComplex(self): self.assertEqual(theComplexField, ring.getRing(1 + 1j))
def testFloat(self): self.assertEqual(theRealField, ring.getRing(1.0))