Ejemplo n.º 1
0
    def __cmp__(self, right):
        """
        Compare self to right.

        EXAMPLES::

            sage: x = Gamma0(18)([19,1,18,1])
            sage: x.__cmp__(3) is not 0
            True
            sage: x.__cmp__(x)
            0

            sage: x = Gamma0(5)([1,1,0,1])
            sage: x == 0
            False

        This once caused a segfault (see trac #5443)::

            sage: r,s,t,u,v = map(SL2Z, [[1, 1, 0, 1], [-1, 0, 0, -1], [1, -1, 0, 1], [1, -1, 2, -1], [-1, 1, -2, 1]])
            sage: v == s*u
            True
            sage: s*u == v
            True
        """
        from sage.misc.functional import parent
        if parent(self) != parent(right):
            return cmp(type(self), type(right))
        else:
            return cmp(self.__x, right.__x)
Ejemplo n.º 2
0
    def __cmp__(self, right):
        """
        Compare self to right.

        EXAMPLES::

            sage: x = Gamma0(18)([19,1,18,1])
            sage: x.__cmp__(3) is not 0
            True
            sage: x.__cmp__(x)
            0

            sage: x = Gamma0(5)([1,1,0,1])
            sage: x == 0
            False

        This once caused a segfault (see trac #5443)::

            sage: r,s,t,u,v = map(SL2Z, [[1, 1, 0, 1], [-1, 0, 0, -1], [1, -1, 0, 1], [1, -1, 2, -1], [-1, 1, -2, 1]])
            sage: v == s*u
            True
            sage: s*u == v
            True
        """
        from sage.misc.functional import parent
        if parent(self) != parent(right):
            return cmp(type(self), type(right))
        else:
            return cmp(self.__x, right.__x)
Ejemplo n.º 3
0
def _negaconvolution_fft(L1, L2, n):
   """
   Returns negacyclic convolution of lists L1 and L2, using FFT
   algorithm. L1 and L2 must both be length `2^n`, where
   `n \geq 3`. Assumes all entries of L1 and L2 belong to the
   same ring.

   EXAMPLES::

       sage: from sage.rings.polynomial.convolution import _negaconvolution_naive
       sage: from sage.rings.polynomial.convolution import _negaconvolution_fft
       sage: _negaconvolution_naive(range(8), range(5, 13))
       [-224, -234, -224, -192, -136, -54, 56, 196]
       sage: _negaconvolution_fft(range(8), range(5, 13), 3)
       [-224, -234, -224, -192, -136, -54, 56, 196]

   ::

       sage: for n in range(3, 10):
       ...      L1 = [ZZ.random_element(100) for _ in range(1 << n)]
       ...      L2 = [ZZ.random_element(100) for _ in range(1 << n)]
       ...      assert _negaconvolution_naive(L1, L2) == _negaconvolution_fft(L1, L2, n)
"""
   assert n >= 3

   R = parent(L1[0])

   # split into 2^m pieces of 2^(k-1) coefficients each, with k as small
   # as possible, subject to m <= k (so that the ring of Fourier coefficients
   # has enough roots of unity)
   m = (n + 1) >> 1
   k = n + 1 - m

   M = 1 << m
   K = 1 << k

   # split inputs into polynomials
   L1 = _split(L1, m, k)
   L2 = _split(L2, m, k)

   # fft each input
   _fft(L1, K, 0, m, K >> 1)
   _fft(L2, K, 0, m, K >> 1)

   # pointwise multiply
   L3 = [_negaconvolution(L1[i], L2[i], k) for i in range(M)]

   # inverse fft
   _ifft(L3, K, 0, m, K >> 1)

   # combine back into a single list
   L3 = _nega_combine(L3, m, k)

   # normalise
   return [R(x / M) for x in L3]
Ejemplo n.º 4
0
def _negaconvolution_fft(L1, L2, n):
    """
   Returns negacyclic convolution of lists L1 and L2, using FFT
   algorithm. L1 and L2 must both be length `2^n`, where
   `n \geq 3`. Assumes all entries of L1 and L2 belong to the
   same ring.

   EXAMPLES::

       sage: from sage.rings.polynomial.convolution import _negaconvolution_naive
       sage: from sage.rings.polynomial.convolution import _negaconvolution_fft
       sage: _negaconvolution_naive(range(8), range(5, 13))
       [-224, -234, -224, -192, -136, -54, 56, 196]
       sage: _negaconvolution_fft(range(8), range(5, 13), 3)
       [-224, -234, -224, -192, -136, -54, 56, 196]

   ::

       sage: for n in range(3, 10):
       ...      L1 = [ZZ.random_element(100) for _ in range(1 << n)]
       ...      L2 = [ZZ.random_element(100) for _ in range(1 << n)]
       ...      assert _negaconvolution_naive(L1, L2) == _negaconvolution_fft(L1, L2, n)
"""
    assert n >= 3

    R = parent(L1[0])

    # split into 2^m pieces of 2^(k-1) coefficients each, with k as small
    # as possible, subject to m <= k (so that the ring of Fourier coefficients
    # has enough roots of unity)
    m = (n + 1) >> 1
    k = n + 1 - m

    M = 1 << m
    K = 1 << k

    # split inputs into polynomials
    L1 = _split(L1, m, k)
    L2 = _split(L2, m, k)

    # fft each input
    _fft(L1, K, 0, m, K >> 1)
    _fft(L2, K, 0, m, K >> 1)

    # pointwise multiply
    L3 = [_negaconvolution(L1[i], L2[i], k) for i in range(M)]

    # inverse fft
    _ifft(L3, K, 0, m, K >> 1)

    # combine back into a single list
    L3 = _nega_combine(L3, m, k)

    # normalise
    return [R(x / M) for x in L3]
Ejemplo n.º 5
0
    def __contains__(self, x):
        r"""
        Check in the element x is in the mathematical parent self.

        EXAMPLES::
            sage: D5 = FiniteCoxeterGroups().example()
            sage: D5.an_element() in D5
            True
            sage: 1 in D5
            False

        (also tested by :meth:`test_an_element` :meth:`test_some_elements`)
        """
        from sage.misc.functional import parent
        return parent(x) is self
Ejemplo n.º 6
0
    def __contains__(self, x):
        r"""
        Check in the element x is in the mathematical parent self.

        EXAMPLES::
            sage: D5 = FiniteCoxeterGroups().example()
            sage: D5.an_element() in D5
            True
            sage: 1 in D5
            False

        (also tested by :meth:`test_an_element` :meth:`test_some_elements`)
        """
        from sage.misc.functional import parent
        return parent(x) is self
Ejemplo n.º 7
0
    def _coerce_impl(self, x):
        """
        Coerce x into self, if possible.

        EXAMPLES::

            sage: J = J0(37) ; J.Hom(J)._coerce_impl(matrix(ZZ,4,[5..20]))
            Abelian variety endomorphism of Abelian variety J0(37) of dimension 2
            sage: K = J0(11) * J0(11) ; J.Hom(K)._coerce_impl(matrix(ZZ,4,[5..20]))
            Abelian variety morphism:
              From: Abelian variety J0(37) of dimension 2
              To:   Abelian variety J0(11) x J0(11) of dimension 2
        """
        if self.matrix_space().has_coerce_map_from(parent(x)):
            return self(x)
        else:
            return HomsetWithBase._coerce_impl(self, x)
Ejemplo n.º 8
0
 def _coerce_impl(self, x):
     """
     Coerce x into self, if possible.
     
     EXAMPLES::
     
         sage: J = J0(37) ; J.Hom(J)._coerce_impl(matrix(ZZ,4,[5..20]))
         Abelian variety endomorphism of Abelian variety J0(37) of dimension 2
         sage: K = J0(11) * J0(11) ; J.Hom(K)._coerce_impl(matrix(ZZ,4,[5..20]))
         Abelian variety morphism:
           From: Abelian variety J0(37) of dimension 2
           To:   Abelian variety J0(11) x J0(11) of dimension 2
     """
     if self.matrix_space().has_coerce_map_from(parent(x)):
         return self(x)
     else:
         return HomsetWithBase._coerce_impl(self, x)
Ejemplo n.º 9
0
def _split(L, m, k):
   """
   Assumes L is a list of length `2^{m+k-1}`. Splits it into
   `2^m` lists of length `2^{k-1}`, returned as a list
   of lists. Each list is zero padded up to length `2^k`.

   EXAMPLES::

       sage: from sage.rings.polynomial.convolution import _split
       sage: _split([1, 2, 3, 4, 5, 6, 7, 8], 2, 2)
       [[1, 2, 0, 0], [3, 4, 0, 0], [5, 6, 0, 0], [7, 8, 0, 0]]
       sage: _split([1, 2, 3, 4, 5, 6, 7, 8], 1, 3)
       [[1, 2, 3, 4, 0, 0, 0, 0], [5, 6, 7, 8, 0, 0, 0, 0]]
       sage: _split([1, 2, 3, 4, 5, 6, 7, 8], 3, 1)
       [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0]]
   """
   K = 1 << (k-1)
   zero = parent(L[0])(0)
   zeroes = [zero] * K
   return [[L[i+j] for j in range(K)] + zeroes for i in range(0, K << m, K)]
Ejemplo n.º 10
0
def _split(L, m, k):
    """
   Assumes L is a list of length `2^{m+k-1}`. Splits it into
   `2^m` lists of length `2^{k-1}`, returned as a list
   of lists. Each list is zero padded up to length `2^k`.

   EXAMPLES::

       sage: from sage.rings.polynomial.convolution import _split
       sage: _split([1, 2, 3, 4, 5, 6, 7, 8], 2, 2)
       [[1, 2, 0, 0], [3, 4, 0, 0], [5, 6, 0, 0], [7, 8, 0, 0]]
       sage: _split([1, 2, 3, 4, 5, 6, 7, 8], 1, 3)
       [[1, 2, 3, 4, 0, 0, 0, 0], [5, 6, 7, 8, 0, 0, 0, 0]]
       sage: _split([1, 2, 3, 4, 5, 6, 7, 8], 3, 1)
       [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0]]
   """
    K = 1 << (k - 1)
    zero = parent(L[0])(0)
    zeroes = [zero] * K
    return [[L[i + j] for j in range(K)] + zeroes for i in range(0, K << m, K)]
Ejemplo n.º 11
0
def _convolution_fft(L1, L2):
   """
   Returns convolution of non-empty lists L1 and L2, using FFT
   algorithm. L1 and L2 may have arbitrary lengths `\geq 4`.
   Assumes all entries of L1 and L2 belong to the same ring.

   EXAMPLES::

       sage: from sage.rings.polynomial.convolution import _convolution_naive
       sage: from sage.rings.polynomial.convolution import _convolution_fft
       sage: _convolution_naive([1, 2, 3], [4, 5, 6])
       [4, 13, 28, 27, 18]
       sage: _convolution_fft([1, 2, 3], [4, 5, 6])
       [4, 13, 28, 27, 18]

   ::

       sage: for len1 in range(4, 30):
       ...      for len2 in range(4, 30):
       ...         L1 = [ZZ.random_element(100) for _ in range(len1)]
       ...         L2 = [ZZ.random_element(100) for _ in range(len2)]
       ...         assert _convolution_naive(L1, L2) == _convolution_fft(L1, L2)
   """
   R = parent(L1[0])

   # choose n so that output convolution length is 2^n
   len1 = len(L1)
   len2 = len(L2)
   outlen = len1 + len2 - 1
   n = int(ceil(log(outlen) / log(2.0)))

   # split into 2^m pieces of 2^(k-1) coefficients each, with k as small
   # as possible, subject to m <= k + 1 (so that the ring of Fourier
   # coefficients has enough roots of unity)
   m = (n >> 1) + 1
   k = n + 1 - m

   N = 1 << n
   M = 1 << m
   K = 1 << k

   # zero pad inputs up to length N
   zero = R(0)
   L1 = L1 + [zero] * (N - len(L1))
   L2 = L2 + [zero] * (N - len(L2))

   # split inputs into polynomials
   L1 = _split(L1, m, k)
   L2 = _split(L2, m, k)

   # fft each input
   _fft(L1, K, 0, m, K)
   _fft(L2, K, 0, m, K)

   # pointwise multiply
   L3 = [_negaconvolution(L1[i], L2[i], k) for i in range(M)]

   # inverse fft
   _ifft(L3, K, 0, m, K)

   # combine back into a single list
   L3 = _combine(L3, m, k)

   # normalise, and truncate to correct length
   return [R(L3[i] / M) for i in range(outlen)]
Ejemplo n.º 12
0
    def __call__(self, M):
        r"""
        Create a homomorphism in this space from M. M can be any of the
        following:

        - a Morphism of abelian varieties

        - a matrix of the appropriate size
          (i.e. 2\*self.domain().dimension() x
          2\*self.codomain().dimension()) whose entries are coercible
          into self.base_ring()

        - anything that can be coerced into self.matrix_space()

        EXAMPLES::

            sage: H = Hom(J0(11), J0(22))
            sage: phi = H(matrix(ZZ,2,4,[5..12])) ; phi
            Abelian variety morphism:
              From: Abelian variety J0(11) of dimension 1
              To:   Abelian variety J0(22) of dimension 2
            sage: phi.matrix()
            [ 5  6  7  8]
            [ 9 10 11 12]
            sage: phi.matrix().parent()
            Full MatrixSpace of 2 by 4 dense matrices over Integer Ring

        ::

            sage: H = J0(22).Hom(J0(11)*J0(11))
            sage: m1 = J0(22).degeneracy_map(11,1).matrix() ; m1
            [ 0  1]
            [-1  1]
            [-1  0]
            [ 0 -1]
            sage: m2 = J0(22).degeneracy_map(11,2).matrix() ; m2
            [ 1 -2]
            [ 0 -2]
            [ 1 -1]
            [ 0 -1]
            sage: m = m1.transpose().stack(m2.transpose()).transpose() ; m
            [ 0  1  1 -2]
            [-1  1  0 -2]
            [-1  0  1 -1]
            [ 0 -1  0 -1]
            sage: phi = H(m) ; phi
            Abelian variety morphism:
              From: Abelian variety J0(22) of dimension 2
              To:   Abelian variety J0(11) x J0(11) of dimension 2
            sage: phi.matrix()
            [ 0  1  1 -2]
            [-1  1  0 -2]
            [-1  0  1 -1]
            [ 0 -1  0 -1]
        """
        if isinstance(M, morphism.Morphism):
            if M.parent() is self:
                return M
            elif M.domain() == self.domain() and M.codomain() == self.codomain():
                M = M.matrix()
            else:
                raise ValueError, "cannot convert %s into %s" % (M, self)
        elif is_Matrix(M):
            if M.base_ring() != ZZ:
                M = M.change_ring(ZZ)
            if M.nrows() != 2*self.domain().dimension() or M.ncols() != 2*self.codomain().dimension():
                raise TypeError, "matrix has wrong dimension"
        elif self.matrix_space().has_coerce_map_from(parent(M)):
            M = self.matrix_space()(M)
        else:
            raise TypeError, "can only coerce in matrices or morphisms"
        return morphism.Morphism(self, M)
Ejemplo n.º 13
0
def _convolution_fft(L1, L2):
    """
   Returns convolution of non-empty lists L1 and L2, using FFT
   algorithm. L1 and L2 may have arbitrary lengths `\geq 4`.
   Assumes all entries of L1 and L2 belong to the same ring.

   EXAMPLES::

       sage: from sage.rings.polynomial.convolution import _convolution_naive
       sage: from sage.rings.polynomial.convolution import _convolution_fft
       sage: _convolution_naive([1, 2, 3], [4, 5, 6])
       [4, 13, 28, 27, 18]
       sage: _convolution_fft([1, 2, 3], [4, 5, 6])
       [4, 13, 28, 27, 18]

   ::

       sage: for len1 in range(4, 30):
       ...      for len2 in range(4, 30):
       ...         L1 = [ZZ.random_element(100) for _ in range(len1)]
       ...         L2 = [ZZ.random_element(100) for _ in range(len2)]
       ...         assert _convolution_naive(L1, L2) == _convolution_fft(L1, L2)
   """
    R = parent(L1[0])

    # choose n so that output convolution length is 2^n
    len1 = len(L1)
    len2 = len(L2)
    outlen = len1 + len2 - 1
    n = int(ceil(log(outlen) / log(2.0)))

    # split into 2^m pieces of 2^(k-1) coefficients each, with k as small
    # as possible, subject to m <= k + 1 (so that the ring of Fourier
    # coefficients has enough roots of unity)
    m = (n >> 1) + 1
    k = n + 1 - m

    N = 1 << n
    M = 1 << m
    K = 1 << k

    # zero pad inputs up to length N
    zero = R(0)
    L1 = L1 + [zero] * (N - len(L1))
    L2 = L2 + [zero] * (N - len(L2))

    # split inputs into polynomials
    L1 = _split(L1, m, k)
    L2 = _split(L2, m, k)

    # fft each input
    _fft(L1, K, 0, m, K)
    _fft(L2, K, 0, m, K)

    # pointwise multiply
    L3 = [_negaconvolution(L1[i], L2[i], k) for i in range(M)]

    # inverse fft
    _ifft(L3, K, 0, m, K)

    # combine back into a single list
    L3 = _combine(L3, m, k)

    # normalise, and truncate to correct length
    return [R(L3[i] / M) for i in range(outlen)]
Ejemplo n.º 14
0
    def __call__(self, M):
        r"""
        Create a homomorphism in this space from M. M can be any of the
        following:
        
        - a Morphism of abelian varieties

        - a matrix of the appropriate size
          (i.e. 2\*self.domain().dimension() x
          2\*self.codomain().dimension()) whose entries are coercible
          into self.base_ring()

        - anything that can be coerced into self.matrix_space()
        
        EXAMPLES::
        
            sage: H = Hom(J0(11), J0(22))
            sage: phi = H(matrix(ZZ,2,4,[5..12])) ; phi
            Abelian variety morphism:
              From: Abelian variety J0(11) of dimension 1
              To:   Abelian variety J0(22) of dimension 2
            sage: phi.matrix()
            [ 5  6  7  8]
            [ 9 10 11 12]
            sage: phi.matrix().parent()
            Full MatrixSpace of 2 by 4 dense matrices over Integer Ring
        
        ::
        
            sage: H = J0(22).Hom(J0(11)*J0(11))
            sage: m1 = J0(22).degeneracy_map(11,1).matrix() ; m1
            [ 0  1]
            [-1  1]
            [-1  0]
            [ 0 -1]
            sage: m2 = J0(22).degeneracy_map(11,2).matrix() ; m2
            [ 1 -2]
            [ 0 -2]
            [ 1 -1]
            [ 0 -1]
            sage: m = m1.transpose().stack(m2.transpose()).transpose() ; m
            [ 0  1  1 -2]
            [-1  1  0 -2]
            [-1  0  1 -1]
            [ 0 -1  0 -1]
            sage: phi = H(m) ; phi
            Abelian variety morphism:
              From: Abelian variety J0(22) of dimension 2
              To:   Abelian variety J0(11) x J0(11) of dimension 2
            sage: phi.matrix()
            [ 0  1  1 -2]
            [-1  1  0 -2]
            [-1  0  1 -1]
            [ 0 -1  0 -1]
        """
        if isinstance(M, morphism.Morphism):
            if M.parent() is self:
                return M
            elif M.domain() == self.domain() and M.codomain() == self.codomain(
            ):
                M = M.matrix()
            else:
                raise ValueError, "cannot convert %s into %s" % (M, self)
        elif is_Matrix(M):
            if M.base_ring() != ZZ:
                M = M.change_ring(ZZ)
            if M.nrows() != 2 * self.domain().dimension() or M.ncols(
            ) != 2 * self.codomain().dimension():
                raise TypeError, "matrix has wrong dimension"
        elif self.matrix_space().has_coerce_map_from(parent(M)):
            M = self.matrix_space()(M)
        else:
            raise TypeError, "can only coerce in matrices or morphisms"
        return morphism.Morphism(self, M)