Exemple #1
0
    def _initialize_fat_horizontal(self, s, L):
        """
        Initialise reduction matrices for horizontal reductions for blocks from `s` to `L`.

        TESTS::

            sage: p = 4999
            sage: x = PolynomialRing(GF(p),"x").gen()
            sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1)
            sage: C._init_frob()
            sage: C._initialize_fat_horizontal(p, 3)
            sage: len(C._horizontal_fat_s[p])
            3
        """
        assert self._sqrtp
        if s not in self._horizontal_fat_s:
            N = self._N - 1  # padic precision of self._Zq0
            d = self._d
            L0 = min(L, N)
            targets = [0] * (2 * L0)
            for l in range(L0):
                targets[2 * l] = self._p * l
                targets[2 * l + 1] = self._p * (l + 1) - d - 1
            (m0, m1), (M0, M1) = self._horizontal_matrix_reduction(s)
            M0, M1 = [elt.change_ring(self._Zq0) for elt in [M0, M1]]
            D0, D1 = [matrix(self._Zq0, [elt]) for elt in [m0, m1]]
            MH = interval_products(M0, M1, targets)
            DH = [elt[0, 0] for elt in interval_products(D0, D1, targets)]
            if L > N:  # Vandermonde interpolation
                #  f^{(r)}(0) p^r / r! for r = 0, ..., N-1,
                MT = [None] * N
                DT = [0] * N
                for r in range(N):
                    MT[r] = matrix(self._Zq0, d, d)
                    for h in range(N):
                        v = self._vandermonde[r, h]
                        for i in range(d):
                            for j in range(d):
                                MT[r][i, j] += v * MH[h][i, j]
                        DT[r] += v * DH[h]
                for k in range(N, L):
                    M = matrix(self._Zq0, d, d)
                    D = 0
                    k1pow = self._Zq0(1)  # power of k + 1
                    for h in range(N):
                        for i in range(d):
                            for j in range(d):
                                M[i, j] += k1pow * MT[h][i, j]
                        D += k1pow * DT[h]
                        k1pow *= k + 1
                    MH.append(M)
                    DH.append(D)

            iDH = [1 / elt for elt in DH]
            self._horizontal_fat_s[s] = [(iDH[i], MH[i]) for i in range(L)]
        assert len(self._horizontal_fat_s[s]) >= L
    def _initialize_fat_vertical(self, s0, max_upper_target):
        """
        Initialise reduction matrices for vertical reductions for blocks from `s0` to `s0 + max_upper_target`.


        TESTS::

            sage: p = 4999
            sage: x = PolynomialRing(GF(p),"x").gen()
            sage: C = CyclicCover(3, x^4 + 4*x^3 + 9*x^2 + 3*x + 1)
            sage: C._init_frob()
            sage: C._initialize_fat_vertical(1, p + p // 3)
            sage: len(C._vertical_fat_s[1])
            2
        """
        L = floor((max_upper_target - self._epsilon) / self._p) + 1
        if s0 not in self._vertical_fat_s:
            (m0, m1), (M0, M1) = self._vertical_matrix_reduction(s0)
            D0, D1 = map(lambda y: matrix(self._Zq, [y]), [m0, m1])
            targets = [0] * (2 * L)
            for l in reversed(range(L)):
                targets[2 * l] = max_upper_target - self._p * (L - l)
                targets[2 * l + 1] = max_upper_target - self._p * (L - 1 - l)
            if targets[0] < 0:
                targets[0] = self._epsilon
            MV = interval_products(M0, M1, targets)
            DV = interval_products(D0, D1, targets)
            for l in range(L):
                D = DV[l][0, 0]
                if D % self._p == 0:
                    iD = 1 / self._Zq(D.lift() / self._p)
                    MV[l] = matrix(
                        self._Zq,
                        [
                            [iD * ZZ(elt.lift() / self._p) for elt in row]
                            for row in MV[l].rows()
                        ],
                    )
                else:
                    MV[l] *= 1 / D
            self._vertical_fat_s[s0] = MV

        assert len(self._vertical_fat_s[s0]) >= L