Ticket #12528: trac_12528_free_module-optimize-nt.patch

File trac_12528_free_module-optimize-nt.patch, 8.3 KB (added by nthiery, 9 years ago)
  • sage/algebras/iwahori_hecke_algebra.py

    # HG changeset patch
    # User Nicolas M. Thiery <nthiery@users.sf.net>
    # Date 1329571592 -3600
    # Node ID d10747ae9fde3dee43a8be5a24de3c8e246e20f0
    # Parent  93bff626ffd1d28115ea273dad7de7f8c6c6c0da
    #12528: Little optimizations in CombinatorialFreeModule
    
    diff --git a/sage/algebras/iwahori_hecke_algebra.py b/sage/algebras/iwahori_hecke_algebra.py
    a b class IwahoriHeckeAlgebraT(Combinatorial 
    424424        """
    425425        wi = w.apply_simple_reflection(i, side = side)
    426426        if w.has_descent(i, side = side):
    427             return self.term(w ,  self._q1+self._q2) + \
    428                    self.term(wi, -self._q1*self._q2)
     427            # 10% faster than a plain addition on the example of #12528
     428            return self.sum_of_terms(((w ,  self._q1+self._q2),
     429                                      (wi, -self._q1*self._q2)), distinct=True)
    429430        else:
    430431            return self.monomial(wi)
    431432
    class IwahoriHeckeAlgebraT(Combinatorial 
    441442            [(q-1)*T1 + q, T2*T1]
    442443
    443444        """
    444         return self.sum(self.product_by_generator_on_basis(w, i)._acted_upon_(c) for (w,c) in x)
     445        return self.linear_combination((self.product_by_generator_on_basis(w, i), c) for (w,c) in x)
    445446
    446447    def _repr_term(self, t):
    447448        """
  • sage/algebras/steenrod/steenrod_algebra.py

    diff --git a/sage/algebras/steenrod/steenrod_algebra.py b/sage/algebras/steenrod/steenrod_algebra.py
    a b class SteenrodAlgebra_generic(Combinator 
    31223122                Sq^2 Sq^1
    31233123                sage: d = Sq(0,0,1)
    31243124                sage: d._basis_dictionary('arnonc')
    3125                 {(7,): 1, (2, 5): 1, (4, 2, 1): 1, (4, 3): 1}
     3125                {(7,): 1, (2, 5): 1, (4, 3): 1, (4, 2, 1): 1}
    31263126                sage: d.change_basis('arnonc')
    31273127                Sq^2 Sq^5 + Sq^4 Sq^2 Sq^1 + Sq^4 Sq^3 + Sq^7
    31283128           
  • sage/combinat/free_module.py

    diff --git a/sage/combinat/free_module.py b/sage/combinat/free_module.py
    a b class CombinatorialFreeModule(UniqueRepr 
    19311931
    19321932    def term(self, index, coeff=None):
    19331933        """
     1934        Constructs a term in ``self``
     1935
    19341936        INPUT:
    1935          - index: the index of a basis element
    1936          - coeff: an element of the coefficient ring
    1937 
    1938         Returns the corresponding term.  The coefficient is assumed to be
    1939         one if it is not given.
     1937
     1938        - ``index`` -- the index of a basis element
     1939        - ``coeff`` -- an element of the coefficient ring (default: one)
    19401940
    19411941        EXAMPLES::
    19421942
    class CombinatorialFreeModule(UniqueRepr 
    19601960            sage: F._monomial('a')
    19611961            B['a']
    19621962        """
    1963         return self.term( index, self.base_ring().one() )
     1963        return self._from_dict( {index: self.base_ring().one()}, remove_zeros = False )
    19641964
    19651965    # This is generic, and should be lifted into modules_with_basis
    19661966    @lazy_attribute
    class CombinatorialFreeModule(UniqueRepr 
    19861986        # Should use a real Map, as soon as combinatorial_classes are enumerated sets, and therefore parents
    19871987        return PoorManMap(self._monomial, domain = self._basis_keys, codomain = self, name = "Term map")
    19881988
    1989     def _sum_of_monomial(self, indices):
     1989    def _sum_of_monomials(self, indices):
    19901990        """
    19911991        TESTS::
    19921992
    19931993            sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
    1994             sage: F._sum_of_monomial(['a', 'b'])
     1994            sage: F._sum_of_monomials(['a', 'b'])
    19951995            B['a'] + B['b']
    19961996        """
    1997         #TODO: optimize
     1997        # TODO: optimize by calling directly _from_dict if we
     1998        # know that all indices are distinct as sum_of_terms;
     1999        # otherwise, maybe call dict_addition directly
    19982000        return self.sum(self.monomial(index) for index in indices)
    19992001
    20002002    @lazy_attribute
    class CombinatorialFreeModule(UniqueRepr 
    20212023            A map to Free module generated by {'a', 'b', 'c'} over Rational Field
    20222024        """
    20232025        # domain = sets of self.combinatorial_class(),
    2024         return PoorManMap(self._sum_of_monomial, codomain = self)
    2025 
    2026     def sum_of_terms(self, terms):
     2026        return PoorManMap(self._sum_of_monomials, codomain = self)
     2027
     2028    def sum_of_terms(self, terms, distinct=False):
    20272029        """
     2030        Constructs a sum of terms of ``self``
     2031
    20282032        INPUT:
    2029          - terms: an list (or iterable) of pairs (index, coeff)
    2030 
    2031         Returns the sum of the terms
     2033
     2034        - ``terms`` -- a list (or iterable) of pairs (index, coeff)
     2035        - ``distinct`` -- whether the indices are guaranteed to be distinct (default: ``False``)
    20322036
    20332037        EXAMPLES::
    20342038
    class CombinatorialFreeModule(UniqueRepr 
    20362040            sage: F.sum_of_terms([('a',2), ('c',3)])
    20372041            2*B['a'] + 3*B['c']
    20382042
     2043        If ``distinct`` is True, then the construction is optimized::
     2044
     2045            sage: F.sum_of_terms([('a',2), ('c',3)], distinct = True)
     2046            2*B['a'] + 3*B['c']
     2047
     2048        .. warning::
     2049
     2050            Use ``distinct=True`` only if you are sure that the
     2051            indices are indeed distinct::
     2052
     2053                sage: F.sum_of_terms([('a',2), ('a',3)], distinct = True)
     2054                3*B['a']
     2055
    20392056        Extreme case::
    20402057
    20412058            sage: F.sum_of_terms([])
    20422059            0
    2043 
    2044         TODO: optimize, especially for the special case where all
    2045         indices are distinct (should there be an option distinct=True
    2046         for this, or a separate function sum_of_distinct_terms)?
    20472060        """
     2061        if distinct:
     2062            return self._from_dict(dict(terms))
    20482063        return self.sum(self.term(index, coeff) for (index, coeff) in terms)
    20492064
    20502065    def monomial_or_zero_if_none(self, i):
    class CombinatorialFreeModule(UniqueRepr 
    20742089
    20752090    def _from_dict( self, d, coerce=False, remove_zeros=True ):
    20762091        """
    2077         Given a monomial coefficient dictionary ``d``, returns the
    2078         element of self with those monomials
     2092        Construct an element of ``self`` from an `{index: coefficient}` dictionary
     2093
     2094        INPUT:
     2095
     2096        - ``d`` -- a dictionary ``{index: coeff}`` where each ``index`` is the
     2097          index of a basis element and each ``coeff`` belongs to the
     2098          coefficient ring ``self.base_ring()``
     2099
     2100        - ``coerce`` -- a boolean (default: ``False``), whether to coerce the
     2101          ``coeff``s to the coefficient ring
     2102
     2103        - ``remove_zeros`` -- a boolean (default: ``True``), if some
     2104          ``coeff``s may be zero and should therefore be removed
    20792105
    20802106        EXAMPLES::
    20812107
    class CombinatorialFreeModule(UniqueRepr 
    20952121            s[2, 1]
    20962122            sage: a.coefficient(part).parent()
    20972123            Rational Field
     2124
     2125        With ``remove_zeros=True``, zero coefficients are removed::
     2126
     2127            sage: s._from_dict({part:0})
     2128            0
     2129
     2130        .. warning::
     2131
     2132            With ``remove_zeros=True``, it is assumed that no
     2133            coefficient of the dictionary is zero. Otherwise, this may
     2134            lead to illegal results::
     2135
     2136                sage: list(s._from_dict({part:0}, remove_zeros=False))
     2137                [([2, 1], 0)]
    20982138        """
    20992139        assert isinstance(d, dict)
    2100 
    2101         R = self.base_ring()
    2102         zero = R( 0 )
    2103         for_removal = []
    2104 
    21052140        if coerce:
    2106             D = d.copy()
    2107             for key, coeff in D.iteritems():
    2108                 if remove_zeros and coeff == zero:
    2109                     for_removal.append( key )
    2110                 else:
    2111                     D[ key ] = R( coeff )
    2112             for key in for_removal:
    2113                 del D[ key ]
    2114             return self.element_class( self, D )
    2115         elif remove_zeros:
    2116             D = d.copy()
    2117             for key, coeff in D.iteritems():
    2118                 if coeff == zero:
    2119                     for_removal.append( key )
    2120             for key in for_removal:
    2121                 del D[ key ]
    2122             return self.element_class( self, D )
    2123         else:
    2124             return self.element_class( self, d )
     2141            R = self.base_ring()
     2142            d = dict( (key, R(coeff)) for key,coeff in d.iteritems())
     2143        if remove_zeros:
     2144            d = dict( (key, coeff) for key, coeff in d.iteritems() if coeff)
     2145        return self.element_class( self, d )
    21252146
    21262147
    21272148class CombinatorialFreeModule_Tensor(CombinatorialFreeModule):