def iterator(n, min_length, max_length, floor, ceiling, min_slope, max_slope): """ .. WARNING:: INTERNAL FUNCTION! DO NOT USE DIRECTLY! EXAMPLES:: sage: from sage.combinat.integer_list_old import iterator sage: IV = sage.combinat.integer_list_old.IntegerListsLex(n=2,length=3,min_slope=0) sage: list(iterator(2, 3, 3, lambda i: 0, lambda i: 5, 0, 10)) [[0, 1, 1], [0, 0, 2]] """ #from sage.misc.superseded import deprecation #deprecation(13605, 'iterator(...) is deprecated. Use IntegerListLex(...) instead.') stopgap("Iterator uses the old implementation of IntegerListsLex, which does not allow for arbitrary input;" " non-allowed input can return wrong results," " please see the documentation for IntegerListsLex for details.", 17548) succ = lambda x: next(x, min_length, max_length, floor, ceiling, min_slope, max_slope) #Handle the case where n is a list of integers if isinstance(n, __builtin__.list): for i in range(n[0], min(n[1]+1,upper_bound(min_length, max_length, floor, ceiling, min_slope, max_slope))): for el in iterator(i, min_length, max_length, floor, ceiling, min_slope, max_slope): yield el else: f = first(n, min_length, max_length, floor, ceiling, min_slope, max_slope) while not f is None: yield f f = succ(f)
def DuadicCodeOddPair(F, S1, S2): """ Constructs the "odd pair" of duadic codes associated to the "splitting" S1, S2 of n. .. warning:: Maybe the splitting should be associated to a sum of q-cyclotomic cosets mod n, where q is a *prime*. EXAMPLES:: sage: from sage.coding.code_constructions import _is_a_splitting sage: n = 11; q = 3 sage: C = Zmod(n).cyclotomic_cosets(q); C [[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]] sage: S1 = C[1] sage: S2 = C[2] sage: _is_a_splitting(S1,S2,11) True sage: codes.DuadicCodeOddPair(GF(q),S1,S2) ([11, 6] Cyclic Code over GF(3), [11, 6] Cyclic Code over GF(3)) This is consistent with Theorem 6.1.3 in [HP2003]_. """ from sage.misc.stopgap import stopgap stopgap( "The function DuadicCodeOddPair has several issues which may cause wrong results", 25896) from .cyclic_code import CyclicCode n = len(S1) + len(S2) + 1 if not _is_a_splitting(S1, S2, n): raise TypeError("%s, %s must be a splitting of %s." % (S1, S2, n)) q = F.order() k = Mod(q, n).multiplicative_order() FF = GF(q**k, "z") z = FF.gen() zeta = z**((q**k - 1) / n) P1 = PolynomialRing(FF, "x") x = P1.gen() g1 = prod([x - zeta**i for i in S1 + [0]]) g2 = prod([x - zeta**i for i in S2 + [0]]) j = sum([x**i / n for i in range(n)]) P2 = PolynomialRing(F, "x") x = P2.gen() coeffs1 = [ _lift2smallest_field(c)[0] for c in (g1 + j).coefficients(sparse=False) ] coeffs2 = [ _lift2smallest_field(c)[0] for c in (g2 + j).coefficients(sparse=False) ] gg1 = P2(coeffs1) gg2 = P2(coeffs2) gg1 = gcd(gg1, x**n - 1) gg2 = gcd(gg2, x**n - 1) C1 = CyclicCode(length=n, generator_pol=gg1) C2 = CyclicCode(length=n, generator_pol=gg2) return C1, C2
def iterator(n, min_length, max_length, floor, ceiling, min_slope, max_slope): """ .. WARNING:: INTERNAL FUNCTION! DO NOT USE DIRECTLY! EXAMPLES:: sage: from sage.combinat.integer_list_old import iterator sage: IV = sage.combinat.integer_list_old.IntegerListsLex(n=2,length=3,min_slope=0) sage: list(iterator(2, 3, 3, lambda i: 0, lambda i: 5, 0, 10)) [[0, 1, 1], [0, 0, 2]] """ #from sage.misc.superseded import deprecation #deprecation(13605, 'iterator(...) is deprecated. Use IntegerListLex(...) instead.') stopgap("Iterator uses the old implementation of IntegerListsLex, which does not allow for arbitrary input;" " non-allowed input can return wrong results," " please see the documentation for IntegerListsLex for details.", 17548) succ = lambda x: next(x, min_length, max_length, floor, ceiling, min_slope, max_slope) #Handle the case where n is a list of integers if isinstance(n, builtins.list): for i in range(n[0], min(n[1]+1,upper_bound(min_length, max_length, floor, ceiling, min_slope, max_slope))): for el in iterator(i, min_length, max_length, floor, ceiling, min_slope, max_slope): yield el else: f = first(n, min_length, max_length, floor, ceiling, min_slope, max_slope) while not f is None: yield f f = succ(f)
def xgcd(self, right): from sage.misc.stopgap import stopgap stopgap( "Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439) return self._xgcd(right)
def xgcd(self, right): from sage.misc.stopgap import stopgap stopgap( "Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439) from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_field return Polynomial_generic_field._xgcd.im_func(self, right)
def next(comp, min_length, max_length, floor, ceiling, min_slope, max_slope): """ Returns the next integer list after ``comp`` that satisfies the constraints. .. WARNING:: INTERNAL FUNCTION! DO NOT USE DIRECTLY! EXAMPLES:: sage: from sage.combinat.integer_list_old import next sage: IV = sage.combinat.integer_list_old.IntegerListsLex(n=2,length=3,min_slope=0) sage: next([0,1,1], 3, 3, lambda i: 0, lambda i: 5, 0, 10) [0, 0, 2] """ stopgap( "Next uses the old implementation of IntegerListsLex, which does not allow for arbitrary input;" " non-allowed input can return wrong results," " please see the documentation for IntegerListsLex for details.", 17548) x = rightmost_pivot(comp, min_length, max_length, floor, ceiling, min_slope, max_slope) if x is None: return None [x, low] = x high = comp[x - 1] - 1 ## // Build wrappers around floor and ceiling to take into ## // account the new constraints on the value of compo[x]. ## // ## // Efficiency note: they are not wrapped more than once, since ## // the method Next calls first, but not the converse. if min_slope == float('-inf'): new_floor = lambda i: floor(x + (i - 1)) else: new_floor = lambda i: max(floor(x + (i - 1)), low + (i - 1) * min_slope) if max_slope == float('+inf'): new_ceiling = lambda i: comp[x - 1] - 1 if i == 1 else ceiling(x + (i - 1)) else: new_ceiling = lambda i: min(ceiling(x + (i - 1)), high + (i - 1) * max_slope) res = [] res += comp[:x - 1] f = first(sum(comp[x - 1:]), max(min_length - x + 1, 0), max_length - x + 1, new_floor, new_ceiling, min_slope, max_slope) if f is None: # Check to make sure it is valid return None res += f return res
def next(comp, min_length, max_length, floor, ceiling, min_slope, max_slope): """ Returns the next integer list after ``comp`` that satisfies the constraints. .. WARNING:: INTERNAL FUNCTION! DO NOT USE DIRECTLY! EXAMPLES:: sage: from sage.combinat.integer_list_old import next sage: IV = sage.combinat.integer_list_old.IntegerListsLex(n=2,length=3,min_slope=0) sage: next([0,1,1], 3, 3, lambda i: 0, lambda i: 5, 0, 10) [0, 0, 2] """ stopgap( "Next uses the old implementation of IntegerListsLex, which does not allow for arbitrary input;" " non-allowed input can return wrong results," " please see the documentation for IntegerListsLex for details.", 17548, ) x = rightmost_pivot(comp, min_length, max_length, floor, ceiling, min_slope, max_slope) if x is None: return None [x, low] = x high = comp[x - 1] - 1 ## // Build wrappers around floor and ceiling to take into ## // account the new constraints on the value of compo[x]. ## // ## // Efficiency note: they are not wrapped more than once, since ## // the method Next calls first, but not the converse. if min_slope == float("-inf"): new_floor = lambda i: floor(x + (i - 1)) else: new_floor = lambda i: max(floor(x + (i - 1)), low + (i - 1) * min_slope) if max_slope == float("+inf"): new_ceiling = lambda i: comp[x - 1] - 1 if i == 1 else ceiling(x + (i - 1)) else: new_ceiling = lambda i: min(ceiling(x + (i - 1)), high + (i - 1) * max_slope) res = [] res += comp[: x - 1] f = first( sum(comp[x - 1 :]), max(min_length - x + 1, 0), max_length - x + 1, new_floor, new_ceiling, min_slope, max_slope ) if f is None: # Check to make sure it is valid return None res += f return res
def DuadicCodeEvenPair(F, S1, S2): r""" Constructs the "even pair" of duadic codes associated to the "splitting" (see the docstring for ``_is_a_splitting`` for the definition) S1, S2 of n. .. warning:: Maybe the splitting should be associated to a sum of q-cyclotomic cosets mod n, where q is a *prime*. EXAMPLES:: sage: from sage.coding.code_constructions import _is_a_splitting sage: n = 11; q = 3 sage: C = Zmod(n).cyclotomic_cosets(q); C [[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]] sage: S1 = C[1] sage: S2 = C[2] sage: _is_a_splitting(S1,S2,11) True sage: codes.DuadicCodeEvenPair(GF(q),S1,S2) ([11, 5] Cyclic Code over GF(3), [11, 5] Cyclic Code over GF(3)) """ from sage.misc.stopgap import stopgap stopgap( "The function DuadicCodeEvenPair has several issues which may cause wrong results", 25896) from .cyclic_code import CyclicCode n = len(S1) + len(S2) + 1 if not _is_a_splitting(S1, S2, n): raise TypeError("%s, %s must be a splitting of %s." % (S1, S2, n)) q = F.order() k = Mod(q, n).multiplicative_order() FF = GF(q**k, "z") z = FF.gen() zeta = z**((q**k - 1) / n) P1 = PolynomialRing(FF, "x") x = P1.gen() g1 = prod([x - zeta**i for i in S1 + [0]]) g2 = prod([x - zeta**i for i in S2 + [0]]) P2 = PolynomialRing(F, "x") x = P2.gen() gg1 = P2( [_lift2smallest_field(c)[0] for c in g1.coefficients(sparse=False)]) gg2 = P2( [_lift2smallest_field(c)[0] for c in g2.coefficients(sparse=False)]) C1 = CyclicCode(length=n, generator_pol=gg1) C2 = CyclicCode(length=n, generator_pol=gg2) return C1, C2
def xgcd(self, right): """ Extended gcd of ``self`` and ``other``. INPUT: - ``other`` -- an element with the same parent as ``self`` OUTPUT: Polynomials ``g``, ``u``, and ``v`` such that ``g = u*self + v*other`` .. WARNING:: The computations are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases. See :trac:`13439`. EXAMPLES:: sage: R.<x> = Qp(3,3)[] sage: f = x + 1 sage: f.xgcd(f^2) ((1 + O(3^3))*x + (1 + O(3^3)), (1 + O(3^3)), 0) In these examples the results are incorrect, see :trac:`13439`:: sage: R.<x> = Qp(3,3)[] sage: f = 3*x + 7 sage: g = 5*x + 9 sage: f.xgcd(f*g) # not tested - currently we get the incorrect result ((O(3^2))*x^2 + (O(3))*x + (1 + O(3^3)), (3^-2 + 2*3^-1 + O(3))*x, (3^-2 + 3^-1 + O(3))) ((3 + O(3^4))*x + (1 + 2*3 + O(3^3)), (1 + O(3^3)), 0) sage: R.<x> = Qp(3)[] sage: f = 490473657*x + 257392844/729 sage: g = 225227399/59049*x - 8669753175 sage: f.xgcd(f*g) # not tested - currently we get the incorrect result ((O(3^18))*x^2 + (O(3^9))*x + (1 + O(3^20)), (3^-5 + 2*3^-1 + 3 + 2*3^2 + 3^4 + 2*3^6 + 3^7 + 3^8 + 2*3^9 + 2*3^11 + 3^13 + O(3^15))*x, (3^5 + 2*3^6 + 2*3^7 + 3^8 + 3^9 + 3^13 + 2*3^14 + 3^17 + 3^18 + 3^20 + 3^21 + 3^23 + 2*3^24 + O(3^25))) ((3^3 + 3^5 + 2*3^6 + 2*3^7 + 3^8 + 2*3^10 + 2*3^11 + 3^12 + 3^13 + 3^15 + 2*3^16 + 3^18 + O(3^23))*x + (2*3^-6 + 2*3^-5 + 3^-3 + 2*3^-2 + 3^-1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 3^11 + O(3^14)), (1 + O(3^20)), 0) """ from sage.misc.stopgap import stopgap stopgap( "Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439) from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_field return Polynomial_generic_field.xgcd(self, right)
def xgcd(self, right): """ Extended gcd of ``self`` and ``other``. INPUT: - ``other`` -- an element with the same parent as ``self`` OUTPUT: Polynomials ``g``, ``u``, and ``v`` such that ``g = u*self + v*other`` .. WARNING:: The computations are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases. See :trac:`13439`. EXAMPLES:: sage: R.<x> = Qp(3,3)[] sage: f = x + 1 sage: f.xgcd(f^2) ((1 + O(3^3))*x + (1 + O(3^3)), (1 + O(3^3)), 0) In these examples the results are incorrect, see :trac:`13439`:: sage: R.<x> = Qp(3,3)[] sage: f = 3*x + 7 sage: g = 5*x + 9 sage: f.xgcd(f*g) # known bug ((3 + O(3^4))*x + (1 + 2*3 + O(3^3)), (1 + O(3^3)), 0) sage: R.<x> = Qp(3)[] sage: f = 490473657*x + 257392844/729 sage: g = 225227399/59049*x - 8669753175 sage: f.xgcd(f*g) # known bug ((3^3 + 3^5 + 2*3^6 + 2*3^7 + 3^8 + 2*3^10 + 2*3^11 + 3^12 + 3^13 + 3^15 + 2*3^16 + 3^18 + O(3^23))*x + (2*3^-6 + 2*3^-5 + 3^-3 + 2*3^-2 + 3^-1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 3^11 + O(3^14)), (1 + O(3^20)), 0) """ from sage.misc.stopgap import stopgap stopgap("Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439) from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_field return Polynomial_generic_field.xgcd(self,right)
def newton_polygon(self): r""" Returns a list of vertices of the Newton polygon of this polynomial. NOTES: The vertices are listed so that the first coordinates are strictly increasing, up to the polynomial's degree (not the limit of available precision information). Also note that if some coefficients have very low precision an error is raised. EXAMPLES:: sage: K = Qp(13) sage: R.<t> = K[] sage: f = t^4 + 13^5*t^2 + 4*13^2*t - 13^7 sage: f.newton_polygon() [(0, 7), (1, 2), (4, 0)] """ if self._poly == 0: return [] for x in range(len(self._relprecs)): if not self._relprecs[x] is infinity: break if self._valaddeds is None: self._comp_valaddeds() if self._poly[x] == 0: raise PrecisionError, "first term with non-infinite valuation must have determined valuation" yrel = self._valaddeds[x] answer = [(x, self._valbase + yrel)] xf = self._poly.degree() if xf == x: return answer yfrel = self._valaddeds[xf] curslope = (yfrel - yrel) / (xf - x) for i in range(x + 1, xf): yrel += curslope if self._valaddeds[i] < yrel: if self._relprecs[i] == self._valaddeds[i]: raise PrecisionError, "not enough precision known in coefficient %s to compute newton polygon" % i yrel = self._valaddeds[i] answer.append((i, self._valbase + yrel)) curslope = (yfrel - yrel) / (xf - i) from sage.misc.stopgap import stopgap stopgap("Check that the Newton polygon below is actually convex.", 6667) answer.append((xf, self._valbase + self._valaddeds[xf])) return answer
def newton_polygon(self): r""" Returns a list of vertices of the Newton polygon of this polynomial. NOTES: The vertices are listed so that the first coordinates are strictly increasing, up to the polynomial's degree (not the limit of available precision information). Also note that if some coefficients have very low precision an error is raised. EXAMPLES:: sage: K = Qp(13) sage: R.<t> = K[] sage: f = t^4 + 13^5*t^2 + 4*13^2*t - 13^7 sage: f.newton_polygon() [(0, 7), (1, 2), (4, 0)] """ if self._poly == 0: return [] for x in range(len(self._relprecs)): if not self._relprecs[x] is infinity: break if self._valaddeds is None: self._comp_valaddeds() if self._poly[x] == 0: raise PrecisionError, "first term with non-infinite valuation must have determined valuation" yrel = self._valaddeds[x] answer = [(x, self._valbase + yrel)] xf = self._poly.degree() if xf == x: return answer yfrel = self._valaddeds[xf] curslope = (yfrel - yrel) / (xf - x) for i in range(x + 1, xf): yrel += curslope if self._valaddeds[i] < yrel: if self._relprecs[i] == self._valaddeds[i]: raise PrecisionError, "not enough precision known in coefficient %s to compute newton polygon"%i yrel = self._valaddeds[i] answer.append((i, self._valbase + yrel)) curslope = (yfrel - yrel) / (xf - i) from sage.misc.stopgap import stopgap stopgap("Check that the Newton polygon below is actually convex.", 6667) answer.append((xf, self._valbase + self._valaddeds[xf])) return answer
def reduced_form(self): r""" Return the reduced form of ``self``. The reduced form of a tableaux `T \in \mathcal{T}(\infty)` is the (not necessarily semistandard) tableaux obtained from `T` by removing all `i`-boxes in the `i`-th row, subject to the condition that if the row is empty, a `\ast` is put as a placeholder. This is described in [BN10]_ and [LS12]_. EXAMPLES:: sage: B = crystals.infinity.Tableaux(['A',3]) sage: b = B.highest_weight_vector().f_string([2,2,2,3,3,3,3,3]) sage: b.pp() 1 1 1 1 1 1 1 1 2 2 2 2 4 4 4 3 4 4 sage: b.reduced_form() [['*'], [4, 4, 4], [4, 4]] """ oldtab = self.to_tableau() newtab = [] for i, row in enumerate(oldtab): j = 0 row = list(row) while j < len(row): if row[j] == i + 1: row.pop(j) if not row: row.append('*') else: j += 1 newtab.append(row) from sage.misc.stopgap import stopgap stopgap("Return value is no longer a Tableau.", 17997) return newtab
def reduced_form(self): r""" Return the reduced form of ``self``. The reduced form of a tableaux `T \in \mathcal{T}(\infty)` is the (not necessarily semistandard) tableaux obtained from `T` by removing all `i`-boxes in the `i`-th row, subject to the condition that if the row is empty, a `\ast` is put as a placeholder. This is described in [BN10]_ and [LS12]_. EXAMPLES:: sage: B = crystals.infinity.Tableaux(['A',3]) sage: b = B.highest_weight_vector().f_string([2,2,2,3,3,3,3,3]) sage: b.pp() 1 1 1 1 1 1 1 1 2 2 2 2 4 4 4 3 4 4 sage: b.reduced_form() [['*'], [4, 4, 4], [4, 4]] """ oldtab = self.to_tableau() newtab = [] for i, row in enumerate(oldtab): j = 0 row = list(row) while j < len(row): if row[j] == i+1: row.pop(j) if not row: row.append('*') else: j += 1 newtab.append(row) from sage.misc.stopgap import stopgap stopgap("Return value is no longer a Tableau.", 17997) return newtab
def xgcd(self, right): from sage.misc.stopgap import stopgap stopgap("Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439) return self._xgcd(right)
def __init__(self, n, length = None, min_length=0, max_length=float('+inf'), floor=None, ceiling = None, min_part = 0, max_part = float('+inf'), min_slope=float('-inf'), max_slope=float('+inf'), name = None, element_constructor = None, element_class = None, global_options = None): """ Initialize ``self``. TESTS:: sage: C = IntegerListsLex(2, length=3) sage: C == loads(dumps(C)) True sage: C == loads(dumps(C)) # this did fail at some point, really! True sage: C is loads(dumps(C)) # todo: not implemented True sage: C.cardinality().parent() is ZZ True sage: TestSuite(C).run() """ from sage.misc.stopgap import stopgap stopgap("This code contains bugs and may be mathematically unreliable.", 17548) # Convert to float infinity from sage.rings.infinity import infinity if max_slope == infinity: max_slope = float('+inf') if min_slope == -infinity: min_slope = float('-inf') if max_length == infinity: max_length = float('inf') if max_part == infinity: max_part = float('+inf') if floor is None: self.floor_list = [] else: try: # Is ``floor`` an iterable? self.floor_list = __builtin__.list(floor) # not ``floor[:]`` because we want # ``self.floor_list`` mutable, and # applying [:] to a tuple gives a # tuple. # Make sure the floor list will make the list satisfy the constraints if max_slope != float('+inf'): for i in reversed(range(len(self.floor_list)-1)): self.floor_list[i] = max(self.floor_list[i], self.floor_list[i+1] - max_slope) if min_slope != float('-inf'): for i in range(1, len(self.floor_list)): self.floor_list[i] = max(self.floor_list[i], self.floor_list[i-1] + min_slope) except TypeError: self.floor = floor if ceiling is None: self.ceiling_list = [] else: try: # Is ``ceiling`` an iterable? self.ceiling_list = __builtin__.list(ceiling) # Make sure the ceiling list will make the list satisfy the constraints if max_slope != float('+inf'): for i in range(1, len(self.ceiling_list)): self.ceiling_list[i] = min(self.ceiling_list[i], self.ceiling_list[i-1] + max_slope) if min_slope != float('-inf'): for i in reversed(range(len(self.ceiling_list)-1)): self.ceiling_list[i] = min(self.ceiling_list[i], self.ceiling_list[i+1] - min_slope) except TypeError: # ``ceiling`` is not an iterable. self.ceiling = ceiling if length is not None: min_length = length max_length = length if name is not None: self.rename(name) if n in ZZ: self.n = n self.n_range = [n] else: self.n_range = n self.min_length = min_length self.max_length = max_length self.min_part = min_part self.max_part = max_part # FIXME: the internal functions currently assume that floor and ceiling start at 1 # this is a workaround self.max_slope = max_slope self.min_slope = min_slope if element_constructor is not None: self._element_constructor_ = element_constructor if element_class is not None: self.Element = element_class if global_options is not None: self.global_options = global_options Parent.__init__(self, category=FiniteEnumeratedSets())
def __init__(self, n, length=None, min_length=0, max_length=float('+inf'), floor=None, ceiling=None, min_part=0, max_part=float('+inf'), min_slope=float('-inf'), max_slope=float('+inf'), name=None, element_constructor=None, element_class=None, global_options=None): """ Initialize ``self``. TESTS:: sage: import sage.combinat.integer_list_old as integer_list sage: C = integer_list.IntegerListsLex(2, length=3) sage: C == loads(dumps(C)) True sage: C == loads(dumps(C)) # this did fail at some point, really! True sage: C is loads(dumps(C)) # todo: not implemented True sage: C.cardinality().parent() is ZZ True sage: TestSuite(C).run() """ stopgap( "The old implementation of IntegerListsLex does not allow for arbitrary input;" " non-allowed input can return wrong results," " please see the documentation for IntegerListsLex for details.", 17548) # Convert to float infinity from sage.rings.infinity import infinity if max_slope == infinity: max_slope = float('+inf') if min_slope == -infinity: min_slope = float('-inf') if max_length == infinity: max_length = float('inf') if max_part == infinity: max_part = float('+inf') if floor is None: self.floor_list = [] else: try: # Is ``floor`` an iterable? # Not ``floor[:]`` because we want ``self.floor_list`` # mutable, and applying [:] to a tuple gives a tuple. self.floor_list = builtins.list(floor) # Make sure the floor list will make the list satisfy the constraints if min_slope != float('-inf'): for i in range(1, len(self.floor_list)): self.floor_list[i] = max( self.floor_list[i], self.floor_list[i - 1] + min_slope) # Some input checking for i in range(1, len(self.floor_list)): if self.floor_list[i] - self.floor_list[i - 1] > max_slope: raise ValueError( "floor does not satisfy the max slope condition") if self.floor_list and min_part - self.floor_list[ -1] > max_slope: raise ValueError( "floor does not satisfy the max slope condition") except TypeError: self.floor = floor if ceiling is None: self.ceiling_list = [] else: try: # Is ``ceiling`` an iterable? self.ceiling_list = builtins.list(ceiling) # Make sure the ceiling list will make the list satisfy the constraints if max_slope != float('+inf'): for i in range(1, len(self.ceiling_list)): self.ceiling_list[i] = min( self.ceiling_list[i], self.ceiling_list[i - 1] + max_slope) # Some input checking for i in range(1, len(self.ceiling_list)): if self.ceiling_list[i] - self.ceiling_list[i - 1] < min_slope: raise ValueError( "ceiling does not satisfy the min slope condition") if self.ceiling_list and max_part - self.ceiling_list[ -1] < min_slope: raise ValueError( "ceiling does not satisfy the min slope condition") except TypeError: # ``ceiling`` is not an iterable. self.ceiling = ceiling if name is not None: self.rename(name) if n in ZZ: self.n = n self.n_range = [n] else: self.n_range = n if length is not None: min_length = length max_length = length self.min_length = min_length self.max_length = max_length self.min_part = min_part self.max_part = max_part # FIXME: the internal functions currently assume that floor and ceiling start at 1 # this is a workaround self.max_slope = max_slope self.min_slope = min_slope if element_constructor is not None: self._element_constructor_ = element_constructor if element_class is not None: self.Element = element_class if global_options is not None: self.global_options = global_options Parent.__init__(self, category=FiniteEnumeratedSets())
def first(n, min_length, max_length, floor, ceiling, min_slope, max_slope): """ Returns the lexicographically smallest valid composition of `n` satisfying the conditions. .. warning:: INTERNAL FUNCTION! DO NOT USE DIRECTLY! .. TODO:: Move this into Cython. Preconditions: - ``floor`` and ``ceiling`` need to satisfy the slope constraints, e.g. be obtained ``fromcomp2floor`` or ``comp2ceil`` - ``floor`` must be below ``ceiling`` to ensure the existence a valid composition TESTS:: sage: import sage.combinat.integer_list_old as integer_list sage: f = lambda l: lambda i: l[i-1] sage: f([0,1,2,3,4,5])(1) 0 sage: integer_list.first(12, 4, 4, f([0,0,0,0]), f([4,4,4,4]), -1, 1) [4, 3, 3, 2] sage: integer_list.first(36, 9, 9, f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -1, 1) [7, 6, 5, 5, 4, 3, 3, 2, 1] sage: integer_list.first(25, 9, 9, f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1) [7, 6, 5, 4, 2, 1, 0, 0, 0] sage: integer_list.first(36, 9, 9, f([3,3,3,2,1,4,2,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1) [7, 6, 5, 5, 5, 4, 3, 1, 0] :: sage: I = integer_list.IntegerListsLex(6, max_slope=2, min_slope=2) sage: list(I) [[6], [2, 4], [0, 2, 4]] """ stopgap( "First uses the old implementation of IntegerListsLex, which does not allow for arbitrary input;" " non-allowed input can return wrong results," " please see the documentation for IntegerListsLex for details.", 17548) # Check trivial cases, and standardize min_length to be at least 1 if n < 0: return None if max_length <= 0: if n == 0: return [] return None if min_length <= 0: if n == 0: return [] min_length = 1 #Increase min_length until n <= sum([ceiling(i) for i in range(min_length)]) #This may run forever! # Find the actual length the list needs to be N = 0 for i in range(1, min_length + 1): ceil = ceiling(i) if ceil < floor(i): return None N += ceil while N < n: min_length += 1 if min_length > max_length: return None ceil = ceiling(min_length) if ceil == 0 and max_slope <= 0 or ceil < floor(min_length): return None N += ceil # Trivial case if min_length == 1: if n < floor(1): return None return [n] if max_slope < min_slope: return None # Compute the minimum values # We are constrained below by the max slope result = [floor(min_length)] n -= floor(min_length) for i in reversed(range(1, min_length)): result.insert(0, max(floor(i), result[0] - max_slope)) n -= result[0] if n < 0: return None if n == 0: # There is nothing more to do return result if min_slope == float('-inf'): for i in range(1, min_length + 1): if n <= ceiling(i) - result[i - 1]: #-1 for indexing result[i - 1] += n break else: n -= ceiling(i) - result[i - 1] result[i - 1] = ceiling(i) else: low_x = 1 low_y = result[0] high_x = 1 high_y = result[0] while n > 0: #invariant after each iteration of the loop: #[low_x, low_y] is the coordinate of the rightmost point of the #current diagonal s.t. result[low_x] < low_y low_y += 1 while low_x < min_length and low_y + min_slope > result[low_x]: low_x += 1 low_y += min_slope high_y += 1 while high_y > ceiling(high_x): high_x += 1 high_y += min_slope n -= low_x - high_x + 1 for j in range(1, high_x): result[j - 1] = ceiling(j) for i in range(0, -n): result[high_x + i - 1] = high_y + min_slope * i - 1 for i in range(-n, low_x - high_x + 1): result[high_x + i - 1] = high_y + min_slope * i # Special check for equal slopes if min_slope == max_slope and any(val + min_slope != result[i + 1] for i, val in enumerate(result[:-1])): return None return result
def xgcd(self, right): from sage.misc.stopgap import stopgap stopgap("Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439) from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_field return Polynomial_generic_field._xgcd.im_func(self,right)
def __init__(self, n, length = None, min_length=0, max_length=float('+inf'), floor=None, ceiling = None, min_part = 0, max_part = float('+inf'), min_slope=float('-inf'), max_slope=float('+inf'), name = None, element_constructor = None, element_class = None, global_options = None): """ Initialize ``self``. TESTS:: sage: import sage.combinat.integer_list_old as integer_list sage: C = integer_list.IntegerListsLex(2, length=3) sage: C == loads(dumps(C)) True sage: C == loads(dumps(C)) # this did fail at some point, really! True sage: C is loads(dumps(C)) # todo: not implemented True sage: C.cardinality().parent() is ZZ True sage: TestSuite(C).run() """ stopgap("The old implementation of IntegerListsLex does not allow for arbitrary input;" " non-allowed input can return wrong results," " please see the documentation for IntegerListsLex for details.", 17548) # Convert to float infinity from sage.rings.infinity import infinity if max_slope == infinity: max_slope = float('+inf') if min_slope == -infinity: min_slope = float('-inf') if max_length == infinity: max_length = float('inf') if max_part == infinity: max_part = float('+inf') if floor is None: self.floor_list = [] else: try: # Is ``floor`` an iterable? # Not ``floor[:]`` because we want ``self.floor_list`` # mutable, and applying [:] to a tuple gives a tuple. self.floor_list = __builtin__.list(floor) # Make sure the floor list will make the list satisfy the constraints if min_slope != float('-inf'): for i in range(1, len(self.floor_list)): self.floor_list[i] = max(self.floor_list[i], self.floor_list[i-1] + min_slope) # Some input checking for i in range(1, len(self.floor_list)): if self.floor_list[i] - self.floor_list[i-1] > max_slope: raise ValueError("floor does not satisfy the max slope condition") if self.floor_list and min_part - self.floor_list[-1] > max_slope: raise ValueError("floor does not satisfy the max slope condition") except TypeError: self.floor = floor if ceiling is None: self.ceiling_list = [] else: try: # Is ``ceiling`` an iterable? self.ceiling_list = __builtin__.list(ceiling) # Make sure the ceiling list will make the list satisfy the constraints if max_slope != float('+inf'): for i in range(1, len(self.ceiling_list)): self.ceiling_list[i] = min(self.ceiling_list[i], self.ceiling_list[i-1] + max_slope) # Some input checking for i in range(1, len(self.ceiling_list)): if self.ceiling_list[i] - self.ceiling_list[i-1] < min_slope: raise ValueError("ceiling does not satisfy the min slope condition") if self.ceiling_list and max_part - self.ceiling_list[-1] < min_slope: raise ValueError("ceiling does not satisfy the min slope condition") except TypeError: # ``ceiling`` is not an iterable. self.ceiling = ceiling if name is not None: self.rename(name) if n in ZZ: self.n = n self.n_range = [n] else: self.n_range = n if length is not None: min_length = length max_length = length self.min_length = min_length self.max_length = max_length self.min_part = min_part self.max_part = max_part # FIXME: the internal functions currently assume that floor and ceiling start at 1 # this is a workaround self.max_slope = max_slope self.min_slope = min_slope if element_constructor is not None: self._element_constructor_ = element_constructor if element_class is not None: self.Element = element_class if global_options is not None: self.global_options = global_options Parent.__init__(self, category=FiniteEnumeratedSets())
def _xgcd_univariate_polynomial(self, f, g): """ Extended gcd for univariate polynomial rings over self. Should not be called directly. Use f.xgcd(g) instead. INPUT: - ``f``, ``g`` - the polynomials of which to take the xgcd OUTPUT: - A tuple (a, b, c) which satisfies `a = b*f + c*g`. There is not guarentee that a, b, and c are minimal. .. WARNING:: The computations are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases. See :trac:`13439`. EXAMPLES:: sage: R.<x> = Zp(3,3)[] sage: f = x + 1 sage: f.xgcd(f^2) ((1 + O(3^3))*x + 1 + O(3^3), 1 + O(3^3), 0) We check that :trac:`13439` has been fixed:: sage: R.<x> = Zp(3,3)[] sage: f = 3*x + 7 sage: g = 5*x + 9 sage: f.xgcd(f*g) ((3 + O(3^4))*x + 1 + 2*3 + O(3^3), 1 + O(3^3), 0) sage: R.<x> = Zp(3)[] sage: f = 357555295953*x + 257392844 sage: g = 225227399*x - 511940255230575 sage: f.xgcd(f*g) ((3^9 + O(3^29))*x + 2 + 2*3 + 3^2 + 2*3^5 + 3^6 + 3^7 + 3^8 + 3^10 + 3^11 + 2*3^13 + 3^14 + 3^16 + 2*3^19 + O(3^20), 1 + 2*3^2 + 3^4 + 2*3^5 + 3^6 + 3^7 + 2*3^8 + 2*3^10 + 2*3^12 + 3^13 + 3^14 + 3^15 + 2*3^17 + 3^18 + O(3^20), 0) We check low precision computations:: sage: R.<x> = Zp(3,1)[] sage: h = 3*x + 7 sage: i = 4*x + 9 sage: h.xgcd(h*i) ((3 + O(3^2))*x + 1 + O(3), 1 + O(3), 0) """ from sage.misc.stopgap import stopgap stopgap( "Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439) base_ring = f.base_ring() fracfield = base_ring.fraction_field() f_field = f.change_ring(fracfield) g_field = g.change_ring(fracfield) xgcd = fracfield._xgcd_univariate_polynomial(f_field, g_field) lcm = base_ring(1) for f in xgcd: for i in f: lcm = (i.denominator()).lcm(lcm) returnlst = [] for f in xgcd: f *= lcm returnlst.append(f.change_ring(base_ring)) return tuple(returnlst)
def _singular_init_(self, singular=singular): """ Return a newly created Singular ring matching this ring. EXAMPLES:: sage: PolynomialRing(QQ,'u_ba')._singular_init_() polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names u_ba // block 2 : ordering C """ if not can_convert_to_singular(self): raise TypeError( "no conversion of this ring to a Singular ring defined") if self.ngens() == 1: _vars = '(%s)' % self.gen() if "*" in _vars: # 1.000...000*x _vars = _vars.split("*")[1] order = 'lp' else: _vars = str(self.gens()) order = self.term_order().singular_str() base_ring = self.base_ring() if is_RealField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.arith.all.integer_ceil((2 * precision - 2) / 7.0) self.__singular = singular.ring("(real,%d,0)" % digits, _vars, order=order, check=False) elif is_ComplexField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.arith.all.integer_ceil((2 * precision - 2) / 7.0) self.__singular = singular.ring("(complex,%d,0,I)" % digits, _vars, order=order, check=False) elif is_RealDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(real,15,0)", _vars, order=order, check=False) elif is_ComplexDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(complex,15,0,I)", _vars, order=order, check=False) elif base_ring.is_prime_field(): self.__singular = singular.ring(self.characteristic(), _vars, order=order, check=False) elif sage.rings.finite_rings.finite_field_constructor.is_FiniteField( base_ring): # not the prime field! gen = str(base_ring.gen()) r = singular.ring("(%s,%s)" % (self.characteristic(), gen), _vars, order=order, check=False) self.__minpoly = (str(base_ring.modulus()).replace("x", gen)).replace( " ", "") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s" % (self.__minpoly)) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif number_field.number_field_base.is_NumberField( base_ring) and base_ring.is_absolute(): # not the rationals! gen = str(base_ring.gen()) poly = base_ring.polynomial() poly_gen = str(poly.parent().gen()) poly_str = str(poly).replace(poly_gen, gen) r = singular.ring("(%s,%s)" % (self.characteristic(), gen), _vars, order=order, check=False) self.__minpoly = (poly_str).replace(" ", "") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s" % (self.__minpoly)) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif sage.rings.fraction_field.is_FractionField(base_ring) and ( base_ring.base_ring() is ZZ or base_ring.base_ring().is_prime_field() or is_FiniteField(base_ring.base_ring())): if base_ring.ngens() == 1: gens = str(base_ring.gen()) else: gens = str(base_ring.gens()) if not (not base_ring.base_ring().is_prime_field() and is_FiniteField(base_ring.base_ring())): self.__singular = singular.ring( "(%s,%s)" % (base_ring.characteristic(), gens), _vars, order=order, check=False) else: ext_gen = str(base_ring.base_ring().gen()) _vars = '(' + ext_gen + ', ' + _vars[1:] R = self.__singular = singular.ring( "(%s,%s)" % (base_ring.characteristic(), gens), _vars, order=order, check=False) self.base_ring().__minpoly = (str( base_ring.base_ring().modulus()).replace("x", ext_gen)).replace( " ", "") singular.eval('setring ' + R._name) from sage.misc.stopgap import stopgap stopgap( "Denominators of fraction field elements are sometimes dropped without warning.", 17696) self.__singular = singular("std(ideal(%s))" % (self.base_ring().__minpoly), type='qring') elif sage.rings.function_field.function_field.is_RationalFunctionField( base_ring) and base_ring.constant_field().is_prime_field(): gen = str(base_ring.gen()) self.__singular = singular.ring("(%s,%s)" % (base_ring.characteristic(), gen), _vars, order=order, check=False) elif is_IntegerModRing(base_ring): ch = base_ring.characteristic() if ch.is_power_of(2): exp = ch.nbits() - 1 self.__singular = singular.ring("(integer,2,%d)" % (exp, ), _vars, order=order, check=False) else: self.__singular = singular.ring("(integer,%d)" % (ch, ), _vars, order=order, check=False) elif base_ring is ZZ: self.__singular = singular.ring("(integer)", _vars, order=order, check=False) else: raise TypeError("no conversion to a Singular ring defined") return self.__singular
def first(n, min_length, max_length, floor, ceiling, min_slope, max_slope): """ Returns the lexicographically smallest valid composition of `n` satisfying the conditions. .. warning:: INTERNAL FUNCTION! DO NOT USE DIRECTLY! .. TODO:: Move this into Cython. Preconditions: - ``floor`` and ``ceiling`` need to satisfy the slope constraints, e.g. be obtained ``fromcomp2floor`` or ``comp2ceil`` - ``floor`` must be below ``ceiling`` to ensure the existence a valid composition TESTS:: sage: import sage.combinat.integer_list_old as integer_list sage: f = lambda l: lambda i: l[i-1] sage: f([0,1,2,3,4,5])(1) 0 sage: integer_list.first(12, 4, 4, f([0,0,0,0]), f([4,4,4,4]), -1, 1) [4, 3, 3, 2] sage: integer_list.first(36, 9, 9, f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -1, 1) [7, 6, 5, 5, 4, 3, 3, 2, 1] sage: integer_list.first(25, 9, 9, f([3,3,3,2,1,1,0,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1) [7, 6, 5, 4, 2, 1, 0, 0, 0] sage: integer_list.first(36, 9, 9, f([3,3,3,2,1,4,2,0,0]), f([7,6,5,5,5,5,5,4,4]), -2, 1) [7, 6, 5, 5, 5, 4, 3, 1, 0] :: sage: I = integer_list.IntegerListsLex(6, max_slope=2, min_slope=2) sage: list(I) [[6], [2, 4], [0, 2, 4]] """ stopgap("First uses the old implementation of IntegerListsLex, which does not allow for arbitrary input;" " non-allowed input can return wrong results," " please see the documentation for IntegerListsLex for details.", 17548) # Check trivial cases, and standardize min_length to be at least 1 if n < 0: return None if max_length <= 0: if n == 0: return [] return None if min_length <= 0: if n == 0: return [] min_length = 1 #Increase min_length until n <= sum([ceiling(i) for i in range(min_length)]) #This may run forever! # Find the actual length the list needs to be N = 0 for i in range(1,min_length+1): ceil = ceiling(i) if ceil < floor(i): return None N += ceil while N < n: min_length += 1 if min_length > max_length: return None ceil = ceiling(min_length) if ceil == 0 and max_slope <= 0 or ceil < floor(min_length): return None N += ceil # Trivial case if min_length == 1: if n < floor(1): return None return [n] if max_slope < min_slope: return None # Compute the minimum values # We are constrained below by the max slope result = [floor(min_length)] n -= floor(min_length) for i in reversed(range(1, min_length)): result.insert(0, max(floor(i), result[0] - max_slope)) n -= result[0] if n < 0: return None if n == 0: # There is nothing more to do return result if min_slope == float('-inf'): for i in range(1, min_length+1): if n <= ceiling(i) - result[i-1]: #-1 for indexing result[i-1] += n break else: n -= ceiling(i) - result[i-1] result[i-1] = ceiling(i) else: low_x = 1 low_y = result[0] high_x = 1 high_y = result[0] while n > 0: #invariant after each iteration of the loop: #[low_x, low_y] is the coordinate of the rightmost point of the #current diagonal s.t. result[low_x] < low_y low_y += 1 while low_x < min_length and low_y + min_slope > result[low_x]: low_x += 1 low_y += min_slope high_y += 1 while high_y > ceiling(high_x): high_x += 1 high_y += min_slope n -= low_x - high_x + 1 for j in range(1, high_x): result[j-1] = ceiling(j) for i in range(0, -n): result[high_x+i-1] = high_y + min_slope * i - 1 for i in range(-n, low_x-high_x+1): result[high_x+i-1] = high_y + min_slope * i # Special check for equal slopes if min_slope == max_slope and any(val + min_slope != result[i+1] for i,val in enumerate(result[:-1])): return None return result
def _singular_init_(self, singular=singular): """ Return a newly created Singular ring matching this ring. EXAMPLES:: sage: PolynomialRing(QQ,'u_ba')._singular_init_() polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names u_ba // block 2 : ordering C """ if not can_convert_to_singular(self): raise TypeError("no conversion of this ring to a Singular ring defined") if self.ngens()==1: _vars = '(%s)'%self.gen() if "*" in _vars: # 1.000...000*x _vars = _vars.split("*")[1] order = 'lp' else: _vars = str(self.gens()) order = self.term_order().singular_str() base_ring = self.base_ring() if is_RealField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.arith.all.integer_ceil((2*precision - 2)/7.0) self.__singular = singular.ring("(real,%d,0)"%digits, _vars, order=order, check=False) elif is_ComplexField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); precision = base_ring.precision() digits = sage.arith.all.integer_ceil((2*precision - 2)/7.0) self.__singular = singular.ring("(complex,%d,0,I)"%digits, _vars, order=order, check=False) elif is_RealDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(real,15,0)", _vars, order=order, check=False) elif is_ComplexDoubleField(base_ring): # singular converts to bits from base_10 in mpr_complex.cc by: # size_t bits = 1 + (size_t) ((float)digits * 3.5); self.__singular = singular.ring("(complex,15,0,I)", _vars, order=order, check=False) elif base_ring.is_prime_field(): self.__singular = singular.ring(self.characteristic(), _vars, order=order, check=False) elif sage.rings.finite_rings.finite_field_constructor.is_FiniteField(base_ring): # not the prime field! gen = str(base_ring.gen()) r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False) self.__minpoly = (str(base_ring.modulus()).replace("x",gen)).replace(" ","") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s"%(self.__minpoly) ) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif number_field.number_field_base.is_NumberField(base_ring) and base_ring.is_absolute(): # not the rationals! gen = str(base_ring.gen()) poly=base_ring.polynomial() poly_gen=str(poly.parent().gen()) poly_str=str(poly).replace(poly_gen,gen) r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False) self.__minpoly = (poly_str).replace(" ","") if singular.eval('minpoly') != "(" + self.__minpoly + ")": singular.eval("minpoly=%s"%(self.__minpoly) ) self.__minpoly = singular.eval('minpoly')[1:-1] self.__singular = r elif sage.rings.fraction_field.is_FractionField(base_ring) and (base_ring.base_ring() is ZZ or base_ring.base_ring().is_prime_field() or is_FiniteField(base_ring.base_ring())): if base_ring.ngens()==1: gens = str(base_ring.gen()) else: gens = str(base_ring.gens()) if not (not base_ring.base_ring().is_prime_field() and is_FiniteField(base_ring.base_ring())) : self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gens), _vars, order=order, check=False) else: ext_gen = str(base_ring.base_ring().gen()) _vars = '(' + ext_gen + ', ' + _vars[1:]; R = self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gens), _vars, order=order, check=False) self.base_ring().__minpoly = (str(base_ring.base_ring().modulus()).replace("x",ext_gen)).replace(" ","") singular.eval('setring '+R._name); from sage.misc.stopgap import stopgap stopgap("Denominators of fraction field elements are sometimes dropped without warning.", 17696) self.__singular = singular("std(ideal(%s))"%(self.base_ring().__minpoly),type='qring') elif sage.rings.function_field.function_field.is_RationalFunctionField(base_ring) and base_ring.constant_field().is_prime_field(): gen = str(base_ring.gen()) self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gen), _vars, order=order, check=False) elif is_IntegerModRing(base_ring): ch = base_ring.characteristic() if ch.is_power_of(2): exp = ch.nbits() -1 self.__singular = singular.ring("(integer,2,%d)"%(exp,), _vars, order=order, check=False) else: self.__singular = singular.ring("(integer,%d)"%(ch,), _vars, order=order, check=False) elif base_ring is ZZ: self.__singular = singular.ring("(integer)", _vars, order=order, check=False) else: raise TypeError("no conversion to a Singular ring defined") return self.__singular