Example #1
0
def __dimension_Sp6Z(wt):
    """
    Return the dimensions of subspaces of Siegel modular forms on $Sp(4,Z)$.

    OUTPUT
    ("Total", "Miyawaki-Type-1", "Miyawaki-Type-2 (conjectured)", "Interesting")
    Remember, Miywaki type 2 is ONLY CONJECTURED!!
    """
    if not is_even(wt):
        return (0, 0, 0, 0)
    R = PowerSeriesRing(IntegerRing(), default_prec=wt + 1, names=('x', ))
    (x, ) = R._first_ngens(1)
    R = PowerSeriesRing(IntegerRing(), default_prec=2 * wt - 1, names=('y', ))
    (y, ) = R._first_ngens(1)
    H_all = 1 / (
        (1 - x**4) * (1 - x**12)**2 * (1 - x**14) * (1 - x**18) * (1 - x**20) *
        (1 - x**30)) * (1 + x**6 + x**10 + x**12 + 3 * x**16 + 2 * x**18 +
                        2 * x**20 + 5 * x**22 + 4 * x**24 + 5 * x**26 +
                        7 * x**28 + 6 * x**30 + 9 * x**32 + 10 * x**34 +
                        10 * x**36 + 12 * x**38 + 14 * x**40 + 15 * x**42 +
                        16 * x**44 + 18 * x**46 + 18 * x**48 + 19 * x**50 +
                        21 * x**52 + 19 * x**54 + 21 * x**56 + 21 * x**58 +
                        19 * x**60 + 21 * x**62 + 19 * x**64 + 18 * x**66 +
                        18 * x**68 + 16 * x**70 + 15 * x**72 + 14 * x**74 +
                        12 * x**76 + 10 * x**78 + 10 * x**80 + 9 * x**82 +
                        6 * x**84 + 7 * x**86 + 5 * x**88 + 4 * x**90 +
                        5 * x**92 + 2 * x**94 + 2 * x**96 + 3 * x**98 +
                        x**102 + x**104 + x**108 + x**114)
    H_noncusp = 1 / (1 - x**4) / (1 - x**6) / (1 - x**10) / (1 - x**12)
    H_E = y**12 / (1 - y**4) / (1 - y**6)
    H_Miyawaki1 = H_E[wt] * H_E[2 * wt - 4]
    H_Miyawaki2 = H_E[wt - 2] * H_E[2 * wt - 2]
    a, b, c, d = H_all[wt], H_noncusp[wt], H_Miyawaki1, H_Miyawaki2
    return (a, c, d, a - b - c - d)
    def _is_even_symmetric_matrix_(self, A, R=None):
        """
        Tests if a matrix is symmetric, defined over R, and has even diagonal in R.

        INPUT:
            A -- matrix

            R -- ring

        EXAMPLES::

            sage: Q = QuadraticForm(ZZ, 2, [2,3,5])
            sage: A = Q.matrix()
            sage: A
            [ 4  3]
            [ 3 10]
            sage: Q._is_even_symmetric_matrix_(A)
            True
            sage: A[0,0] = 1
            sage: Q._is_even_symmetric_matrix_(A)
            False

        """
        if not is_Matrix(A):
            raise TypeError("A is not a matrix.")

        ring_coerce_test = True
        if R == None:            ## This allows us to omit the ring from the variables, and take it from the matrix
            R = A.base_ring()
            ring_coerce_test = False

        if not isinstance(R, Ring):
            raise TypeError("R is not a ring.")

        if not A.is_square():
            return False

        ## Test that the matrix is symmetric
        n = A.nrows()
        for i in range(n):
            for j in range(i+1, n):
                if A[i,j] != A[j,i]:
                    return False

        ## Test that all entries coerce to R
        if not ((A.base_ring() == R) or (ring_coerce_test == True)):
            try:
                for i in range(n):
                    for j in range(i, n):
                        x = R(A[i,j])
            except Exception:
                return False

        ## Test that the diagonal is even (if 1/2 isn't in R)
        if not R(2).is_unit():
            for i in range(n):
                if not is_even(R(A[i,i])):
                    return False

        return True
        def apply_simple_reflection_right(self, i):
            r"""
            Implements :meth:`CoxeterGroups.ElementMethods.apply_simple_reflection`.

            EXAMPLES::

                sage: D5 = FiniteCoxeterGroups().example(5)
                sage: [i^2 for i in D5]  # indirect doctest
                [(), (), (), (1, 2, 1, 2), (2, 1, 2, 1), (), (), (2, 1), (1, 2), ()]
                sage: [i^5 for i in D5]  # indirect doctest
                [(), (1,), (2,), (), (), (1, 2, 1), (2, 1, 2), (), (), (1, 2, 1, 2, 1)]
            """
            from copy import copy
            reduced_word = copy(self.value)
            n = self.parent().n
            if len(reduced_word) == n:
                if (i == 1 and is_odd(n)) or (i == 2 and is_even(n)):
                    return self.parent()(reduced_word[:-1])
                else:
                    return self.parent()(reduced_word[1:])
            elif (len(reduced_word) == n - 1 and
                  (not self.has_descent(i))) and (reduced_word[0] == 2):
                return self.parent()((1, ) + reduced_word)
            else:
                if self.has_descent(i):
                    return self.parent()(reduced_word[:-1])
                else:
                    return self.parent()(reduced_word + (i, ))
Example #4
0
def _dimension_Sp4Z( wt_range):
    """
    Return the dimensions of subspaces of Siegel modular forms on $Sp(4,Z)$.

    OUTPUT
        ("Total", "Eisenstein", "Klingen", "Maass", "Interesting")
    """
    headers = ['Total', 'Eisenstein', 'Klingen', 'Maass', 'Interesting']

    R = PowerSeriesRing( IntegerRing(), default_prec = wt_range[-1] + 1, names = ('x',))
    (x,) = R._first_ngens(1)
    H_all = 1 / (1 - x ** 4) / (1 - x ** 6) / (1 - x ** 10) / (1 - x ** 12)
    H_Kl = x ** 12 / (1 - x ** 4) / (1 - x ** 6)
    H_MS = (x ** 10 + x ** 12) / (1 - x ** 4) / (1 - x ** 6)

    dct = dict( (k,
                 { 'Total': H_all[k], 
                   'Eisenstein': 1 if k >= 4 else 0,
                   'Klingen': H_Kl[k],
                   'Maass': H_MS[k],
                   'Interesting': H_all[k]-(1 if k >= 4 else 0)-H_Kl[k]-H_MS[k]
                   }
                 if is_even(k) else
                 { 'Total': H_all[k-35], 
                   'Eisenstein': 0,
                   'Klingen': 0,
                   'Maass': 0,
                   'Interesting': H_all[k-35]
                   }
                 ) for k in wt_range)

    return headers, dct
Example #5
0
def __dimension_Sp6Z(wt):
    """
    Return the dimensions of subspaces of Siegel modular forms on $Sp(6,Z)$.

    OUTPUT
    ("Total", "Miyawaki-Type-1", "Miyawaki-Type-2 (conjectured)", "Interesting")
    Remember, Miywaki type 2 is ONLY CONJECTURED!!
    """
    if not is_even(wt):
        return (0, 0, 0, 0)
    R = PowerSeriesRing(IntegerRing(), default_prec=wt + 1, names=('x',))
    (x,) = R._first_ngens(1)
    S = PowerSeriesRing(IntegerRing(), default_prec=max(2 * wt - 1,1), names=('y',))
    (y,) = S._first_ngens(1)
    H_all = 1 / ((1 - x ** 4) * (1 - x ** 12) ** 2 * (1 - x ** 14) * (1 - x ** 18) *
                (1 - x ** 20) * (1 - x ** 30)) * (
                    1 + x ** 6 + x ** 10 + x ** 12 + 3 * x ** 16 + 2 * x ** 18 + 2 * x ** 20 +
                    5 * x ** 22 + 4 * x ** 24 + 5 * x ** 26 + 7 * x ** 28 + 6 * x ** 30 + 9 * x ** 32 +
                    10 * x ** 34 + 10 * x ** 36 + 12 * x ** 38 + 14 * x ** 40 + 15 * x ** 42 + 16 * x ** 44 +
                    18 * x ** 46 + 18 * x ** 48 + 19 * x ** 50 + 21 * x ** 52 + 19 * x ** 54 + 21 * x ** 56 +
                    21 * x ** 58 + 19 * x ** 60 + 21 * x ** 62 + 19 * x ** 64 + 18 * x ** 66 + 18 * x ** 68 +
                    16 * x ** 70 + 15 * x ** 72 + 14 * x ** 74 + 12 * x ** 76 + 10 * x ** 78 + 10 * x ** 80 +
                    9 * x ** 82 + 6 * x ** 84 + 7 * x ** 86 + 5 * x ** 88 + 4 * x ** 90 + 5 * x ** 92 +
                    2 * x ** 94 + 2 * x ** 96 + 3 * x ** 98 + x ** 102 + x ** 104 + x ** 108 + x ** 114)

    H_noncusp = 1 / (1 - x ** 4) / (1 - x ** 6) / (1 - x ** 10) / (1 - x ** 12)
    H_E = y ** 12 / (1 - y ** 4) / (1 - y ** 6)
    H_Miyawaki1 = H_E[wt] * H_E[2 * wt - 4]
    H_Miyawaki2 = H_E[wt - 2] * H_E[2 * wt - 2]
    a, b, c, d = H_all[wt], H_noncusp[wt], H_Miyawaki1, H_Miyawaki2
    return (a, c, d, a - b - c - d)
Example #6
0
def _dimension_Sp4Z(wt_range):
    """
    Return the dimensions of subspaces of Siegel modular forms on $Sp(4,Z)$.

    OUTPUT
        ("Total", "Eisenstein", "Klingen", "Maass", "Interesting")
    """
    headers = ['Total', 'Eisenstein', 'Klingen', 'Maass', 'Interesting']

    R = PowerSeriesRing(IntegerRing(),
                        default_prec=wt_range[-1] + 1,
                        names=('x', ))
    (x, ) = R._first_ngens(1)
    H_all = 1 / (1 - x**4) / (1 - x**6) / (1 - x**10) / (1 - x**12)
    H_Kl = x**12 / (1 - x**4) / (1 - x**6)
    H_MS = (x**10 + x**12) / (1 - x**4) / (1 - x**6)

    dct = dict(
        (k, {
            'Total': H_all[k],
            'Eisenstein': 1 if k >= 4 else 0,
            'Klingen': H_Kl[k],
            'Maass': H_MS[k],
            'Interesting': H_all[k] - (1 if k >= 4 else 0) - H_Kl[k] - H_MS[k]
        } if is_even(k) else {
            'Total': H_all[k - 35],
            'Eisenstein': 0,
            'Klingen': 0,
            'Maass': 0,
            'Interesting': H_all[k - 35]
        }) for k in wt_range)

    return headers, dct
Example #7
0
        def apply_simple_reflection_right(self, i):
            r"""
            Implements :meth:`CoxeterGroups.ElementMethods.apply_simple_reflection`.

            EXEMPLES::

                sage: D5 = FiniteCoxeterGroups().example(5)
                sage: [i^2 for i in D5]
                [(), (), (1, 2, 1, 2), (), (2, 1), (), (), (2, 1, 2, 1), (), (1, 2)]
                sage: [i^5 for i in D5]
                [(), (1,), (), (1, 2, 1), (), (1, 2, 1, 2, 1), (2,), (), (2, 1, 2), ()]
            """
            from copy import copy
            reduced_word = copy(self.value)
            n = self.parent().n
            if len(reduced_word) == n:
                if (i == 1 and is_odd(n)) or (i == 2 and is_even(n)):
                    return self.parent()(reduced_word[:-1])
                else:
                    return self.parent()(reduced_word[1:])
            elif (len(reduced_word) == n-1 and (not self.has_descent(i))) and (reduced_word[0] == 2):
                return self.parent()((1,)+reduced_word)
            else:
                if self.has_descent(i):
                    return self.parent()(reduced_word[:-1])
                else:
                    return self.parent()(reduced_word+(i,))
Example #8
0
def hadamard_matrix(n):
    """
    Tries to construct a Hadamard matrix using a combination of Paley
    and Sylvester constructions.

    EXAMPLES::

        sage: hadamard_matrix(12).det()
        2985984
        sage: 12^6
        2985984
        sage: hadamard_matrix(2)
        [ 1  1]
        [ 1 -1]
        sage: hadamard_matrix(8)
        [ 1  1  1  1  1  1  1  1]
        [ 1 -1  1 -1  1 -1  1 -1]
        [ 1  1 -1 -1  1  1 -1 -1]
        [ 1 -1 -1  1  1 -1 -1  1]
        [ 1  1  1  1 -1 -1 -1 -1]
        [ 1 -1  1 -1 -1  1 -1  1]
        [ 1  1 -1 -1 -1 -1  1  1]
        [ 1 -1 -1  1 -1  1  1 -1]
        sage: hadamard_matrix(8).det() == 8^4
        True
    """
    if not (n % 4 == 0) and (n != 2):
        raise ValueError("The Hadamard matrix of order %s does not exist" % n)
    if n == 2:
        return matrix([[1, 1], [1, -1]])
    if is_even(n):
        N = Integer(n / 2)
    elif n == 1:
        return matrix([1])
    if is_prime(N - 1) and (N - 1) % 4 == 1:
        return hadamard_matrix_paleyII(n)
    elif n == 4 or n % 8 == 0:
        had = hadamard_matrix(Integer(n / 2))
        chad1 = matrix([list(r) + list(r) for r in had.rows()])
        mhad = (-1) * had
        R = len(had.rows())
        chad2 = matrix(
            [list(had.rows()[i]) + list(mhad.rows()[i]) for i in range(R)])
        return chad1.stack(chad2)
    elif is_prime(N - 1) and (N - 1) % 4 == 3:
        return hadamard_matrix_paleyI(n)
    else:
        raise ValueError(
            "The Hadamard matrix of order %s is not yet implemented." % n)
Example #9
0
def hadamard_matrix(n):
    """
    Tries to construct a Hadamard matrix using a combination of Paley
    and Sylvester constructions.

    EXAMPLES::

        sage: hadamard_matrix(12).det()
        2985984
        sage: 12^6
        2985984
        sage: hadamard_matrix(2)
        [ 1  1]
        [ 1 -1]
        sage: hadamard_matrix(8)
        [ 1  1  1  1  1  1  1  1]
        [ 1 -1  1 -1  1 -1  1 -1]
        [ 1  1 -1 -1  1  1 -1 -1]
        [ 1 -1 -1  1  1 -1 -1  1]
        [ 1  1  1  1 -1 -1 -1 -1]
        [ 1 -1  1 -1 -1  1 -1  1]
        [ 1  1 -1 -1 -1 -1  1  1]
        [ 1 -1 -1  1 -1  1  1 -1]
        sage: hadamard_matrix(8).det() == 8^4
        True
    """
    if not(n % 4 == 0) and (n != 2):
        raise ValueError("The Hadamard matrix of order %s does not exist" % n)
    if n == 2:
        return matrix([[1, 1], [1, -1]])
    if is_even(n):
        N = Integer(n / 2)
    elif n == 1:
        return matrix([1])
    if is_prime(N - 1) and (N - 1) % 4 == 1:
        return hadamard_matrix_paleyII(n)
    elif n == 4 or n % 8 == 0:
        had = hadamard_matrix(Integer(n / 2))
        chad1 = matrix([list(r) + list(r) for r in had.rows()])
        mhad = (-1) * had
        R = len(had.rows())
        chad2 = matrix([list(had.rows()[i]) + list(mhad.rows()[i])
                       for i in range(R)])
        return chad1.stack(chad2)
    elif is_prime(N - 1) and (N - 1) % 4 == 3:
        return hadamard_matrix_paleyI(n)
    else:
        raise ValueError("The Hadamard matrix of order %s is not yet implemented." % n)
Example #10
0
def _dimension_Gamma0_4_psi_4(wt):
    """
    Return the dimensions of subspaces of Siegel modular forms
    on $Gamma_0(4)$
    with character $\psi_4$.

    OUTPUT
        ( "Total")

    REMARK
        The formula for odd weights is unknown or not obvious from the paper.
    """
    R = PowerSeriesRing(IntegerRing(), default_prec=wt + 1, names=("x",))
    (x,) = R._first_ngens(1)
    H_all_even = (x ** 12 + x ** 14) / (1 - x ** 2) ** 3 / (1 - x ** 6)
    if is_even(wt):
        return (H_all_even[wt],)
    else:
        raise NotImplementedError("Dimensions of $M_{k}(\Gamma_0(4), \psi_4)$ for odd $k$ not implemented")
Example #11
0
    def is_bent(self):
        r"""
        Return ``True`` if this S-Box is bent, i.e. its nonlinearity
        is equal to `2^{m-1} - 2^{m/2 - 1}` where `m` is the input size
        of the S-Box.

        EXAMPLES::

            sage: from sage.crypto.sbox import SBox
            sage: R.<x> = GF(2**2, 'a')[]
            sage: base = R.base_ring()
            sage: a = base.gen()
            sage: G = a * x^2 + 1
            sage: S = SBox([G(x * y**(14)) for x in sorted(base) for y in sorted(base)])
            sage: S.is_bent()
            True
            sage: S.nonlinearity()
            6
            sage: S.linear_approximation_matrix()
            [ 8 -2  2 -2]
            [ 0 -2  2 -2]
            [ 0 -2  2 -2]
            [ 0 -2  2 -2]
            [ 0 -2  2 -2]
            [ 0 -2 -2  2]
            [ 0  2  2  2]
            [ 0  2 -2 -2]
            [ 0 -2  2 -2]
            [ 0  2 -2 -2]
            [ 0 -2 -2  2]
            [ 0  2  2  2]
            [ 0 -2  2 -2]
            [ 0  2  2  2]
            [ 0  2 -2 -2]
            [ 0 -2 -2  2]
        """
        m = self.m
        n = self.n

        if not is_even(m) or n > m//2:
            return False

        return self.nonlinearity() == 2**(m-1) - 2**(m//2 - 1)
Example #12
0
    def is_bent(self):
        r"""
        Return ``True`` if this S-Box is bent, i.e. its nonlinearity
        is equal to `2^{m-1} - 2^{m/2 - 1}` where `m` is the input size
        of the S-Box.

        EXAMPLES::

            sage: from sage.crypto.sbox import SBox
            sage: R.<x> = GF(2**2, 'a')[]
            sage: base = R.base_ring()
            sage: a = base.gen()
            sage: G = a * x^2 + 1
            sage: S = SBox([G(x * y**(14)) for x in sorted(base) for y in sorted(base)])
            sage: S.is_bent()
            True
            sage: S.nonlinearity()
            6
            sage: S.linear_approximation_matrix()
            [ 8 -2  2 -2]
            [ 0 -2  2 -2]
            [ 0 -2  2 -2]
            [ 0 -2  2 -2]
            [ 0 -2  2 -2]
            [ 0 -2 -2  2]
            [ 0  2  2  2]
            [ 0  2 -2 -2]
            [ 0 -2  2 -2]
            [ 0  2 -2 -2]
            [ 0 -2 -2  2]
            [ 0  2  2  2]
            [ 0 -2  2 -2]
            [ 0  2  2  2]
            [ 0  2 -2 -2]
            [ 0 -2 -2  2]
        """
        m = self.m
        n = self.n

        if not is_even(m) or n > m//2:
            return False

        return self.nonlinearity() == 2**(m-1) - 2**(m//2 - 1)
Example #13
0
def _dimension_Gamma0_3_psi_3(wt):
    """
    Return the dimensions of the space of Siegel modular forms
    on $Gamma_0(3)$ with character $\psi_3$.

    OUTPUT
        ( "Total")

    REMARK
        Not completely implemented
    """
    R = PowerSeriesRing(IntegerRing(), default_prec=wt + 1, names=('x', ))
    (x, ) = R._first_ngens(1)
    B = 1 / (1 - x**1) / (1 - x**3) / (1 - x**4) / (1 - x**3)
    H_all_odd = B
    H_all_even = B * x**14
    if is_even(wt):
        return (H_all_even[wt], )
    else:
        return (H_all_odd[wt], )
Example #14
0
def _dimension_Gamma0_3_psi_3(wt):
    """
    Return the dimensions of the space of Siegel modular forms
    on $Gamma_0(3)$ with character $\psi_3$.

    OUTPUT
        ( "Total")

    REMARK
        Not completely implemented
    """
    R = PowerSeriesRing(IntegerRing(), default_prec=wt + 1, names=("x",))
    (x,) = R._first_ngens(1)
    B = 1 / (1 - x ** 1) / (1 - x ** 3) / (1 - x ** 4) / (1 - x ** 3)
    H_all_odd = B
    H_all_even = B * x ** 14
    if is_even(wt):
        return (H_all_even[wt],)
    else:
        return (H_all_odd[wt],)
Example #15
0
def _dimension_Gamma0_4_psi_4(wt):
    """
    Return the dimensions of subspaces of Siegel modular forms
    on $Gamma_0(4)$
    with character $\psi_4$.

    OUTPUT
        ( "Total")

    REMARK
        The formula for odd weights is unknown or not obvious from the paper.
    """
    R = PowerSeriesRing(IntegerRing(), default_prec=wt + 1, names=('x', ))
    (x, ) = R._first_ngens(1)
    H_all_even = (x**12 + x**14) / (1 - x**2)**3 / (1 - x**6)
    if is_even(wt):
        return (H_all_even[wt], )
    else:
        raise NotImplementedError(
            'Dimensions of $M_{k}(\Gamma_0(4), \psi_4)$ for odd $k$ not implemented'
        )
Example #16
0
    def is_almost_bent(self):
        r"""
        Return ``True`` if this S-Box is an almost bent (AB) function.

        An `m \times m` S-Box `S`, for `m` odd, is called almost bent if its
        nonlinearity is equal to `2^{m-1} - 2^{(m-1)/2}`.

        EXAMPLES::

            sage: S = mq.SBox([0,1,3,6,7,4,5,2])
            sage: S.is_almost_bent()
            True
        """
        if self.m != self.n:
            raise TypeError("almost bent function only exists for self.m == self.n")

        m = self.m

        if is_even(m):
            return False

        return self.nonlinearity() == 2**(m-1) - 2**((m-1)/2)
Example #17
0
    def is_almost_bent(self):
        r"""
        Return ``True`` if this S-Box is an almost bent (AB) function.

        An `m \times m` S-Box `S`, for `m` odd, is called almost bent if its
        nonlinearity is equal to `2^{m-1} - 2^{(m-1)/2}`.

        EXAMPLES::

            sage: S = mq.SBox([0,1,3,6,7,4,5,2])
            sage: S.is_almost_bent()
            True
        """
        if self.m != self.n:
            raise TypeError("almost bent function only exists for self.m == self.n")

        m = self.m

        if is_even(m):
            return False

        return self.nonlinearity() == 2**(m-1) - 2**((m-1)//2)
Example #18
0
def serre_cartan_mono_to_string(mono, latex=False, p=2):
    r"""
    String representation of element of the Serre-Cartan basis.

    This is used by the _repr_ and _latex_ methods.

    INPUT:

    - ``mono`` - tuple of positive integers (a,b,c,...)  when `p=2`,
      or tuple (e0, n1, e1, n2, ...) when `p>2`, where each ei is 0 or
      1, and each ni is positive

    - ``latex`` - boolean (optional, default False), if true, output
      LaTeX string

    - ``p`` - positive prime number (optional, default 2)

    OUTPUT: ``rep`` - string

    This returns a string like ``Sq^{a} Sq^{b} Sq^{c} ...`` when
    `p=2`, or a string like
    ``\beta^{e0} P^{n1} \beta^{e1} P^{n2} ...`` when `p`
    is odd.

    EXAMPLES::

        sage: from sage.algebras.steenrod.steenrod_algebra_misc import serre_cartan_mono_to_string
        sage: serre_cartan_mono_to_string((1,2,3,4))
        'Sq^{1} Sq^{2} Sq^{3} Sq^{4}'
        sage: serre_cartan_mono_to_string((1,2,3,4),latex=True)
        '\\text{Sq}^{1} \\text{Sq}^{2} \\text{Sq}^{3} \\text{Sq}^{4}'
        sage: serre_cartan_mono_to_string((0,5,1,1,0), p=3)
        'P^{5} beta P^{1}'
        sage: serre_cartan_mono_to_string((0,5,1,1,0), p=3, latex=True)
        '\\mathcal{P}^{5} \\beta \\mathcal{P}^{1}'

    The empty tuple represents the unit element 1::

        sage: serre_cartan_mono_to_string(())
        '1'
        sage: serre_cartan_mono_to_string((), p=7)
        '1'
    """
    if latex:
        if p == 2:
            sq = "\\text{Sq}"
            P = "\\text{Sq}"
        else:
            P = "\\mathcal{P}"
    else:
        if p == 2:
            sq = "Sq"
            P = "Sq"
        else:
            P = "P"
    if len(mono) == 0 or mono == (0,):
        return "1"
    else:
        if p == 2:
            string = ""
            for n in mono:
                string = string + sq + "^{" + str(n) + "} "
        else:
            string = ""
            index = 0
            for n in mono:
                from sage.misc.functional import is_even
                if is_even(index):
                    if n == 1:
                        if latex:
                            string = string + "\\beta "
                        else:
                            string = string + "beta "
                else:
                    string = string + P + "^{" + str(n) + "} "
                index += 1
        return string.strip(" ")
Example #19
0
    def MatchingComplex(self, n):
        """
        The matching complex of graphs on n vertices.

        Fix an integer `n>0` and consider a set `V` of `n` vertices.
        A 'partial matching' on `V` is a graph formed by edges so that
        each vertex is in at most one edge.  If `G` is a partial
        matching, then so is any graph obtained by deleting edges from
        `G`.  Thus the set of all partial matchings on `n` vertices,
        viewed as a set of subsets of the `n` choose 2 possible edges,
        is closed under taking subsets, and thus forms a simplicial
        complex called the 'matching complex'.  This function produces
        that simplicial complex.

        INPUT:

        -  ``n`` - positive integer.
    
        See Dumas et al. for information on computing its homology by
        computer, and see Wachs for an expository article about the
        theory.  For example, the homology of these complexes seems to
        have only mod 3 torsion, and this has been proved for the
        bottom non-vanishing homology group for the matching complex
        `M_n`.

        EXAMPLES::

            sage: M = simplicial_complexes.MatchingComplex(7)
            sage: H = M.homology()
            sage: H
            {0: 0, 1: C3, 2: Z^20}
            sage: H[2].ngens()
            20
            sage: simplicial_complexes.MatchingComplex(8).homology(2)  # long time (a few seconds)
            Z^132

        REFERENCES:

        - Dumas, Heckenbach, Saunders, Welker, "Computing simplicial
          homology based on efficient Smith normal form algorithms,"
          in "Algebra, geometry, and software systems" (2003),
          177-206.

        - Wachs, "Topology of Matching, Chessboard and General Bounded
          Degree Graph Complexes" (Algebra Universalis Special Issue
          in Memory of Gian-Carlo Rota, Algebra Universalis, 49 (2003)
          345-385)
        """
        G_vertices = Set(range(1, n + 1))
        E_list = []
        for w in G_vertices:
            for v in range(1, w):
                E_list.append((v, w))
        facets = []
        if is_even(n):
            half = int(n / 2)
            half_n_sets = list(G_vertices.subsets(size=half))
        else:
            half = int((n - 1) / 2)
            half_n_sets = list(G_vertices.subsets(size=half))
        for X in half_n_sets:
            Xcomp = G_vertices.difference(X)
            if is_even(n):
                if 1 in X:
                    A = X
                    B = Xcomp
                else:
                    A = Xcomp
                    B = X
                for M in matching(A, B):
                    facet = []
                    for pair in M:
                        facet.append(tuple(sorted(pair)))
                        facets.append(facet)
            else:
                for w in Xcomp:
                    if 1 in X or (w == 1 and 2 in X):
                        A = X
                        B = Xcomp.difference([w])
                    else:
                        B = X
                        A = Xcomp.difference([w])
                    for M in matching(A, B):
                        facet = []
                        for pair in M:
                            facet.append(tuple(sorted(pair)))
                        facets.append(facet)
        return SimplicialComplex(E_list, facets)
Example #20
0
    def MatchingComplex(self, n):
        """
        The matching complex of graphs on n vertices.

        Fix an integer `n>0` and consider a set `V` of `n` vertices.
        A 'partial matching' on `V` is a graph formed by edges so that
        each vertex is in at most one edge.  If `G` is a partial
        matching, then so is any graph obtained by deleting edges from
        `G`.  Thus the set of all partial matchings on `n` vertices,
        viewed as a set of subsets of the `n` choose 2 possible edges,
        is closed under taking subsets, and thus forms a simplicial
        complex called the 'matching complex'.  This function produces
        that simplicial complex.

        INPUT:

        -  ``n`` - positive integer.
    
        See Dumas et al. for information on computing its homology by
        computer, and see Wachs for an expository article about the
        theory.  For example, the homology of these complexes seems to
        have only mod 3 torsion, and this has been proved for the
        bottom non-vanishing homology group for the matching complex
        `M_n`.

        EXAMPLES::

            sage: M = simplicial_complexes.MatchingComplex(7)
            sage: H = M.homology()
            sage: H
            {0: 0, 1: C3, 2: Z^20}
            sage: H[2].ngens()
            20
            sage: simplicial_complexes.MatchingComplex(8).homology(2)  # long time (a few seconds)
            Z^132

        REFERENCES:

        - Dumas, Heckenbach, Saunders, Welker, "Computing simplicial
          homology based on efficient Smith normal form algorithms,"
          in "Algebra, geometry, and software systems" (2003),
          177-206.

        - Wachs, "Topology of Matching, Chessboard and General Bounded
          Degree Graph Complexes" (Algebra Universalis Special Issue
          in Memory of Gian-Carlo Rota, Algebra Universalis, 49 (2003)
          345-385)
        """
        G_vertices = Set(range(1,n+1))
        E_list = []
        for w in G_vertices:
            for v in range(1,w):
                E_list.append((v,w))
        facets = []
        if is_even(n):
            half = int(n/2)
            half_n_sets = list(G_vertices.subsets(size=half))
        else:
            half = int((n-1)/2)
            half_n_sets = list(G_vertices.subsets(size=half))
        for X in half_n_sets:
            Xcomp = G_vertices.difference(X)
            if is_even(n):
                if 1 in X:
                    A = X
                    B = Xcomp
                else:
                    A = Xcomp
                    B = X
                for M in matching(A, B):
                    facet = []
                    for pair in M:
                        facet.append(tuple(sorted(pair)))
                        facets.append(facet)
            else:
                for w in Xcomp:
                    if 1 in X or (w == 1 and 2 in X):
                        A = X
                        B = Xcomp.difference([w])
                    else:
                        B = X
                        A = Xcomp.difference([w])
                    for M in matching(A, B):
                        facet = []
                        for pair in M:
                            facet.append(tuple(sorted(pair)))
                        facets.append(facet)
        return SimplicialComplex(E_list, facets)
Example #21
0
    def product_on_basis(self, w1, w2):
        r"""
        Return the product of two indices within the algebra.

        EXAMPLES::

            sage: A.<x,y,z> = GradedCommutativeAlgebra(QQ, degrees=(4,8,2), max_degree=10)
            sage: z*x
            x*z
            sage: x^3
            0
            sage: 5*z + 4*z*x
            5*z + 4*x*z

        ::

            sage: A.<x,y,z> = GradedCommutativeAlgebra(QQ, degrees=(1,2,3), max_degree=5)
            sage: 2*x*y
            2*x*y
            sage: x^2
            0
            sage: x*z
            x*z
            sage: z*x
            -x*z
            sage: x*y*z
            0

        TESTS::

            sage: A.<x,y,z> = GradedCommutativeAlgebra(QQ, degrees=(4,8,2), max_degree=10)
            sage: weighted_vectors = A._weighted_vectors
            sage: w1 = A._weighted_vectors([1,0,1])
            sage: w2 = A._weighted_vectors([0,0,0])
            sage: A.product_on_basis(w1, w2)
            x*z

        ::

            sage: A.<x,y,z> = GradedCommutativeAlgebra(QQ, degrees=(1,2,3), max_degree=5)
            sage: weighted_vectors = A._weighted_vectors
            sage: w1 = A._weighted_vectors([1,0,0])
            sage: w2 = A._weighted_vectors([0,0,1])
            sage: A.product_on_basis(w1, w2)
            x*z
            sage: A.product_on_basis(w2, w1)
            -x*z

        ::

            sage: A.<x,y,z> = GradedCommutativeAlgebra(QQ, degrees=(1,2,3), max_degree=10)
            sage: weighted_vectors = A._weighted_vectors
            sage: w1 = A._weighted_vectors([1,1,0])
            sage: w2 = A._weighted_vectors([0,1,1])
            sage: A.product_on_basis(w1, w2)
            x*y^2*z
            sage: A.product_on_basis(w2, w1)
            -x*y^2*z

        """
        grading = self._weighted_vectors.grading
        deg_left = grading(w1)
        deg_right = grading(w2)
        deg_tot = deg_left + deg_right
        if deg_tot > self._max_deg:
            return self.zero()
        w_tot = self._weighted_vectors([sum(w) for w in zip(w1, w2)])
        if not self._valid_index(w_tot):
            return self.zero()
        # determine sign
        n = self.__ngens
        c = 0
        for p, i, d in zip(reversed(range(n)), reversed(w1),
                           reversed(self._degrees)):
            if is_even(d) or i == 0:
                continue
            for q, j, b in zip(range(n), w2, self._degrees):
                if q == p:
                    break
                if j == 0 or is_even(b):
                    continue
                c += 1
        return (-1)**c * self.monomial(w_tot)
def serre_cartan_mono_to_string(mono, latex=False, generic=False):
    r"""
    String representation of element of the Serre-Cartan basis.

    This is used by the _repr_ and _latex_ methods.

    INPUT:

    - ``mono`` - tuple of positive integers (a,b,c,...)  when `generic=False`,
      or tuple (e0, n1, e1, n2, ...) when `generic=True`, where each ei is 0 or
      1, and each ni is positive

    - ``latex`` - boolean (optional, default False), if true, output
      LaTeX string

    - ``generic`` - whether to format generically, or for the prime 2 (default)

    OUTPUT: ``rep`` - string

    This returns a string like ``Sq^{a} Sq^{b} Sq^{c} ...`` when
    `generic=False`, or a string like
    ``\beta^{e0} P^{n1} \beta^{e1} P^{n2} ...`` when `generic=True`.
    is odd.


    EXAMPLES::

        sage: from sage.algebras.steenrod.steenrod_algebra_misc import serre_cartan_mono_to_string
        sage: serre_cartan_mono_to_string((1,2,3,4))
        'Sq^{1} Sq^{2} Sq^{3} Sq^{4}'
        sage: serre_cartan_mono_to_string((1,2,3,4),latex=True)
        '\\text{Sq}^{1} \\text{Sq}^{2} \\text{Sq}^{3} \\text{Sq}^{4}'
        sage: serre_cartan_mono_to_string((0,5,1,1,0), generic=True)
        'P^{5} beta P^{1}'
        sage: serre_cartan_mono_to_string((0,5,1,1,0), generic=True, latex=True)
        '\\mathcal{P}^{5} \\beta \\mathcal{P}^{1}'

    The empty tuple represents the unit element 1::

        sage: serre_cartan_mono_to_string(())
        '1'
        sage: serre_cartan_mono_to_string((), generic=True)
        '1'
    """
    if latex:
        if not generic:
            sq = "\\text{Sq}"
            P = "\\text{Sq}"
        else:
            P = "\\mathcal{P}"
    else:
        if not generic:
            sq = "Sq"
            P = "Sq"
        else:
            P = "P"
    if len(mono) == 0 or mono == (0, ):
        return "1"
    else:
        if not generic:
            string = ""
            for n in mono:
                string = string + sq + "^{" + str(n) + "} "
        else:
            string = ""
            index = 0
            for n in mono:
                from sage.misc.functional import is_even
                if is_even(index):
                    if n == 1:
                        if latex:
                            string = string + "\\beta "
                        else:
                            string = string + "beta "
                else:
                    string = string + P + "^{" + str(n) + "} "
                index += 1
        return string.strip(" ")