Esempio n. 1
0
    def __init__(self, q, name="a", modulus=None, repr="poly", cache=False):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: k.<a> = GF(2^3)
            sage: j.<b> = GF(3^4)
            sage: k == j
            False

            sage: GF(2^3,'a') == copy(GF(2^3,'a'))
            True
            sage: TestSuite(GF(2^3, 'a')).run()
        """
        self._kwargs = {}

        if repr not in ['int', 'log', 'poly']:
            raise ValueError, "Unknown representation %s" % repr

        q = Integer(q)
        if q < 2:
            raise ValueError, "q  must be a prime power"
        F = q.factor()
        if len(F) > 1:
            raise ValueError, "q must be a prime power"
        p = F[0][0]
        k = F[0][1]

        if q >= 1 << 16:
            raise ValueError, "q must be < 2^16"

        import constructor
        FiniteField.__init__(self,
                             constructor.FiniteField(p),
                             name,
                             normalize=False)

        self._kwargs['repr'] = repr
        self._kwargs['cache'] = cache

        if modulus is None or modulus == 'conway':
            if k == 1:
                modulus = 'random'  # this will use the gfq_factory_pk function.
            elif ConwayPolynomials().has_polynomial(p, k):
                from sage.rings.finite_rings.conway_polynomials import conway_polynomial
                modulus = conway_polynomial(p, k)
            elif modulus is None:
                modulus = 'random'
            else:
                raise ValueError, "Conway polynomial not found"

        from sage.rings.polynomial.all import is_Polynomial
        if is_Polynomial(modulus):
            modulus = modulus.list()

        self._cache = Cache_givaro(self, p, k, modulus, repr, cache)
Esempio n. 2
0
    def __init__(self, q, name="a",  modulus=None, repr="poly", cache=False):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: k.<a> = GF(2^3)
            sage: j.<b> = GF(3^4)
            sage: k == j
            False

            sage: GF(2^3,'a') == copy(GF(2^3,'a'))
            True
            sage: TestSuite(GF(2^3, 'a')).run()
        """
        self._kwargs = {}

        if repr not in ['int', 'log', 'poly']:
            raise ValueError("Unknown representation %s"%repr)

        q = Integer(q)
        if q < 2:
            raise ValueError("q  must be a prime power")
        F = q.factor()
        if len(F) > 1:
            raise ValueError("q must be a prime power")
        p = F[0][0]
        k = F[0][1]

        if q >= 1<<16:
            raise ValueError("q must be < 2^16")

        import constructor
        FiniteField.__init__(self, constructor.FiniteField(p), name, normalize=False)

        self._kwargs['repr'] = repr
        self._kwargs['cache'] = cache

        if modulus is None or modulus == 'conway':
            if k == 1:
                modulus = 'random' # this will use the gfq_factory_pk function.
            elif ConwayPolynomials().has_polynomial(p, k):
                from sage.rings.finite_rings.conway_polynomials import conway_polynomial
                modulus = conway_polynomial(p, k)
            elif modulus is None:
                modulus = 'random'
            else:
                raise ValueError("Conway polynomial not found")

        from sage.rings.polynomial.all import is_Polynomial
        if is_Polynomial(modulus):
            modulus = modulus.list()

        self._cache = Cache_givaro(self, p, k, modulus, repr, cache)
Esempio n. 3
0
def q3_minus_one_matrix(K):
    r"""
    Return a companion matrix in `GL(3, K)` whose multiplicative order is `q^3 - 1`.

    This function is used in :func:`HughesPlane`

    EXAMPLES::

        sage: from sage.combinat.designs.block_design import q3_minus_one_matrix
        sage: m = q3_minus_one_matrix(GF(3))
        sage: m.multiplicative_order() == 3**3 - 1
        True

        sage: m = q3_minus_one_matrix(GF(4,'a'))
        sage: m.multiplicative_order() == 4**3 - 1
        True

        sage: m = q3_minus_one_matrix(GF(5))
        sage: m.multiplicative_order() == 5**3 - 1
        True

        sage: m = q3_minus_one_matrix(GF(9,'a'))
        sage: m.multiplicative_order() == 9**3 - 1
        True
    """
    q = K.cardinality()
    M = MatrixSpace(K, 3)

    if q.is_prime():
        from sage.rings.finite_rings.conway_polynomials import conway_polynomial
        try:
            a, b, c, _ = conway_polynomial(q, 3)
        except RuntimeError:  # the polynomial is not in the database
            pass
        else:
            return M([0, 0, -a, 1, 0, -b, 0, 1, -c])

    m = M()
    m[1, 0] = m[2, 1] = K.one()
    while True:
        m[0, 2] = K._random_nonzero_element()
        m[1, 2] = K.random_element()
        m[2, 2] = K.random_element()
        if m.multiplicative_order() == q**3 - 1:
            return m
Esempio n. 4
0
def q3_minus_one_matrix(K):
    r"""
    Return a companion matrix in `GL(3, K)` whose multiplicative order is `q^3 - 1`.

    This function is used in :func:`HughesPlane`

    EXAMPLES::

        sage: from sage.combinat.designs.block_design import q3_minus_one_matrix
        sage: m = q3_minus_one_matrix(GF(3))
        sage: m.multiplicative_order() == 3**3 - 1
        True

        sage: m = q3_minus_one_matrix(GF(4,'a'))
        sage: m.multiplicative_order() == 4**3 - 1
        True

        sage: m = q3_minus_one_matrix(GF(5))
        sage: m.multiplicative_order() == 5**3 - 1
        True

        sage: m = q3_minus_one_matrix(GF(9,'a'))
        sage: m.multiplicative_order() == 9**3 - 1
        True
    """
    q = K.cardinality()
    M = MatrixSpace(K, 3)

    if q.is_prime():
        from sage.rings.finite_rings.conway_polynomials import conway_polynomial
        try:
            a,b,c,_ = conway_polynomial(q, 3)
        except RuntimeError:  # the polynomial is not in the database
            pass
        else:
            return M([0,0,-a,1,0,-b,0,1,-c])

    m = M()
    m[1,0] = m[2,1] = K.one()
    while True:
        m[0,2] = K._random_nonzero_element()
        m[1,2] = K.random_element()
        m[2,2] = K.random_element()
        if m.multiplicative_order() == q**3 - 1:
            return m
Esempio n. 5
0
def random_q3_minus_one_matrix(K):
    r"""
    Return a companion matrix in `GL(3, K)` whose multiplicative order is `q^3 - 1`.

    EXAMPLES::

        sage: m = random_q3_minus_one_matrix(GF(3))
        sage: m.multiplicative_order() == 3**3 - 1
        True

        sage: m = random_q3_minus_one_matrix(GF(4,'a'))
        sage: m.multiplicative_order() == 4**3 - 1
        True

        sage: m = random_q3_minus_one_matrix(GF(5))
        sage: m.multiplicative_order() == 5**3 - 1
        True

        sage: m = random_q3_minus_one_matrix(GF(9,'a'))
        sage: m.multiplicative_order() == 9**3 - 1
        True
    """
    q = K.cardinality()
    M = MatrixSpace(K, 3)

    if q.is_prime():
        from sage.rings.finite_rings.conway_polynomials import conway_polynomial
        try:
            a,b,c,_ = conway_polynomial(q, 3)
        except RuntimeError:  # the polynomial is not in the database
            pass
        else:
            return M([0,0,-a,1,0,-b,0,1,-c])

    while True:
        a = K._random_nonzero_element()
        b = K.random_element()
        c = K.random_element()
        m = M([0,0,-a,1,0,-b,0,1,-c])
        if m.multiplicative_order() == q**3 - 1:
            return m
Esempio n. 6
0
def singer_difference_set(q,d):
    r"""
    Return a difference set associated to the set of hyperplanes in a projective
    space of dimension `d` over `GF(q)`.

    A Singer difference set has parameters:

    .. MATH::

        v = \frac{q^{d+1}-1}{q-1}, \quad
        k = \frac{q^d-1}{q-1}, \quad
        \lambda = \frac{q^{d-1}-1}{q-1}.

    The idea of the construction is as follows. One consider the finite field
    `GF(q^{d+1})` as a vector space of dimension `d+1` over `GF(q)`. The set of
    `GF(q)`-lines in `GF(q^{d+1})` is a projective plane and its set of
    hyperplanes form a balanced incomplete block design.

    Now, considering a multiplicative generator `z` of `GF(q^{d+1})`, we get a
    transitive action of a cyclic group on our projective plane from which it is
    possible to build a difference set.

    The construction is given in details in [Stinson2004]_, section 3.3.

    EXAMPLES::

        sage: from sage.combinat.designs.difference_family import singer_difference_set, is_difference_family
        sage: G,D = singer_difference_set(3,2)
        sage: is_difference_family(G,D,verbose=True)
        It is a (13,4,1)-difference family
        True

        sage: G,D = singer_difference_set(4,2)
        sage: is_difference_family(G,D,verbose=True)
        It is a (21,5,1)-difference family
        True

        sage: G,D = singer_difference_set(3,3)
        sage: is_difference_family(G,D,verbose=True)
        It is a (40,13,4)-difference family
        True

        sage: G,D = singer_difference_set(9,3)
        sage: is_difference_family(G,D,verbose=True)
        It is a (820,91,10)-difference family
        True
    """
    q = Integer(q)
    assert q.is_prime_power()
    assert d >= 2

    from sage.rings.finite_rings.constructor import GF
    from sage.rings.finite_rings.conway_polynomials import conway_polynomial
    from sage.rings.finite_rings.integer_mod_ring import Zmod

    # build a polynomial c over GF(q) such that GF(q)[x] / (c(x)) is a
    # GF(q**(d+1)) and such that x is a multiplicative generator.
    p,e = q.factor()[0]
    c = conway_polynomial(p,e*(d+1))
    if e != 1:  # i.e. q is not a prime, so we factorize c over GF(q) and pick
                # one of its factor
        K = GF(q,'z')
        c = c.change_ring(K).factor()[0][0]
    else:
        K = GF(q)
    z = c.parent().gen()

    # Now we consider the GF(q)-subspace V spanned by (1,z,z^2,...,z^(d-1)) inside
    # GF(q^(d+1)). The multiplication by z is an automorphism of the
    # GF(q)-projective space built from GF(q^(d+1)). The difference family is
    # obtained by taking the integers i such that z^i belong to V.
    powers = [0]
    i = 1
    x = z
    k = (q**d-1)//(q-1)
    while len(powers) < k:
        if x.degree() <= (d-1):
            powers.append(i)
        x = (x*z).mod(c)
        i += 1

    return Zmod((q**(d+1)-1)//(q-1)), [powers]
Esempio n. 7
0
def singer_difference_set(q, d):
    r"""
    Return a difference set associated to the set of hyperplanes in a projective
    space of dimension `d` over `GF(q)`.

    A Singer difference set has parameters:

    .. MATH::

        v = \frac{q^{d+1}-1}{q-1}, \quad
        k = \frac{q^d-1}{q-1}, \quad
        \lambda = \frac{q^{d-1}-1}{q-1}.

    The idea of the construction is as follows. One consider the finite field
    `GF(q^{d+1})` as a vector space of dimension `d+1` over `GF(q)`. The set of
    `GF(q)`-lines in `GF(q^{d+1})` is a projective plane and its set of
    hyperplanes form a balanced incomplete block design.

    Now, considering a multiplicative generator `z` of `GF(q^{d+1})`, we get a
    transitive action of a cyclic group on our projective plane from which it is
    possible to build a difference set.

    The construction is given in details in [Stinson2004]_, section 3.3.

    EXAMPLES::

        sage: from sage.combinat.designs.difference_family import singer_difference_set, is_difference_family
        sage: G,D = singer_difference_set(3,2)
        sage: is_difference_family(G,D,verbose=True)
        It is a (13,4,1)-difference family
        True

        sage: G,D = singer_difference_set(4,2)
        sage: is_difference_family(G,D,verbose=True)
        It is a (21,5,1)-difference family
        True

        sage: G,D = singer_difference_set(3,3)
        sage: is_difference_family(G,D,verbose=True)
        It is a (40,13,4)-difference family
        True

        sage: G,D = singer_difference_set(9,3)
        sage: is_difference_family(G,D,verbose=True)
        It is a (820,91,10)-difference family
        True
    """
    q = Integer(q)
    assert q.is_prime_power()
    assert d >= 2

    from sage.rings.finite_rings.constructor import GF
    from sage.rings.finite_rings.conway_polynomials import conway_polynomial
    from sage.rings.finite_rings.integer_mod_ring import Zmod

    # build a polynomial c over GF(q) such that GF(q)[x] / (c(x)) is a
    # GF(q**(d+1)) and such that x is a multiplicative generator.
    p, e = q.factor()[0]
    c = conway_polynomial(p, e * (d + 1))
    if e != 1:  # i.e. q is not a prime, so we factorize c over GF(q) and pick
        # one of its factor
        K = GF(q, 'z')
        c = c.change_ring(K).factor()[0][0]
    else:
        K = GF(q)
    z = c.parent().gen()

    # Now we consider the GF(q)-subspace V spanned by (1,z,z^2,...,z^(d-1)) inside
    # GF(q^(d+1)). The multiplication by z is an automorphism of the
    # GF(q)-projective space built from GF(q^(d+1)). The difference family is
    # obtained by taking the integers i such that z^i belong to V.
    powers = [0]
    i = 1
    x = z
    k = (q**d - 1) // (q - 1)
    while len(powers) < k:
        if x.degree() <= (d - 1):
            powers.append(i)
        x = (x * z).mod(c)
        i += 1

    return Zmod((q**(d + 1) - 1) // (q - 1)), [powers]