From 421e377a68a9160acdc630def97af10e7c24a33f Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Wed, 4 Nov 2015 14:59:06 -0500 Subject: [PATCH 1/4] mutable poset map: remove elements ``None`` --- src/sage/data_structures/mutable_poset.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/sage/data_structures/mutable_poset.py b/src/sage/data_structures/mutable_poset.py index 2f30ccb4535..3848d59ddf7 100644 --- a/src/sage/data_structures/mutable_poset.py +++ b/src/sage/data_structures/mutable_poset.py @@ -3451,6 +3451,11 @@ def map(self, function, topological=False, reverse=False): Since this method works inplace, it is not allowed that ``function`` alters the key of an element. + .. NOTE:: + + If ``function`` returns ``None``, then the element is + removed after the mapping. + EXAMPLES:: sage: from sage.data_structures.mutable_poset import MutablePoset as MP @@ -3464,6 +3469,11 @@ def map(self, function, topological=False, reverse=False): sage: P poset((1, 2, 3), (1, 3, 4), (2, 1, 3), (2, 2, 4), (4, 4, 8)) + TESTS:: + + sage: P.map(lambda e: e if e[2] != 4 else None); P + poset((1, 2, 3), (2, 1, 3), (4, 4, 8)) + .. SEEALSO:: :meth:`copy`, @@ -3471,8 +3481,13 @@ def map(self, function, topological=False, reverse=False): """ shells = self.shells_topological(reverse=reverse) \ if topological else self.shells() + remove = [] for shell in shells: shell._element_ = function(shell._element_) + if shell._element_ is None: + remove.append(shell.key) + for key in remove: + self.remove(key) def mapped(self, function): From 1d28240e9f9368dd113c345350dbe50c2a29c257 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Wed, 4 Nov 2015 14:59:24 -0500 Subject: [PATCH 2/4] term monoid: write change_parameter --- src/sage/rings/asymptotic/term_monoid.py | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/sage/rings/asymptotic/term_monoid.py b/src/sage/rings/asymptotic/term_monoid.py index 0d18e1d900b..71fd66b9070 100644 --- a/src/sage/rings/asymptotic/term_monoid.py +++ b/src/sage/rings/asymptotic/term_monoid.py @@ -1456,6 +1456,52 @@ def coefficient_ring(self): return self._coefficient_ring_ + def change_parameter(self, growth_group=None, coefficient_ring=None): + r""" + Return a term monoid with a change in one or more of the + given parameters. + + INPUT: + + - ``growth_group`` -- (default: ``None``) the new growth group. + + - ``coefficient_ring`` -- (default: ``None``) the new coefficient ring. + + OUTPUT: + + A term monoid. + + EXAMPLES:: + + sage: from sage.rings.asymptotic.growth_group import GrowthGroup + sage: from sage.rings.asymptotic.term_monoid import TermMonoid + sage: E = TermMonoid('exact', GrowthGroup('n^ZZ'), ZZ) + sage: E.change_parameter(coefficient_ring=QQ) + Exact Term Monoid n^ZZ with coefficients in Rational Field + sage: E.change_parameter(growth_group=GrowthGroup('n^QQ')) + Exact Term Monoid n^QQ with coefficients in Integer Ring + + TESTS:: + + sage: E.change_parameter() is E + True + sage: E.change_parameter(growth_group=None) is E + True + sage: E.change_parameter(coefficient_ring=None) is E + True + sage: E.change_parameter(growth_group=None, coefficient_ring=None) is E + True + """ + if growth_group is None: + growth_group = self.growth_group + if coefficient_ring is None: + coefficient_ring = self.coefficient_ring + if self.growth_group is growth_group and \ + self.coefficient_ring is coefficient_ring: + return self + return TermMonoid(self, growth_group, coefficient_ring) + + def _repr_(self): r""" A representation string for this generic term monoid. From 2c37889d1c188d580e467553a8ae6264b7b16aaa Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Wed, 4 Nov 2015 15:04:15 -0500 Subject: [PATCH 3/4] correct a bug in change_parameter --- src/sage/rings/asymptotic/asymptotic_ring.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/asymptotic/asymptotic_ring.py b/src/sage/rings/asymptotic/asymptotic_ring.py index a2bacd54ade..faa24f102c3 100644 --- a/src/sage/rings/asymptotic/asymptotic_ring.py +++ b/src/sage/rings/asymptotic/asymptotic_ring.py @@ -2439,11 +2439,16 @@ def change_parameter(self, **kwds): sage: A.change_parameter(coefficient_ring=ZZ) is A True + sage: A.change_parameter(coefficient_ring=None) is A + True """ parameters = ('growth_group', 'coefficient_ring', 'default_prec') values = dict() for parameter in parameters: - values[parameter] = kwds.get(parameter, getattr(self, parameter)) + default = getattr(self, parameter) + values[parameter] = kwds.get(parameter, default) + if values[parameter] is None: + values[parameter] = default values['category'] = self.category() if isinstance(values['growth_group'], str): from growth_group import GrowthGroup From bdcb72be9df4b2e57a94be7d250e78e8b5105304 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Wed, 4 Nov 2015 15:04:26 -0500 Subject: [PATCH 4/4] write map_coefficients --- src/sage/rings/asymptotic/asymptotic_ring.py | 53 ++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/sage/rings/asymptotic/asymptotic_ring.py b/src/sage/rings/asymptotic/asymptotic_ring.py index faa24f102c3..1b9d1415eb3 100644 --- a/src/sage/rings/asymptotic/asymptotic_ring.py +++ b/src/sage/rings/asymptotic/asymptotic_ring.py @@ -2105,6 +2105,59 @@ def symbolic_expression(self, R=None): _symbolic_ = symbolic_expression # will be used by SR._element_constructor_ + def map_coefficients(self, f, new_coefficient_ring=None): + r""" + Return the asymptotic expansion obtained by applying ``f`` to + each coefficient of this asymptotic expansion. + + INPUT: + + - ``f`` -- a callable. A coefficient `c` will be mapped to `f(c)`. + + - ``new_coefficient_ring`` -- (default: ``None``) a ring. + + OUTPUT: + + An asymptotic expansion. + + EXAMPLES:: + + sage: A. = AsymptoticRing(growth_group='n^ZZ', coefficient_ring=ZZ) + sage: a = n^4 + 2*n^3 + 3*n^2 + O(n) + sage: a.map_coefficients(lambda c: c+1) + 2*n^4 + 3*n^3 + 4*n^2 + O(n) + sage: a.map_coefficients(lambda c: c-2) + -n^4 + n^2 + O(n) + + TESTS:: + + sage: a.map_coefficients(lambda c: 1/c, new_coefficient_ring=QQ) + n^4 + 1/2*n^3 + 1/3*n^2 + O(n) + sage: _.parent() + Asymptotic Ring over Rational Field + sage: a.map_coefficients(lambda c: 1/c) + Traceback (most recent call last): + ... + ValueError: ... is not a coefficient in + Exact Term Monoid n^ZZ with coefficients in Integer Ring. + """ + def mapping(term): + T = term.parent().change_parameter( + coefficient_ring=new_coefficient_ring) + if hasattr(term, 'coefficient'): + c = f(term.coefficient) + if c == 0: + return None + return T(term.growth, c) + else: + return T(term.growth) + + P = self.parent().change_parameter(coefficient_ring=new_coefficient_ring) + S = self.summands.copy() + S.map(mapping) + return P(S, simplify=False, convert=False) + + class AsymptoticRing(Algebra, UniqueRepresentation): r""" A ring consisting of :class:`asymptotic expansions `.