コード例 #1
0
ファイル: bibd.py プロジェクト: aaditya-thakkar/sage
def v_5_1_BIBD(v, check=True):
    r"""
    Return a `(v,5,1)`-BIBD.

    This method follows the constuction from [ClaytonSmith]_.

    INPUT:

    - ``v`` (integer)

    .. SEEALSO::

        * :func:`balanced_incomplete_block_design`

    EXAMPLES::

        sage: from sage.combinat.designs.bibd import v_5_1_BIBD
        sage: i = 0
        sage: while i<200:
        ....:    i += 20
        ....:    _ = v_5_1_BIBD(i+1)
        ....:    _ = v_5_1_BIBD(i+5)

    TESTS:

    Check that the needed difference families are there::

        sage: for v in [21,41,61,81,141,161,281]:
        ....:     assert designs.difference_family(v,5,existence=True)
        ....:     _ = designs.difference_family(v,5)
    """
    v = int(v)

    assert (v > 1)
    assert (v%20 == 5 or v%20 == 1)  # note: equivalent to (v-1)%4 == 0 and (v*(v-1))%20 == 0

    # Lemma 27
    if v%5 == 0 and (v//5)%4 == 1 and is_prime_power(v//5):
        bibd = BIBD_5q_5_for_q_prime_power(v//5)
    # Lemma 28
    elif v in [21,41,61,81,141,161,281]:
        from difference_family import difference_family
        G,D = difference_family(v,5)
        bibd = BIBD_from_difference_family(G, D, check=False)
    # Lemma 29
    elif v == 165:
        bibd = BIBD_from_PBD(v_5_1_BIBD(41,check=False),165,5,check=False)
    elif v == 181:
        bibd = BIBD_from_PBD(v_5_1_BIBD(45,check=False),181,5,check=False)
    elif v in (201,285,301,401,421,425):
        # Call directly the BIBD_from_TD function
        # note: there are (201,5,1) and (421,5)-difference families that can be
        # obtained from the general constructor
        bibd = BIBD_from_TD(v,5)
    # Theorem 31.2
    elif (v-1)//4 in [80, 81, 85, 86, 90, 91, 95, 96, 110, 111, 115, 116, 120, 121, 250, 251, 255, 256, 260, 261, 265, 266, 270, 271]:
        r = (v-1)//4
        if r <= 96:
            k,t,u = 5, 16, r-80
        elif r <= 121:
            k,t,u = 10, 11, r-110
        else:
            k,t,u = 10, 25, r-250
        bibd = BIBD_from_PBD(PBD_from_TD(k,t,u),v,5,check=False)

    else:
        r,s,t,u = _get_r_s_t_u(v)
        bibd = BIBD_from_PBD(PBD_from_TD(5,t,u),v,5,check=False)

    if check:
        assert is_pairwise_balanced_design(bibd,v,[5])

    return bibd
コード例 #2
0
ファイル: bibd.py プロジェクト: aaditya-thakkar/sage
def balanced_incomplete_block_design(v, k, existence=False, use_LJCR=False):
    r"""
    Return a BIBD of parameters `v,k`.

    A Balanced Incomplete Block Design of parameters `v,k` is a collection
    `\mathcal C` of `k`-subsets of `V=\{0,\dots,v-1\}` such that for any two
    distinct elements `x,y\in V` there is a unique element `S\in \mathcal C`
    such that `x,y\in S`.

    More general definitions sometimes involve a `\lambda` parameter, and we
    assume here that `\lambda=1`.

    For more information on BIBD, see the
    :wikipedia:`corresponding Wikipedia entry <Block_design#Definition_of_a_BIBD_.28or_2-design.29>`.

    INPUT:

    - ``v,k`` (integers)

    - ``existence`` (boolean) -- instead of building the design, return:

        - ``True`` -- meaning that Sage knows how to build the design

        - ``Unknown`` -- meaning that Sage does not know how to build the
          design, but that the design may exist (see :mod:`sage.misc.unknown`).

        - ``False`` -- meaning that the design does not exist.

    - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering
      Repository for the design when Sage does not know how to build it (see
      :func:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This
      requires internet.

    .. SEEALSO::

        * :func:`steiner_triple_system`
        * :func:`v_4_1_BIBD`
        * :func:`v_5_1_BIBD`

    TODO:

        * Implement other constructions from the Handbook of Combinatorial
          Designs.

    EXAMPLES::

        sage: designs.balanced_incomplete_block_design(7, 3).blocks()
        [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]]
        sage: B = designs.balanced_incomplete_block_design(66, 6, use_LJCR=True) # optional - internet
        sage: B                                                              # optional - internet
        Incidence structure with 66 points and 143 blocks
        sage: B.blocks()                                                     # optional - internet
        [[0, 1, 2, 3, 4, 65], [0, 5, 24, 25, 39, 57], [0, 6, 27, 38, 44, 55], ...
        sage: designs.balanced_incomplete_block_design(66, 6, use_LJCR=True)  # optional - internet
        Incidence structure with 66 points and 143 blocks
        sage: designs.balanced_incomplete_block_design(216, 6)
        Traceback (most recent call last):
        ...
        NotImplementedError: I don't know how to build a (216,6,1)-BIBD!

    TESTS::

        sage: designs.balanced_incomplete_block_design(85,5,existence=True)
        True
        sage: _ = designs.balanced_incomplete_block_design(85,5)

    A BIBD from a Finite Projective Plane::

        sage: _ = designs.balanced_incomplete_block_design(21,5)

    Some trivial BIBD::

        sage: designs.balanced_incomplete_block_design(10,10)
        (10,10,1)-Balanced Incomplete Block Design
        sage: designs.balanced_incomplete_block_design(1,10)
        (1,0,1)-Balanced Incomplete Block Design

    Existence of BIBD with `k=3,4,5`::

        sage: [v for v in xrange(50) if designs.balanced_incomplete_block_design(v,3,existence=True)]
        [1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49]
        sage: [v for v in xrange(100) if designs.balanced_incomplete_block_design(v,4,existence=True)]
        [1, 4, 13, 16, 25, 28, 37, 40, 49, 52, 61, 64, 73, 76, 85, 88, 97]
        sage: [v for v in xrange(150) if designs.balanced_incomplete_block_design(v,5,existence=True)]
        [1, 5, 21, 25, 41, 45, 61, 65, 81, 85, 101, 105, 121, 125, 141, 145]

    For `k > 5` there are currently very few constructions::

        sage: [v for v in xrange(300) if designs.balanced_incomplete_block_design(v,6,existence=True) is True]
        [1, 6, 31, 66, 76, 91, 96, 106, 111, 121, 126, 136, 141, 151, 156, 171, 181, 186, 196, 201, 211, 241, 271]
        sage: [v for v in xrange(300) if designs.balanced_incomplete_block_design(v,6,existence=True) is Unknown]
        [51, 61, 81, 166, 216, 226, 231, 246, 256, 261, 276, 286, 291]

    Here are some constructions with `k \geq 7` and `v` a prime power::

        sage: designs.balanced_incomplete_block_design(169,7)
        (169,7,1)-Balanced Incomplete Block Design
        sage: designs.balanced_incomplete_block_design(617,8)
        (617,8,1)-Balanced Incomplete Block Design
        sage: designs.balanced_incomplete_block_design(433,9)
        (433,9,1)-Balanced Incomplete Block Design
        sage: designs.balanced_incomplete_block_design(1171,10)
        (1171,10,1)-Balanced Incomplete Block Design

    And we know some inexistence results::

        sage: designs.balanced_incomplete_block_design(21,6,existence=True)
        False
    """
    lmbd = 1

    # Trivial BIBD
    if v == 1:
        if existence:
            return True
        return BalancedIncompleteBlockDesign(v, [], check=False)

    if k == v:
        if existence:
            return True
        return BalancedIncompleteBlockDesign(v, [range(v)], check=False, copy=False)

    # Non-existence of BIBD
    if (v < k or
        k < 2 or
        (v-1) % (k-1) != 0 or
        (v*(v-1)) % (k*(k-1)) != 0 or
        # From the Handbook of combinatorial designs:
        #
        # With lambda>1 other exceptions are
        # (15,5,2),(21,6,2),(22,7,2),(22,8,4).
        (k==6 and v in [36,46]) or
        (k==7 and v == 43) or
        # Fisher's inequality
        (v*(v-1))/(k*(k-1)) < v):
        if existence:
            return False
        raise EmptySetError("There exists no ({},{},{})-BIBD".format(v,k,lmbd))

    if k == 2:
        if existence:
            return True
        from itertools import combinations
        return BalancedIncompleteBlockDesign(v, combinations(range(v),2), check=False, copy=True)
    if k == 3:
        if existence:
            return v%6 == 1 or v%6 == 3
        return steiner_triple_system(v)
    if k == 4:
        if existence:
            return v%12 == 1 or v%12 == 4
        return BalancedIncompleteBlockDesign(v, v_4_1_BIBD(v), copy=False)
    if k == 5:
        if existence:
            return v%20 == 1 or v%20 == 5
        return BalancedIncompleteBlockDesign(v, v_5_1_BIBD(v), copy=False)

    from difference_family import difference_family
    from database import BIBD_constructions

    if (v,k,1) in BIBD_constructions:
        if existence:
            return True
        return BlockDesign(v,BIBD_constructions[(v,k,1)](), copy=False)
    if BIBD_from_arc_in_desarguesian_projective_plane(v,k,existence=True):
        if existence:
            return True
        B = BIBD_from_arc_in_desarguesian_projective_plane(v,k)
        return BalancedIncompleteBlockDesign(v, B, copy=False)
    if BIBD_from_TD(v,k,existence=True):
        if existence:
            return True
        return BalancedIncompleteBlockDesign(v, BIBD_from_TD(v,k), copy=False)
    if v == (k-1)**2+k and is_prime_power(k-1):
        if existence:
            return True
        from block_design import projective_plane
        return BalancedIncompleteBlockDesign(v, projective_plane(k-1),copy=False)
    if difference_family(v,k,existence=True):
        if existence:
            return True
        G,D = difference_family(v,k)
        return BalancedIncompleteBlockDesign(v, BIBD_from_difference_family(G,D,check=False), copy=False)
    if use_LJCR:
        from covering_design import best_known_covering_design_www
        B = best_known_covering_design_www(v,k,2)

        # Is it a BIBD or just a good covering ?
        expected_n_of_blocks = binomial(v,2)/binomial(k,2)
        if B.low_bd() > expected_n_of_blocks:
            if existence:
                return False
            raise EmptySetError("There exists no ({},{},{})-BIBD".format(v,k,lmbd))
        B = B.incidence_structure()
        if B.num_blocks() == expected_n_of_blocks:
            if existence:
                return True
            else:
                return B

    if existence:
        return Unknown
    else:
        raise NotImplementedError("I don't know how to build a ({},{},1)-BIBD!".format(v,k))
コード例 #3
0
ファイル: bibd.py プロジェクト: aaditya-thakkar/sage
def v_4_1_BIBD(v, check=True):
    r"""
    Return a `(v,4,1)`-BIBD.

    A `(v,4,1)`-BIBD is an edge-decomposition of the complete graph `K_v` into
    copies of `K_4`. For more information, see
    :func:`balanced_incomplete_block_design`. It exists if and only if `v\equiv 1,4
    \pmod {12}`.

    See page 167 of [Stinson2004]_ for the construction details.

    .. SEEALSO::

        * :func:`balanced_incomplete_block_design`

    INPUT:

    - ``v`` (integer) -- number of points.

    - ``check`` (boolean) -- whether to check that output is correct before
      returning it. As this is expected to be useless (but we are cautious
      guys), you may want to disable it whenever you want speed. Set to ``True``
      by default.

    EXAMPLES::

        sage: from sage.combinat.designs.bibd import v_4_1_BIBD  # long time
        sage: for n in range(13,100):                            # long time
        ....:    if n%12 in [1,4]:                               # long time
        ....:       _ = v_4_1_BIBD(n, check = True)              # long time

    TESTS:

    Check that the `(25,4)` and `(37,4)`-difference family are available::

        sage: assert designs.difference_family(25,4,existence=True)
        sage: _ = designs.difference_family(25,4)
        sage: assert designs.difference_family(37,4,existence=True)
        sage: _ = designs.difference_family(37,4)

    Check some larger `(v,4,1)`-BIBD (see :trac:`17557`)::

        sage: for v in range(400):                                      # long time
        ....:     if v%12 in [1,4]:                                     # long time
        ....:         _ = designs.balanced_incomplete_block_design(v,4) # long time
    """
    k = 4
    if v == 0:
        return []
    if v <= 12 or v%12 not in [1,4]:
        raise EmptySetError("A K_4-decomposition of K_v exists iif v=2,4 mod 12, v>12 or v==0")

    # Step 1. Base cases.
    if v == 13:
        # note: this construction can also be obtained from difference_family
        from block_design import projective_plane
        return projective_plane(3)._blocks
    if v == 16:
        from block_design import AffineGeometryDesign
        from sage.rings.finite_rings.constructor import FiniteField
        return AffineGeometryDesign(2,1,FiniteField(4,'x'))._blocks
    if v == 25 or v == 37:
        from difference_family import difference_family
        G,D = difference_family(v,4)
        return BIBD_from_difference_family(G,D,check=False)
    if v == 28:
        return [[0, 1, 23, 26], [0, 2, 10, 11], [0, 3, 16, 18], [0, 4, 15, 20],
                [0, 5, 8, 9], [0, 6, 22, 25], [0, 7, 14, 21], [0, 12, 17, 27],
                [0, 13, 19, 24], [1, 2, 24, 27], [1, 3, 11, 12], [1, 4, 17, 19],
                [1, 5, 14, 16], [1, 6, 9, 10], [1, 7, 20, 25], [1, 8, 15, 22],
                [1, 13, 18, 21], [2, 3, 21, 25], [2, 4, 12, 13], [2, 5, 18, 20],
                [2, 6, 15, 17], [2, 7, 19, 22], [2, 8, 14, 26], [2, 9, 16, 23],
                [3, 4, 22, 26], [3, 5, 7, 13], [3, 6, 14, 19], [3, 8, 20, 23],
                [3, 9, 15, 27], [3, 10, 17, 24], [4, 5, 23, 27], [4, 6, 7, 8],
                [4, 9, 14, 24], [4, 10, 16, 21], [4, 11, 18, 25], [5, 6, 21, 24],
                [5, 10, 15, 25], [5, 11, 17, 22], [5, 12, 19, 26], [6, 11, 16, 26],
                [6, 12, 18, 23], [6, 13, 20, 27], [7, 9, 17, 18], [7, 10, 26, 27],
                [7, 11, 23, 24], [7, 12, 15, 16], [8, 10, 18, 19], [8, 11, 21, 27],
                [8, 12, 24, 25], [8, 13, 16, 17], [9, 11, 19, 20], [9, 12, 21, 22],
                [9, 13, 25, 26], [10, 12, 14, 20], [10, 13, 22, 23], [11, 13, 14, 15],
                [14, 17, 23, 25], [14, 18, 22, 27], [15, 18, 24, 26], [15, 19, 21, 23],
                [16, 19, 25, 27], [16, 20, 22, 24], [17, 20, 21, 26]]

    # Step 2 : this is function PBD_4_5_8_9_12
    PBD = PBD_4_5_8_9_12((v-1)/(k-1),check=False)

    # Step 3 : Theorem 7.20
    bibd = BIBD_from_PBD(PBD,v,k,check=False)

    if check:
        assert is_pairwise_balanced_design(bibd,v,[k])

    return bibd
コード例 #4
0
def balanced_incomplete_block_design(v, k, existence=False, use_LJCR=False):
    r"""
    Return a BIBD of parameters `v,k`.

    A Balanced Incomplete Block Design of parameters `v,k` is a collection
    `\mathcal C` of `k`-subsets of `V=\{0,\dots,v-1\}` such that for any two
    distinct elements `x,y\in V` there is a unique element `S\in \mathcal C`
    such that `x,y\in S`.

    More general definitions sometimes involve a `\lambda` parameter, and we
    assume here that `\lambda=1`.

    For more information on BIBD, see the
    :wikipedia:`corresponding Wikipedia entry <Block_design#Definition_of_a_BIBD_.28or_2-design.29>`.

    INPUT:

    - ``v,k`` (integers)

    - ``existence`` (boolean) -- instead of building the design, return:

        - ``True`` -- meaning that Sage knows how to build the design

        - ``Unknown`` -- meaning that Sage does not know how to build the
          design, but that the design may exist (see :mod:`sage.misc.unknown`).

        - ``False`` -- meaning that the design does not exist.

    - ``use_LJCR`` (boolean) -- whether to query the La Jolla Covering
      Repository for the design when Sage does not know how to build it (see
      :func:`~sage.combinat.designs.covering_design.best_known_covering_design_www`). This
      requires internet.

    .. SEEALSO::

        * :func:`steiner_triple_system`
        * :func:`v_4_1_BIBD`
        * :func:`v_5_1_BIBD`

    TODO:

        * Implement other constructions from the Handbook of Combinatorial
          Designs.

    EXAMPLES::

        sage: designs.balanced_incomplete_block_design(7, 3).blocks()
        [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]]
        sage: B = designs.balanced_incomplete_block_design(66, 6, use_LJCR=True) # optional - internet
        sage: B                                                              # optional - internet
        Incidence structure with 66 points and 143 blocks
        sage: B.blocks()                                                     # optional - internet
        [[0, 1, 2, 3, 4, 65], [0, 5, 24, 25, 39, 57], [0, 6, 27, 38, 44, 55], ...
        sage: designs.balanced_incomplete_block_design(66, 6, use_LJCR=True)  # optional - internet
        Incidence structure with 66 points and 143 blocks
        sage: designs.balanced_incomplete_block_design(141, 6)
        Traceback (most recent call last):
        ...
        NotImplementedError: I don't know how to build a (141,6,1)-BIBD!

    TESTS::

        sage: designs.balanced_incomplete_block_design(85,5,existence=True)
        True
        sage: _ = designs.balanced_incomplete_block_design(85,5)

    A BIBD from a Finite Projective Plane::

        sage: _ = designs.balanced_incomplete_block_design(21,5)

    Some trivial BIBD::

        sage: designs.balanced_incomplete_block_design(10,10)
        (10,10,1)-Balanced Incomplete Block Design
        sage: designs.balanced_incomplete_block_design(1,10)
        (1,0,1)-Balanced Incomplete Block Design

    Existence of BIBD with `k=3,4,5`::

        sage: [v for v in xrange(50) if designs.balanced_incomplete_block_design(v,3,existence=True)]
        [1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49]
        sage: [v for v in xrange(100) if designs.balanced_incomplete_block_design(v,4,existence=True)]
        [1, 4, 13, 16, 25, 28, 37, 40, 49, 52, 61, 64, 73, 76, 85, 88, 97]
        sage: [v for v in xrange(150) if designs.balanced_incomplete_block_design(v,5,existence=True)]
        [1, 5, 21, 25, 41, 45, 61, 65, 81, 85, 101, 105, 121, 125, 141, 145]

    For `k > 5` there are currently very few constructions::

        sage: [v for v in xrange(150) if designs.balanced_incomplete_block_design(v,6,existence=True) is True]
        [1, 6, 31, 91, 121]
        sage: [v for v in xrange(150) if designs.balanced_incomplete_block_design(v,6,existence=True) is Unknown]
        [51, 61, 66, 76, 81, 96, 106, 111, 126, 136, 141]

    Here are some constructions with `k \geq 7` and `v` a prime power::

        sage: designs.balanced_incomplete_block_design(169,7)
        (169,7,1)-Balanced Incomplete Block Design
        sage: designs.balanced_incomplete_block_design(617,8)
        (617,8,1)-Balanced Incomplete Block Design
        sage: designs.balanced_incomplete_block_design(433,9)
        (433,9,1)-Balanced Incomplete Block Design
        sage: designs.balanced_incomplete_block_design(1171,10)
        (1171,10,1)-Balanced Incomplete Block Design

    And we know some inexistence results::

        sage: designs.balanced_incomplete_block_design(21,6,existence=True)
        False
    """
    lmbd = 1

    # Trivial BIBD
    if v == 1:
        if existence:
            return True
        return BalancedIncompleteBlockDesign(v, [], check=False)

    if k == v:
        if existence:
            return True
        return BalancedIncompleteBlockDesign(v, [range(v)],
                                             check=False,
                                             copy=False)

    # Non-existence of BIBD
    if (v < k or k < 2 or (v - 1) % (k - 1) != 0
            or (v * (v - 1)) % (k * (k - 1)) != 0 or
            # From the Handbook of combinatorial designs:
            #
            # With lambda>1 other exceptions are
            # (15,5,2),(21,6,2),(22,7,2),(22,8,4).
        (k == 6 and v in [36, 46]) or (k == 7 and v == 43) or
            # Fisher's inequality
        (v * (v - 1)) / (k * (k - 1)) < v):
        if existence:
            return False
        raise EmptySetError("There exists no ({},{},{})-BIBD".format(
            v, k, lmbd))

    if k == 2:
        if existence:
            return True
        from itertools import combinations
        return BalancedIncompleteBlockDesign(v,
                                             combinations(range(v), 2),
                                             check=False,
                                             copy=True)
    if k == 3:
        if existence:
            return v % 6 == 1 or v % 6 == 3
        return steiner_triple_system(v)
    if k == 4:
        if existence:
            return v % 12 == 1 or v % 12 == 4
        return BalancedIncompleteBlockDesign(v, v_4_1_BIBD(v), copy=False)
    if k == 5:
        if existence:
            return v % 20 == 1 or v % 20 == 5
        return BalancedIncompleteBlockDesign(v, v_5_1_BIBD(v), copy=False)

    from difference_family import difference_family
    from database import BIBD_constructions

    if (v, k, 1) in BIBD_constructions:
        if existence:
            return True
        return BlockDesign(v, BIBD_constructions[(v, k, 1)](), copy=False)
    if BIBD_from_TD(v, k, existence=True):
        if existence:
            return True
        return BalancedIncompleteBlockDesign(v, BIBD_from_TD(v, k), copy=False)
    if v == (k - 1)**2 + k and is_prime_power(k - 1):
        if existence:
            return True
        from block_design import projective_plane
        return BalancedIncompleteBlockDesign(v,
                                             projective_plane(k - 1),
                                             copy=False)
    if difference_family(v, k, existence=True):
        if existence:
            return True
        G, D = difference_family(v, k)
        return BalancedIncompleteBlockDesign(v,
                                             BIBD_from_difference_family(
                                                 G, D, check=False),
                                             copy=False)
    if use_LJCR:
        from covering_design import best_known_covering_design_www
        B = best_known_covering_design_www(v, k, 2)

        # Is it a BIBD or just a good covering ?
        expected_n_of_blocks = binomial(v, 2) / binomial(k, 2)
        if B.low_bd() > expected_n_of_blocks:
            if existence:
                return False
            raise EmptySetError("There exists no ({},{},{})-BIBD".format(
                v, k, lmbd))
        B = B.incidence_structure()
        if B.num_blocks() == expected_n_of_blocks:
            if existence:
                return True
            else:
                return B

    if existence:
        return Unknown
    else:
        raise NotImplementedError(
            "I don't know how to build a ({},{},1)-BIBD!".format(v, k))
コード例 #5
0
def v_4_1_BIBD(v, check=True):
    r"""
    Return a `(v,4,1)`-BIBD.

    A `(v,4,1)`-BIBD is an edge-decomposition of the complete graph `K_v` into
    copies of `K_4`. For more information, see
    :func:`balanced_incomplete_block_design`. It exists if and only if `v\equiv 1,4
    \pmod {12}`.

    See page 167 of [Stinson2004]_ for the construction details.

    .. SEEALSO::

        * :func:`balanced_incomplete_block_design`

    INPUT:

    - ``v`` (integer) -- number of points.

    - ``check`` (boolean) -- whether to check that output is correct before
      returning it. As this is expected to be useless (but we are cautious
      guys), you may want to disable it whenever you want speed. Set to ``True``
      by default.

    EXAMPLES::

        sage: from sage.combinat.designs.bibd import v_4_1_BIBD  # long time
        sage: for n in range(13,100):                            # long time
        ....:    if n%12 in [1,4]:                               # long time
        ....:       _ = v_4_1_BIBD(n, check = True)              # long time

    TESTS:

    Check that the `(25,4)` and `(37,4)`-difference family are available::

        sage: assert designs.difference_family(25,4,existence=True)
        sage: _ = designs.difference_family(25,4)
        sage: assert designs.difference_family(37,4,existence=True)
        sage: _ = designs.difference_family(37,4)

    Check some larger `(v,4,1)`-BIBD (see :trac:`17557`)::

        sage: for v in range(400):                                      # long time
        ....:     if v%12 in [1,4]:                                     # long time
        ....:         _ = designs.balanced_incomplete_block_design(v,4) # long time
    """
    k = 4
    if v == 0:
        return []
    if v <= 12 or v % 12 not in [1, 4]:
        raise EmptySetError(
            "A K_4-decomposition of K_v exists iif v=2,4 mod 12, v>12 or v==0")

    # Step 1. Base cases.
    if v == 13:
        # note: this construction can also be obtained from difference_family
        from block_design import projective_plane
        return projective_plane(3)._blocks
    if v == 16:
        from block_design import AffineGeometryDesign
        from sage.rings.finite_rings.constructor import FiniteField
        return AffineGeometryDesign(2, 1, FiniteField(4, 'x'))._blocks
    if v == 25 or v == 37:
        from difference_family import difference_family
        G, D = difference_family(v, 4)
        return BIBD_from_difference_family(G, D, check=False)
    if v == 28:
        return [[0, 1, 23, 26], [0, 2, 10, 11], [0, 3, 16, 18], [0, 4, 15, 20],
                [0, 5, 8, 9], [0, 6, 22, 25], [0, 7, 14, 21], [0, 12, 17, 27],
                [0, 13, 19, 24],
                [1, 2, 24, 27], [1, 3, 11, 12], [1, 4, 17, 19], [1, 5, 14, 16],
                [1, 6, 9, 10], [1, 7, 20, 25], [1, 8, 15, 22], [1, 13, 18, 21],
                [2, 3, 21, 25], [2, 4, 12, 13], [2, 5, 18, 20], [2, 6, 15, 17],
                [2, 7, 19, 22], [2, 8, 14, 26], [2, 9, 16, 23], [3, 4, 22, 26],
                [3, 5, 7, 13], [3, 6, 14, 19], [3, 8, 20, 23], [3, 9, 15, 27],
                [3, 10, 17, 24], [4, 5, 23, 27], [4, 6, 7, 8], [4, 9, 14, 24],
                [4, 10, 16, 21], [4, 11, 18, 25], [5, 6, 21, 24],
                [5, 10, 15, 25], [5, 11, 17, 22], [5, 12, 19, 26],
                [6, 11, 16, 26], [6, 12, 18, 23], [6, 13, 20, 27],
                [7, 9, 17, 18], [7, 10, 26, 27], [7, 11, 23, 24],
                [7, 12, 15, 16], [8, 10, 18, 19], [8, 11, 21, 27],
                [8, 12, 24, 25], [8, 13, 16, 17], [9, 11, 19, 20],
                [9, 12, 21, 22], [9, 13, 25, 26], [10, 12, 14, 20],
                [10, 13, 22, 23], [11, 13, 14, 15], [14, 17, 23, 25],
                [14, 18, 22, 27], [15, 18, 24, 26], [15, 19, 21, 23],
                [16, 19, 25, 27], [16, 20, 22, 24], [17, 20, 21, 26]]

    # Step 2 : this is function PBD_4_5_8_9_12
    PBD = PBD_4_5_8_9_12((v - 1) / (k - 1), check=False)

    # Step 3 : Theorem 7.20
    bibd = BIBD_from_PBD(PBD, v, k, check=False)

    if check:
        assert is_pairwise_balanced_design(bibd, v, [k])

    return bibd
コード例 #6
0
def v_5_1_BIBD(v, check=True):
    r"""
    Return a `(v,5,1)`-BIBD.

    This method follows the constuction from [ClaytonSmith]_.

    INPUT:

    - ``v`` (integer)

    .. SEEALSO::

        * :func:`balanced_incomplete_block_design`

    EXAMPLES::

        sage: from sage.combinat.designs.bibd import v_5_1_BIBD
        sage: i = 0
        sage: while i<200:
        ....:    i += 20
        ....:    _ = v_5_1_BIBD(i+1)
        ....:    _ = v_5_1_BIBD(i+5)

    TESTS:

    Check that the needed difference families are there::

        sage: for v in [21,41,61,81,141,161,281]:
        ....:     assert designs.difference_family(v,5,existence=True)
        ....:     _ = designs.difference_family(v,5)
    """
    v = int(v)

    assert (v > 1)
    assert (v % 20 == 5 or v % 20 == 1
            )  # note: equivalent to (v-1)%4 == 0 and (v*(v-1))%20 == 0

    # Lemma 27
    if v % 5 == 0 and (v // 5) % 4 == 1 and is_prime_power(v // 5):
        bibd = BIBD_5q_5_for_q_prime_power(v // 5)
    # Lemma 28
    elif v in [21, 41, 61, 81, 141, 161, 281]:
        from difference_family import difference_family
        G, D = difference_family(v, 5)
        bibd = BIBD_from_difference_family(G, D, check=False)
    # Lemma 29
    elif v == 165:
        bibd = BIBD_from_PBD(v_5_1_BIBD(41, check=False), 165, 5, check=False)
    elif v == 181:
        bibd = BIBD_from_PBD(v_5_1_BIBD(45, check=False), 181, 5, check=False)
    elif v in (201, 285, 301, 401, 421, 425):
        # Call directly the BIBD_from_TD function
        # note: there are (201,5,1) and (421,5)-difference families that can be
        # obtained from the general constructor
        bibd = BIBD_from_TD(v, 5)
    # Theorem 31.2
    elif (v - 1) // 4 in [
            80, 81, 85, 86, 90, 91, 95, 96, 110, 111, 115, 116, 120, 121, 250,
            251, 255, 256, 260, 261, 265, 266, 270, 271
    ]:
        r = (v - 1) // 4
        if r <= 96:
            k, t, u = 5, 16, r - 80
        elif r <= 121:
            k, t, u = 10, 11, r - 110
        else:
            k, t, u = 10, 25, r - 250
        bibd = BIBD_from_PBD(PBD_from_TD(k, t, u), v, 5, check=False)

    else:
        r, s, t, u = _get_r_s_t_u(v)
        bibd = BIBD_from_PBD(PBD_from_TD(5, t, u), v, 5, check=False)

    if check:
        assert is_pairwise_balanced_design(bibd, v, [5])

    return bibd