Ticket #14542: trac_14542-review-dg.patch

File trac_14542-review-dg.patch, 5.3 KB (added by darij, 9 years ago)

review patch

  • sage/combinat/species/generating_series.py

    # HG changeset patch
    # User darij grinberg <darijgrinberg@gmail.com>
    # Date 1375120438 25200
    # Node ID aed403aadf7c282d83d42eb084e8dde6e4c2ec04
    # Parent  e3a9833b4d47d4fdc055b9fd24d647cb36565478
    trac #14542: review patch
    
    diff --git a/sage/combinat/species/generating_series.py b/sage/combinat/species/generating_series.py
    a b class CycleIndexSeries(LazyPowerSeries): 
    597597            yield res
    598598            n += 1
    599599
    600     def arithmetic_product(self, g):
     600    def arithmetic_product(self, g, check_input = True):
    601601        """
    602         Returns the arithmetic product of ``self`` with ``g``.
    603        
     602        Return the arithmetic product of ``self`` with ``g``.
     603
    604604        For species `M` and `N` such that `M[\\varnothing] = N[\\varnothing] = \\varnothing`,
    605605        their arithmetic product is the species `M \\boxdot N` of "`M`-assemblies of cloned `N`-structures".
    606606        This operation is defined and several examples are given in [MM]_.
    607607
    608608        The cycle index series for `M \\boxdot N` can be computed in terms of the component series `Z_M` and `Z_N`,
    609609        as implemented in this method.
    610        
     610
     611        INPUT:
     612
     613        - ``g`` -- a cycle index series having the same parent as ``self``.
     614
     615        - ``check_input`` -- (default: ``True``) a Boolean which, when set
     616          to ``False``, will cause input checks to be skipped.
     617
     618        OUTPUT:
     619
     620        The arithmetic product of ``self`` with ``g``. This is a cycle
     621        index series defined in terms of ``self`` and ``g`` such that
     622        if ``self`` and ``g`` are the cycle index series of two species
     623        `M` and `N`, their arithmetic product is the cycle index series
     624        of the species `M \\boxdot N`.
     625
    611626        EXAMPLES:
    612627
    613628        For `C` the species of (oriented) cycles and `L_{+}` the species of nonempty linear orders, `C \\boxdot L_{+}` corresponds
    class CycleIndexSeries(LazyPowerSeries): 
    635650
    636651        REFERENCES:
    637652       
    638         .. [MM] M. Maia and M. Mendez. "On the arithmetic product of combinatorial species." Discrete Mathematics, vol. 308, issue 23, 2008, pp. 5407-5427.
    639           http://arxiv.org/abs/math/0503436.
     653        .. [MM] M. Maia and M. Mendez. "On the arithmetic product of combinatorial species".
     654           Discrete Mathematics, vol. 308, issue 23, 2008, pp. 5407-5427.
     655           :arXiv:`math/0503436v2`.
    640656       
    641657        """
    642658        from sage.combinat.partition import Partition, Partitions
    class CycleIndexSeries(LazyPowerSeries): 
    646662
    647663        p = self.base_ring()
    648664
    649         assert self.coefficient(0) == p.zero()
    650         assert g.coefficient(0) == p.zero()
     665        if check_input:
     666            assert self.coefficient(0) == p.zero()
     667            assert g.coefficient(0) == p.zero()
    651668
    652669        # We first define an operation `\\boxtimes` on partitions as in Lemma 2.1 of [MM]_.
    653         def arith_prod_of_partitions (l1, l2):
     670        def arith_prod_of_partitions(l1, l2):
    654671            # Given two partitions `l_1` and `l_2`, we construct a new partition `l_1 \\boxtimes l_2` by
    655             # the following procedure: each pair of parts `a \\in l_1` and `b \\in l_2` contributes a part
    656             # `\\lcm (a, b)` to `l_1 \\boxtimes l_2` with multiplicity `\\gcm (l_1, l_2)``.
     672            # the following procedure: each pair of parts `a \\in l_1` and `b \\in l_2` contributes
     673            # `\\gcd (a, b)`` parts of size `\\lcm (a, b)` to `l_1 \\boxtimes l_2`. If `l_1` and `l_2`
     674            # are partitions of integers `n` and `m`, respectively, then `l_1 \\boxtimes l_2` is a
     675            # partition of `nm`.
    657676            term_iterable = chain.from_iterable( repeat(lcm(pair), times=gcd(pair)) for pair in product(l1, l2) )
    658677            term_list = sorted(term_iterable, reverse=True)
    659678            res = Partition(term_list)
    660679            return res
    661680
    662         # We then extend this to an operation on symmetric functions as per eq. 52 of [MM]_.
    663         def arith_prod_sf (x, y):
     681        # We then extend this to an operation on symmetric functions as per eq. (52) of [MM]_.
     682        # (Maia and Mendez, in [MM]_, are talking about polynomials instead of symmetric
     683        # functions, but this boils down to the same: Their x_i corresponds to the i-th power
     684        # sum symmetric function.)
     685        def arith_prod_sf(x, y):
    664686            ap_sf_wrapper = lambda l1, l2: p(arith_prod_of_partitions(l1, l2))
    665687            return p._apply_multi_module_morphism(x, y, ap_sf_wrapper)
    666688
    667689        # Sage stores cycle index series by degree.
    668690        # Thus, to compute the arithmetic product `Z_M \\boxdot Z_N` it is useful
    669691        # to compute all terms of a given degree `n` at once.
    670         def arith_prod_coeff (n):
     692        def arith_prod_coeff(n):
    671693            if n == 0:
    672694                res = p.zero()
    673695            else:
    674                 index_set = ((d, n/d) for d in divisors(n))
     696                index_set = ((d, n // d) for d in divisors(n))
    675697                res = sum(arith_prod_sf(self.coefficient(i), g.coefficient(j)) for i,j in index_set)
    676698
    677             # Build a list which has res in the nth slot and 0's before and after
     699            # Build a list which has res in the `n`th slot and 0's before and after
    678700            # to feed to sum_generator
    679701            res_in_seq = [p.zero()]*n + [res, p.zero()]
    680702