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)
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)
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
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
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
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]
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]