Exemple #1
0
 def _enumerate_row(self, ans, col, dia, rownum):
     if rownum == self.nrows - 1:
         loop = [
             (self.one, ans, col, dia),
         ].__iter__()
     else:
         loop = self._enumerate_row(ans, col, dia, rownum + 1)
     for (cf, a, c, d) in loop:
         # fill in row #rownum
         for sol in WeightedIntegerVectors(self.exp[rownum], self.powers):
             cf2 = cf
             isbad = False
             for (i, s) in enumerate(sol):
                 if s > 0 and rownum + i >= self.maxn:
                     isbad = True
                     break
                 a[rownum, i] = s
                 if rownum + 1 < self.nrows:
                     cprev = c[rownum + 1, i]
                     dprev = 0 if i == 0 else d[rownum + 1, i - 1]
                 else:
                     cprev = 0
                     dprev = 0
                 c[rownum, i] = cprev + s
                 d[rownum, i] = dprev + s
                 cf2 *= binom_modp(self.p, dprev + s, s)
                 if cf2.is_zero():
                     isbad = True
                     break
             if isbad:
                 continue
             yield (cf2, a, c, d)
Exemple #2
0
    def __action_exponents(self, p, n, maxP, isconjugate=False):
        """
        generator for exponent sequences R such that the multinomial coefficient

           (p r1 | p^2 r2 | p^3 r3 | ... | (p-1)n - sum rk)

        is not zero and R is dominated by maxP
        """
        # Question: can we enforce sum rk <= (p-1)n?
        for (cf, exp, dg, psum,
             esum) in self.__action_exponents2(p, maxP, 0, 0):
            # the flag isconjugate switches between ordinary and conjugate action
            if isconjugate:
                c2 = binom_modp(p, -n * (p - 1), psum)
            else:
                c2 = binom_modp(p, psum + n * (p - 1) - esum, psum)
            if c2 != 0:
                yield (c2 * cf, exp, dg)
Exemple #3
0
    def decompose(p, n):
        """
        Decompose a omega_n into a product of Dicksonians
        """

        inv = p**(p - 2)
        tdeg = 2 * (p - 1) if p > 2 else 1
        pmo = p - 1
        # FIXME: why does this not depend on the generic/non-generic flag for p=2?
        for expos in PetersonPolynomials._milnor_basis(p, tdeg * n):
            sum = 0
            cf = 1
            for a in expos:
                sum += a
                cf *= binom_modp(p, sum, a)
                if 0 == cf:
                    break
            if 0 == cf:
                continue
            cf *= binom_modp(p, -n * pmo, sum)
            if 0 != cf:
                yield [cf, expos]
Exemple #4
0
    def left_steenrod_action_milnor(self, a, m):
        qexp, Rexp = a
        yexp, xexp = m & 1, m >> 1
        p = self._prime

        if len(qexp) > 1:
            # Q_i Q_j z = 0 for all z
            return self.zero()
        if len(qexp) == 1 and yexp == 0:
            # Qj(x^k) = 0
            return self.zero()

        # compute P(Rexp)*x^xexp
        sum = 0
        deg = xexp
        ppow = p
        cf = 1
        for i in Rexp:
            sum = sum + i
            if xexp >= 0 and sum > xexp:
                return self.zero()
            cf *= binom_modp(self._prime, sum, i)
            cf = cf % p
            if 0 == cf:
                return self.zero()
            deg += i * (ppow - 1)
            ppow *= p
        rest = xexp - sum
        cf *= binom_modp(self._prime, rest + sum, sum)
        if 0 == cf:
            return self.zero()
        cf = cf % p

        if len(qexp) == 0:
            ans = self.monomial(yexp + (deg << 1))
        else:
            # Qi(y) = x^{p^i}
            ans = self.monomial((deg + p**qexp[0]) << 1)
        return self.linear_combination(((ans, cf), ))
Exemple #5
0
 def _multinomials(self, smds, prime, total):
     try:
         cursmd = next(smds)
         r, q, p = cursmd
     except StopIteration:
         yield self._coaction_tensor(self.one(), 0, ()), total, []
         return
     for (smd, tot2, elst) in self._multinomials(smds, prime, total):
         # r2,q2,p2 = smd
         maxexpo = tot2
         for expo in range(0, maxexpo + 1):
             coeff = binom_modp(self._prime, tot2, expo)
             nr, nq, np = smd
             yield self._coaction_tensor(
                 nr.map_coefficients(lambda x: coeff * x), nq, np
             ), tot2 - expo, elst + [
                 expo,
             ]
             nextpow = cursmd * smd
             if len(nextpow) == 0:
                 break
             smd = nextpow[0]
Exemple #6
0
 def __action_exponents2(self, p, maxP, partialsum, expsum):
     idx = len(maxP)
     if idx > 0:
         ppow = p**idx
         opdeg = (ppow - 1) // (p - 1)
         idx = idx - 1
         for e in range(maxP[idx] + 1):
             epow = e * ppow
             ps2 = partialsum + epow
             cf = binom_modp(p, ps2, epow)
             if cf != 0:
                 for (c, exp, dg, ps, es) in self.__action_exponents2(
                         p, maxP[0:idx], ps2, expsum + e):
                     yield (
                         c * cf,
                         exp + [
                             e,
                         ],
                         dg + e * opdeg,
                         ps,
                         es,
                     )
     else:
         yield (1, [], 0, partialsum, expsum)
Exemple #7
0
    def admissible_action(self, redpow, elem, debug=False):
        """
        Compute redpow * elem using admissible matrices
        """
        from yacop.utils.admissible_matrices import AdmissibleMatrices

        isgen = redpow.parent().is_generic()
        zpad = [
            0,
        ] * self._index
        ans = []
        for (key, cf) in redpow:
            if isgen:
                (epart, expos) = key
                if len(epart) > 0:
                    raise ValueError(
                        "exterior multiplications not implemented yet")
            else:
                expos = key
            # print "redpow contains", (key,cf), "expos=",expos
            for (c, a, cols,
                 diag) in AdmissibleMatrices(self._prime,
                                             expos,
                                             maxn=self._index).enumerate():
                if debug:
                    print("admissible matrix, coeff=%d\n%s" % (c, a))
                for (dkey, dcf) in elem:
                    ncf = c * dcf * cf
                    for _ in [
                            0,
                    ]:
                        dkey = list(dkey) + zpad + zpad
                        if max(dkey[0::2]) != 0:
                            raise ValueError(
                                "exterior part not implemented yet")
                        rexpos = dkey[1::2]
                        zexpos = list(reversed(rexpos[0:self._index - 1]))
                        zexpos = [-1 - _ for _ in zexpos] + [
                            -1 + sum(zexpos) + rexpos[self._index - 1]
                        ]
                        if debug:
                            print(
                                "%s = zeta(%s)" %
                                (self._from_dict({tuple(dkey): dcf}), zexpos))
                        zrems = [
                            a - b for (a, b) in zip(zexpos, cols[1:] + zpad)
                        ]
                        if debug:
                            print("zeta-remainder = ", zrems)
                        for (dterm, zterm) in zip(diag, zrems):
                            ncf *= binom_modp(self._prime, dterm + zterm,
                                              dterm)
                            if ncf.is_zero():
                                break
                        if debug:
                            print("coefficient=", ncf)
                        if ncf.is_zero():
                            continue
                        newzeta = [a + b for (a, b) in zip(diag + zpad, zrems)]
                        newexpo = list(
                            reversed(
                                [-1 - a for a in newzeta[0:self._index - 1]]))
                        newexpo.append(1 + newzeta[self._index - 1] -
                                       sum(newexpo))
                        newkey = [(0, _) for _ in newexpo]
                        newkey = [_ for j in newkey for _ in j]
                        while newkey[-1] == 0:
                            newkey.pop()
                        ans.append(self._from_dict({tuple(newkey): ncf}))
        return self.sum(ans)
Exemple #8
0
 def gamma(self, n):
     """
     the gamma(n) in the definition of omega(n)
     """
     return binom_modp(self.p, -(self.p - 1) * n, n)
Exemple #9
0
    def left_steenrod_action_milnor_conj(self, a, m):
        """
        TESTS::

            sage: from yacop.modules.classifying_spaces import *
            sage: N = BZp(5) ; N.inject_variables()
            Defining y, x
            sage: A = SteenrodAlgebra(5)
            sage: P = A.P
            sage: for i in range(10):
            ....:     for q in range(3):
            ....:         Q = A.one() if q == 0 else A.Q(q)
            ....:         for r1 in range(10):
            ....:             for r2 in range(3):
            ....:                 op = P(r1,r2)*Q
            ....:                 po = op.antipode()
            ....:                 assert po * (x**i) == op % (x**i)
            ....:                 assert po * (y*x**i) == op % (y*x**i)
        """

        qexp, Rexp = a
        yexp, xexp = m & 1, m >> 1
        p = self._prime

        cf = 1

        if len(qexp) > 1:
            # Q_i Q_j z = 0 for all z
            return self.zero()
        if len(qexp) == 1:
            if yexp == 0:
                # Qj(x^k) = 0
                return self.zero()
            else:
                # evaluate chi(Q_k)(y*x**i) = -x**(i+p^k) first
                cf = p - 1
                yexp = 0
                xexp += p**qexp[0]

        # compute P(Rexp)*x^xexp
        sum = 0
        psum = 0
        deg = xexp
        ppow = p
        for i in Rexp:
            sum = sum + i
            cf *= binom_modp(self._prime, sum, i)
            cf = cf % p
            if 0 == cf:
                return self.zero()
            deg += i * (ppow - 1)
            psum += ppow * i
            ppow *= p
        rest = -1 - xexp - psum
        cf *= binom_modp(self._prime, rest + sum, sum)
        if 0 == cf:
            return self.zero()
        cf = cf % p

        ans = self.monomial(yexp + (deg << 1))

        return self.linear_combination(((ans, cf), ))