Ejemplo n.º 1
0
 def canonize_and_add_monomials(self, monomials, lower_bound=None):
     inadmissibles = KeyOrderedDict()
     
     def push_inadmissible(inad):
         inadmissibles.toggle(RevlexBasisMonomial(*inad), 1)
     
     for mon in monomials:
         if mon.admissible():
             self._add_admissible_monomial(mon)
         else:
             push_inadmissible(mon)
     while inadmissibles:
         mon, _ = inadmissibles.remove_max()
         if lower_bound is not None and leading_integer_upper_bound(mon) < lower_bound[0]:
             continue
         for rep in _adem_relation(mon):
             if rep.admissible():
                 if lower_bound is None or rep >= lower_bound: 
                     self._add_admissible_monomial(rep)
             else:
                 push_inadmissible(rep)
Ejemplo n.º 2
0
 def __init__(self, monomials, lower_bound=None):
     self._admissibles = KeyOrderedDict()
     self.canonize_and_add_monomials(monomials, lower_bound=lower_bound)
Ejemplo n.º 3
0
class AdmissibleTerm(object):
    def __init__(self, monomials, lower_bound=None):
        self._admissibles = KeyOrderedDict()
        self.canonize_and_add_monomials(monomials, lower_bound=lower_bound)

    def __str__(self):
        s = ' + '.join(map(str, self._admissibles))
        return s if s else '0'

    def _add_admissible_monomial(self, monomial):
        self._admissibles.toggle(LexBasisMonomial(*monomial), 1)

    def __len__(self):
        return len(self._admissibles)

    def __iter__(self):
        return iter(self._admissibles)

    def __eq__(self, other):
        return self._admissibles == other._admissibles

    def __bool__(self):
        return bool(self._admissibles)

    is_zero = __bool__

    def leading_term(self):
        if self._admissibles:
            k, _ = self._admissibles.peek_max()
            return k
        else:
            raise IndexError('Attempt to examine leading term in zero expression')

    # this obviously leaves room for improvement
    def canonize_and_add_monomials(self, monomials, lower_bound=None):
        inadmissibles = KeyOrderedDict()
        
        def push_inadmissible(inad):
            inadmissibles.toggle(RevlexBasisMonomial(*inad), 1)
        
        for mon in monomials:
            if mon.admissible():
                self._add_admissible_monomial(mon)
            else:
                push_inadmissible(mon)
        while inadmissibles:
            mon, _ = inadmissibles.remove_max()
            if lower_bound is not None and leading_integer_upper_bound(mon) < lower_bound[0]:
                continue
            for rep in _adem_relation(mon):
                if rep.admissible():
                    if lower_bound is None or rep >= lower_bound: 
                        self._add_admissible_monomial(rep)
                else:
                    push_inadmissible(rep)

    def differential(self, lower_bound=None):
        seq = chain.from_iterable(map(_differential, iter(self)))
        return AdmissibleTerm(seq, lower_bound=lower_bound)
    
    def __add__(self, other):
        new_at = AdmissibleTerm([])
        new_at._admissibles = self._admissibles.sym_diff(other._admissibles)
        return new_at

    def __iadd__(self, other):
        self._admissibles = self._admissibles.sym_diff(other._admissibles)
        return self

    def __mul__(self, other):
        terms = (x * y for x, y in product(self, other))
        return AdmissibleTerm(terms)

    def copy(self):
        new_at = AdmissibleTerm([])
        new_at._admissibles = self._admissibles.copy()
        return new_at