예제 #1
0
def WittDesign(n):
    """
    INPUT:

    - ``n`` is in `9,10,11,12,21,22,23,24`.

    Wraps GAP Design's WittDesign. If ``n=24`` then this function returns the
    large Witt design `W_{24}`, the unique (up to isomorphism) `5-(24,8,1)`
    design. If ``n=12`` then this function returns the small Witt design
    `W_{12}`, the unique (up to isomorphism) `5-(12,6,1)` design.  The other
    values of `n` return a block design derived from these.

    .. NOTE::

        Requires GAP's Design package (included in the gap_packages Sage spkg).

    EXAMPLES::

        sage: BD = designs.WittDesign(9)             # optional - gap_packages (design package)
        sage: BD.is_t_design(return_parameters=True) # optional - gap_packages (design package)
        (True, (2, 9, 3, 1))
        sage: BD                             # optional - gap_packages (design package)
        Incidence structure with 9 points and 12 blocks
        sage: print(BD)                      # optional - gap_packages (design package)
        Incidence structure with 9 points and 12 blocks
    """
    libgap.load_package("design")
    B = libgap.WittDesign(n)
    v = B['v'].sage()
    gB = [[x - 1 for x in b] for b in B['blocks'].sage()]
    return BlockDesign(v, gB, name="WittDesign", check=True)
예제 #2
0
파일: guava.py 프로젝트: timgates42/sage
def RandomLinearCodeGuava(n, k, F):
    r"""
    The method used is to first construct a `k \times n` matrix of the block
    form `(I,A)`, where `I` is a `k \times k` identity matrix and `A` is a
    `k \times (n-k)` matrix constructed using random elements of `F`. Then
    the columns are permuted using a randomly selected element of the symmetric
    group `S_n`.

    INPUT:

    - ``n,k`` -- integers with `n>k>1`.

    OUTPUT:

    Returns a "random" linear code with length `n`, dimension `k` over field `F`.

    EXAMPLES::

        sage: C = codes.RandomLinearCodeGuava(30,15,GF(2)); C      # optional - gap_packages (Guava package)
        [30, 15] linear code over GF(2)
        sage: C = codes.RandomLinearCodeGuava(10,5,GF(4,'a')); C      # optional - gap_packages (Guava package)
        [10, 5] linear code over GF(4)

    AUTHOR: David Joyner (11-2005)
    """
    current_randstate().set_seed_gap()

    GapPackage("guava", spkg="gap_packages").require()
    libgap.load_package("guava")
    C=libgap.RandomLinearCode(n,k,F)
    G=C.GeneratorMat()
    MS = MatrixSpace(F, len(G), len(G[0]))
    return LinearCode(MS(G))
예제 #3
0
def plotkin_upper_bound(n, q, d, algorithm=None):
    r"""
    Return the Plotkin upper bound.

    Return the Plotkin upper bound for the number of elements in a largest
    code of minimum distance `d` in `\GF{q}^n`.
    More precisely this is a generalization of Plotkin's result for `q=2`
    to bigger `q` due to Berlekamp.

    The ``algorithm="gap"`` option wraps Guava's ``UpperBoundPlotkin``.

    EXAMPLES::

        sage: codes.bounds.plotkin_upper_bound(10,2,3)
        192
        sage: codes.bounds.plotkin_upper_bound(10,2,3,algorithm="gap")  # optional - gap_packages (Guava package)
        192
    """
    _check_n_q_d(n, q, d, field_based=False)
    if algorithm == "gap":
        libgap.load_package("guava")
        return QQ(libgap.UpperBoundPlotkin(n, d, q))
    else:
        t = 1 - 1 / q
        if (q == 2) and (n == 2 * d) and (d % 2 == 0):
            return 4 * d
        elif (q == 2) and (n == 2 * d + 1) and (d % 2 == 1):
            return 4 * d + 4
        elif d > t * n:
            return int(d / (d - t * n))
        elif d < t * n + 1:
            fact = (d - 1) / t
            if RR(fact) == RR(int(fact)):
                fact = int(fact) + 1
            return int(d / (d - t * fact)) * q**(n - fact)
예제 #4
0
파일: guava.py 프로젝트: timgates42/sage
def QuasiQuadraticResidueCode(p):
    r"""
    A (binary) quasi-quadratic residue code (or QQR code).

    Follows the definition of Proposition 2.2 in [BM2003]_. The code has a generator
    matrix in the block form `G=(Q,N)`. Here `Q` is a `p \times p` circulant
    matrix whose top row is `(0,x_1,...,x_{p-1})`, where `x_i=1` if and only if
    `i` is a quadratic residue `\mod p`, and `N` is a `p \times p` circulant
    matrix whose top row is `(0,y_1,...,y_{p-1})`, where `x_i+y_i=1` for all
    `i`.

    INPUT:

    - ``p`` -- a prime `>2`.

    OUTPUT:

    Returns a QQR code of length `2p`.

    EXAMPLES::

        sage: C = codes.QuasiQuadraticResidueCode(11); C   # optional - gap_packages (Guava package)
        [22, 11] linear code over GF(2)

    These are self-orthogonal in general and self-dual when $p \\equiv 3 \\pmod 4$.

    AUTHOR: David Joyner (11-2005)
    """
    GapPackage("guava", spkg="gap_packages").require()
    libgap.load_package("guava")
    C=libgap.QQRCode(p)
    G=C.GeneratorMat()
    MS = MatrixSpace(GF(2), len(G), len(G[0]))
    return LinearCode(MS(G))
예제 #5
0
def bounds_on_minimum_distance_in_guava(n, k, F):
    r"""
    Compute a lower and upper bound on the greatest minimum distance of a
    `[n,k]` linear code over the field ``F``.

    This function requires the optional GAP package GUAVA.

    The function returns a GAP record with the two bounds and an explanation for
    each bound. The method ``Display`` can be used to show the explanations.

    The values for the lower and upper bound are obtained from a table
    constructed by Cen Tjhai for GUAVA, derived from the table of
    Brouwer. See http://www.codetables.de/ for the most recent data.
    These tables contain lower and upper bounds for `q=2` (when ``n <= 257``),
    `q=3` (when ``n <= 243``), `q=4` (``n <= 256``). (Current as of
    11 May 2006.) For codes over other fields and for larger word lengths,
    trivial bounds are used.

    INPUT:

    - ``n`` -- the length of the code to look up

    - ``k`` -- the dimension of the code to look up

    - ``F`` -- the base field of the code to look up

    OUTPUT:

    - A GAP record object. See below for an example.

    EXAMPLES::

        sage: gap_rec = codes.databases.bounds_on_minimum_distance_in_guava(10,5,GF(2))  # optional - gap_packages (Guava package)
        sage: gap_rec.Display()                                                          # optional - gap_packages (Guava package)
        rec(
          construction := [ <Operation "ShortenedCode">,
            [ [ <Operation "UUVCode">,
              [ [ <Operation "DualCode">,
              [ [ <Operation "RepetitionCode">, [ 8, 2 ] ] ] ],
              [ <Operation "UUVCode">, [ [ <Operation "DualCode">,
                [ [ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ],
                [ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ] ] ],
            [ 1, 2, 3, 4, 5, 6 ] ] ],
          k := 5,
          lowerBound := 4,
          lowerBoundExplanation := ...
          n := 10,
          q := 2,
          references := rec(
               ),
          upperBound := 4,
          upperBoundExplanation := ... )
    """
    GapPackage("guava", spkg="gap_packages").require()
    libgap.load_package("guava")
    return libgap.BoundsMinimumDistance(n, k, F)
예제 #6
0
def griesmer_upper_bound(n, q, d, algorithm=None):
    r"""
    Return the Griesmer upper bound.

    Return the Griesmer upper bound for the number of elements in a
    largest linear code of minimum distance `d` in `\GF{q}^n`, cf. [HP2003]_.
    If the method is "gap", it wraps GAP's ``UpperBoundGriesmer``.

    The bound states:

    .. MATH::

        `n\geq \sum_{i=0}^{k-1} \lceil d/q^i \rceil.`


    EXAMPLES:

    The bound is reached for the ternary Golay codes::

        sage: codes.bounds.griesmer_upper_bound(12,3,6)
        729
        sage: codes.bounds.griesmer_upper_bound(11,3,5)
        729

    ::

        sage: codes.bounds.griesmer_upper_bound(10,2,3)
        128
        sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm="gap")  # optional - gap_packages (Guava package)
        128

    TESTS::

        sage: codes.bounds.griesmer_upper_bound(11,3,6)
        243
        sage: codes.bounds.griesmer_upper_bound(11,3,6)
        243
    """
    _check_n_q_d(n, q, d)
    if algorithm == "gap":
        libgap.load_package("guava")
        return QQ(libgap.UpperBoundGriesmer(n, d, q))
    else:
        # To compute the bound, we keep summing up the terms on the RHS
        # until we start violating the inequality.
        from sage.functions.other import ceil
        den = 1
        s = 0
        k = 0
        while s <= n:
            s += ceil(d / den)
            den *= q
            k = k + 1
        return q**(k - 1)
예제 #7
0
def best_linear_code_in_guava(n, k, F):
    r"""
    Return the linear code of length ``n``, dimension ``k`` over field ``F``
    with the maximal minimum distance which is known to the GAP package GUAVA.

    The function uses the tables described in :func:`bounds_on_minimum_distance_in_guava` to
    construct this code. This requires the optional GAP package GUAVA.

    INPUT:

    - ``n`` -- the length of the code to look up

    - ``k`` -- the dimension of the code to look up

    - ``F`` -- the base field of the code to look up

    OUTPUT:

    A :class:`LinearCode` which is a best linear code of the given parameters known to GUAVA.

    EXAMPLES::

        sage: codes.databases.best_linear_code_in_guava(10,5,GF(2))    # long time; optional - gap_packages (Guava package)
        [10, 5] linear code over GF(2)
        sage: gap.eval("C:=BestKnownLinearCode(10,5,GF(2))")           # long time; optional - gap_packages (Guava package)
        'a linear [10,5,4]2..4 shortened code'

    This means that the best possible binary linear code of length 10 and
    dimension 5 is a code with minimum distance 4 and covering radius s somewhere
    between 2 and 4. Use ``bounds_on_minimum_distance_in_guava(10,5,GF(2))``
    for further details.
    """
    from .linear_code import LinearCode
    GapPackage("guava", spkg="gap_packages").require()
    libgap.load_package("guava")
    C = libgap.BestKnownLinearCode(n, k, F)
    return LinearCode(C.GeneratorMat()._matrix_(F))
예제 #8
0
def elias_upper_bound(n, q, d, algorithm=None):
    r"""
    Return the Elias upper bound.

    Return the Elias upper bound for number of elements in the largest
    code of minimum distance `d` in `\GF{q}^n`, cf. [HP2003]_.
    If the method is "gap", it wraps GAP's ``UpperBoundElias``.

    EXAMPLES::

        sage: codes.bounds.elias_upper_bound(10,2,3)
        232
        sage: codes.bounds.elias_upper_bound(10,2,3,algorithm="gap")  # optional - gap_packages (Guava package)
        232
    """
    _check_n_q_d(n, q, d, field_based=False)
    r = 1 - 1 / q
    if algorithm == "gap":
        libgap.load_package("guava")
        return QQ(libgap.UpperBoundElias(n, d, q))
    else:

        def ff(n, d, w, q):
            return r * n * d * q**n / (
                (w**2 - 2 * r * n * w + r * n * d) * volume_hamming(n, q, w))

    def get_list(n, d, q):
        I = []
        for i in range(1, int(r * n) + 1):
            if i**2 - 2 * r * n * i + r * n * d > 0:
                I.append(i)
        return I

    I = get_list(n, d, q)
    bnd = min([ff(n, d, w, q) for w in I])
    return int(bnd)
예제 #9
0
def ProjectiveGeometryDesign(n,
                             d,
                             F,
                             algorithm=None,
                             point_coordinates=True,
                             check=True):
    r"""
    Return a projective geometry design.

    The projective geometry design `PG_d(n,q)` has for points the lines of
    `\GF{q}^{n+1}`, and for blocks the `d+1`-dimensional subspaces of
    `\GF{q}^{n+1}`, each of which contains `\frac {|\GF{q}|^{d+1}-1} {|\GF{q}|-1}` lines.
    It is a `2`-design with parameters

    .. MATH::

        v = \binom{n+1}{1}_q,\ k = \binom{d+1}{1}_q,\ \lambda =
        \binom{n-1}{d-1}_q

    where the `q`-binomial coefficient `\binom{m}{r}_q` is defined by

    .. MATH::

        \binom{m}{r}_q = \frac{(q^m - 1)(q^{m-1} - 1) \cdots (q^{m-r+1}-1)}
              {(q^r-1)(q^{r-1}-1)\cdots (q-1)}

    .. SEEALSO::

        :func:`AffineGeometryDesign`

    INPUT:

    - ``n`` is the projective dimension

    - ``d`` is the dimension of the subspaces which make up the blocks.

    - ``F`` -- a finite field or a prime power.

    - ``algorithm`` -- set to ``None`` by default, which results in using Sage's
      own implementation. In order to use GAP's implementation instead (i.e. its
      ``PGPointFlatBlockDesign`` function) set ``algorithm="gap"``. Note that
      GAP's "design" package must be available in this case, and that it can be
      installed with the ``gap_packages`` spkg.

    - ``point_coordinates`` -- ``True`` by default. Ignored and assumed to be ``False`` if
      ``algorithm="gap"``. If ``True``, the ground set is indexed by coordinates
      in `\GF{q}^{n+1}`.  Otherwise the ground set is indexed by integers.

    - ``check`` -- (optional, default to ``True``) whether to check the output.

    EXAMPLES:

    The set of `d`-dimensional subspaces in a `n`-dimensional projective space
    forms `2`-designs (or balanced incomplete block designs)::

        sage: PG = designs.ProjectiveGeometryDesign(4, 2, GF(2))
        sage: PG
        Incidence structure with 31 points and 155 blocks
        sage: PG.is_t_design(return_parameters=True)
        (True, (2, 31, 7, 7))

        sage: PG = designs.ProjectiveGeometryDesign(3, 1, GF(4))
        sage: PG.is_t_design(return_parameters=True)
        (True, (2, 85, 5, 1))

    Check with ``F`` being a prime power::

        sage: PG = designs.ProjectiveGeometryDesign(3, 2, 4)
        sage: PG
        Incidence structure with 85 points and 85 blocks

    Use coordinates::

        sage: PG = designs.ProjectiveGeometryDesign(2, 1, GF(3))
        sage: PG.blocks()[0]
        [(1, 0, 0), (1, 0, 1), (1, 0, 2), (0, 0, 1)]

    Use indexing by integers::

        sage: PG = designs.ProjectiveGeometryDesign(2,1,GF(3),point_coordinates=0)
        sage: PG.blocks()[0]
        [0, 1, 2, 12]

    Check that the constructor using gap also works::

        sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm="gap") # optional - gap_packages (design package)
        sage: BD.is_t_design(return_parameters=True)                              # optional - gap_packages (design package)
        (True, (2, 7, 3, 1))
    """
    try:
        q = int(F)
    except TypeError:
        q = F.cardinality()
    else:
        from sage.rings.finite_rings.finite_field_constructor import GF
        F = GF(q)

    if algorithm is None:
        from sage.matrix.echelon_matrix import reduced_echelon_matrix_iterator

        points = {
            p: i
            for i, p in enumerate(
                reduced_echelon_matrix_iterator(
                    F, 1, n + 1, copy=True, set_immutable=True))
        }
        blocks = []
        for m1 in reduced_echelon_matrix_iterator(F, d + 1, n + 1, copy=False):
            b = []
            for m2 in reduced_echelon_matrix_iterator(F, 1, d + 1, copy=False):
                m = m2 * m1
                m.echelonize()
                m.set_immutable()
                b.append(points[m])
            blocks.append(b)
        B = BlockDesign(len(points),
                        blocks,
                        name="ProjectiveGeometryDesign",
                        check=check)
        if point_coordinates:
            B.relabel({i: p[0] for p, i in points.items()})

    elif algorithm == "gap":  # Requires GAP's Design
        libgap.load_package("design")
        D = libgap.PGPointFlatBlockDesign(n, F.order(), d)
        v = D['v'].sage()
        gblcks = D['blocks'].sage()
        gB = []
        for b in gblcks:
            gB.append([x - 1 for x in b])
        B = BlockDesign(v, gB, name="ProjectiveGeometryDesign", check=check)

    if check:
        from sage.combinat.q_analogues import q_binomial
        q = F.cardinality()
        if not B.is_t_design(t=2,
                             v=q_binomial(n + 1, 1, q),
                             k=q_binomial(d + 1, 1, q),
                             l=q_binomial(n - 1, d - 1, q)):
            raise RuntimeError(
                "error in ProjectiveGeometryDesign "
                "construction. Please e-mail [email protected]")
    return B
예제 #10
0
def codesize_upper_bound(n, d, q, algorithm=None):
    r"""
    Return an upper bound on the number of codewords in a (possibly non-linear)
    code.

    This function computes the minimum value of the upper bounds of Singleton,
    Hamming, Plotkin, and Elias.

    If algorithm="gap" then this returns the best known upper
    bound `A(n,d)=A_q(n,d)` for the size of a code of length n,
    minimum distance d over a field of size q. The function first
    checks for trivial cases (like d=1 or n=d), and if the value
    is in the built-in table. Then it calculates the minimum value
    of the upper bound using the algorithms of Singleton, Hamming,
    Johnson, Plotkin and Elias. If the code is binary,
    `A(n, 2\ell-1) = A(n+1,2\ell)`, so the function
    takes the minimum of the values obtained from all algorithms for the
    parameters `(n, 2\ell-1)` and `(n+1, 2\ell)`. This
    wraps GUAVA's (i.e. GAP's package Guava) UpperBound( n, d, q ).

    If algorithm="LP" then this returns the Delsarte (a.k.a. Linear
    Programming) upper bound.

    EXAMPLES::

        sage: codes.bounds.codesize_upper_bound(10,3,2)
        93
        sage: codes.bounds.codesize_upper_bound(24,8,2,algorithm="LP")
        4096
        sage: codes.bounds.codesize_upper_bound(10,3,2,algorithm="gap")  # optional - gap_packages (Guava package)
        85
        sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm=None)
        123361
        sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="gap")  # optional - gap_packages (Guava package)
        123361
        sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="LP")
        109226

    TESTS:

    Make sure :trac:`22961` is fixed::

        sage: codes.bounds.codesize_upper_bound(19,10,2)
        20
        sage: codes.bounds.codesize_upper_bound(19,10,2,algorithm="gap") # optional - gap_packages (Guava package)
        20

    Meaningless parameters are rejected::

        sage: codes.bounds.codesize_upper_bound(10, -20, 6)
        Traceback (most recent call last):
        ...
        ValueError: The length or minimum distance does not make sense
    """
    _check_n_q_d(n, q, d, field_based=False)
    if algorithm == "gap":
        libgap.load_package('guava')
        return int(libgap.UpperBound(n, d, q))
    if algorithm == "LP":
        return int(delsarte_bound_hamming_space(n, d, q))
    else:
        eub = elias_upper_bound(n, q, d)
        hub = hamming_upper_bound(n, q, d)
        pub = plotkin_upper_bound(n, q, d)
        sub = singleton_upper_bound(n, q, d)
        return min([eub, hub, pub, sub])