예제 #1
0
    def points_from_gap(self):
        """
        Literally pushes this block design over to GAP and returns the
        points of that. Other than debugging, usefulness is unclear.

        REQUIRES: GAP's Design package.

        EXAMPLES::

            sage: from sage.combinat.designs.block_design import BlockDesign
            sage: BD = BlockDesign(7,[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]])
            sage: BD.points_from_gap()      # optional - gap_packages (design package)
            doctest:1: DeprecationWarning: Unless somebody protests this method will be removed, as nobody seems to know why it is there.
            See http://trac.sagemath.org/14499 for details.
            [1, 2, 3, 4, 5, 6, 7]
        """
        from sage.misc.superseded import deprecation
        deprecation(14499, ('Unless somebody protests this method will be '
                            'removed, as nobody seems to know why it is there.'))
        from sage.interfaces.gap import gap, GapElement
        from sage.sets.set import Set
        gap.load_package("design")
        gD = self._gap_()
        gP = gap.eval("BlockDesignPoints("+gD+")").replace("..",",")
        return range(eval(gP)[0],eval(gP)[1]+1)
예제 #2
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
    """
    from sage.interfaces.gap import gap
    gap.load_package("design")
    gap.eval("B:=WittDesign(%s)"%n)
    v = eval(gap.eval("B.v"))
    gblcks = eval(gap.eval("B.blocks"))
    gB = []
    for b in gblcks:
       gB.append([x-1 for x in b])
    return BlockDesign(v, gB, name="WittDesign", check=True)
예제 #3
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
    """
    from sage.interfaces.gap import gap, GapElement
    gap.load_package("design")
    gap.eval("B:=WittDesign(%s)"%n)
    v = eval(gap.eval("B.v"))
    gblcks = eval(gap.eval("B.blocks"))
    gB = []
    for b in gblcks:
       gB.append([x-1 for x in b])
    return BlockDesign(v, gB, name="WittDesign", check=True)
def ProjectiveGeometryDesign(n, d, F, algorithm=None):
    """
    Returns a projective geometry design.

    A projective geometry design of parameters `n,d,F` has for points the lines
    of `F^{n+1}`, and for blocks the `d+1`-dimensional subspaces of `F^{n+1}`,
    each of which contains `\\frac {|F|^{d+1}-1} {|F|-1}` lines.

    INPUT:

    - ``n`` is the projective dimension

    - ``d`` is the dimension of the subspaces of `P = PPn(F)` which
      make up the blocks.

    - ``F`` is a finite field.

    - ``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.

    EXAMPLES:

    The points of the following design are the `\\frac {2^{2+1}-1} {2-1}=7`
    lines of `\mathbb{Z}_2^{2+1}`. It has `7` blocks, corresponding to each
    2-dimensional subspace of `\mathbb{Z}_2^{2+1}`::

        sage: designs.ProjectiveGeometryDesign(2, 1, GF(2))
        Incidence structure with 7 points and 7 blocks
        sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm="gap") # optional - gap_packages (design package)
        sage: BD.is_block_design()                                     # optional - gap_packages (design package)
        (True, [2, 7, 3, 1])
    """
    q = F.order()
    from sage.interfaces.gap import gap, GapElement
    from sage.sets.set import Set
    if algorithm is None:
        V = VectorSpace(F, n + 1)
        points = list(V.subspaces(1))
        flats = list(V.subspaces(d + 1))
        blcks = []
        for p in points:
            b = []
            for i in range(len(flats)):
                if p.is_subspace(flats[i]):
                    b.append(i)
            blcks.append(b)
        v = (q**(n + 1) - 1) / (q - 1)
        return BlockDesign(v, blcks, name="ProjectiveGeometryDesign")
    if algorithm == "gap":  # Requires GAP's Design
        gap.load_package("design")
        gap.eval("D := PGPointFlatBlockDesign( %s, %s, %d )" % (n, q, d))
        v = eval(gap.eval("D.v"))
        gblcks = eval(gap.eval("D.blocks"))
        gB = []
        for b in gblcks:
            gB.append([x - 1 for x in b])
        return BlockDesign(v, gB, name="ProjectiveGeometryDesign")
예제 #5
0
    def dual(self, algorithm=None):
        """
        Return the dual of the incidence structure.

        INPUT:

        - ``algorithm`` -- whether to use Sage's implementation
          (``algorithm=None``, default) or use GAP's (``algorithm="gap"``).

          .. NOTE::

              The ``algorithm="gap"`` option requires GAP's Design package
              (included in the gap_packages Sage spkg).

        EXAMPLES:

        The dual of a projective plane is a projective plane::

            sage: PP = designs.DesarguesianProjectivePlaneDesign(4)
            sage: PP.dual().is_t_design(return_parameters=True)
            (True, (2, 21, 5, 1))

        TESTS::

            sage: D = designs.IncidenceStructure(4, [[0,2],[1,2,3],[2,3]])
            sage: D
            Incidence structure with 4 points and 3 blocks
            sage: D.dual()
            Incidence structure with 3 points and 4 blocks
            sage: print D.dual(algorithm="gap")       # optional - gap_packages
            IncidenceStructure<points=[0, 1, 2], blocks=[[0], [0, 1, 2], [1], [1, 2]]>
            sage: blocks = [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]
            sage: BD = designs.IncidenceStructure(7, blocks, name="FanoPlane");
            sage: BD
            Incidence structure with 7 points and 7 blocks
            sage: print BD.dual(algorithm="gap")         # optional - gap_packages
            IncidenceStructure<points=[0, 1, 2, 3, 4, 5, 6], blocks=[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]]>
            sage: BD.dual()
            Incidence structure with 7 points and 7 blocks

        REFERENCE:

        - Soicher, Leonard, Design package manual, available at
          http://www.gap-system.org/Manuals/pkg/design/htm/CHAP003.htm
        """
        if algorithm == "gap":
            from sage.interfaces.gap import gap
            gap.load_package("design")
            gD = self._gap_()
            gap.eval("DD:=DualBlockDesign("+gD+")")
            v = eval(gap.eval("DD.v"))
            gblcks = eval(gap.eval("DD.blocks"))
            gB = []
            for b in gblcks:
                gB.append([x-1 for x in b])
            return IncidenceStructure(range(v), gB, name=None, check=False)
        else:
            return IncidenceStructure(
                          incidence_matrix=self.incidence_matrix().transpose(),
                          check=False)
예제 #6
0
def ProjectiveGeometryDesign(n, d, F, algorithm=None):
    """
    Returns a projective geometry design.

    A projective geometry design of parameters `n,d,F` has for points the lines
    of `F^{n+1}`, and for blocks the `d+1`-dimensional subspaces of `F^{n+1}`,
    each of which contains `\\frac {|F|^{d+1}-1} {|F|-1}` lines.

    INPUT:

    - ``n`` is the projective dimension

    - ``d`` is the dimension of the subspaces of `P = PPn(F)` which
      make up the blocks.

    - ``F`` is a finite field.

    - ``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.

    EXAMPLES:

    The points of the following design are the `\\frac {2^{2+1}-1} {2-1}=7`
    lines of `\mathbb{Z}_2^{2+1}`. It has `7` blocks, corresponding to each
    2-dimensional subspace of `\mathbb{Z}_2^{2+1}`::

        sage: designs.ProjectiveGeometryDesign(2, 1, GF(2))
        Incidence structure with 7 points and 7 blocks
        sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm="gap") # optional - gap_packages (design package)
        sage: BD.is_block_design()                                     # optional - gap_packages (design package)
        (True, [2, 7, 3, 1])
    """
    q = F.order()
    from sage.interfaces.gap import gap, GapElement
    from sage.sets.set import Set
    if algorithm is None:
        V = VectorSpace(F, n+1)
        points = list(V.subspaces(1))
        flats = list(V.subspaces(d+1))
        blcks = []
        for p in points:
            b = []
            for i in range(len(flats)):
                if p.is_subspace(flats[i]):
                    b.append(i)
            blcks.append(b)
        v = (q**(n+1)-1)/(q-1)
        return BlockDesign(v, blcks, name="ProjectiveGeometryDesign")
    if algorithm == "gap":   # Requires GAP's Design
        gap.load_package("design")
        gap.eval("D := PGPointFlatBlockDesign( %s, %s, %d )"%(n,q,d))
        v = eval(gap.eval("D.v"))
        gblcks = eval(gap.eval("D.blocks"))
        gB = []
        for b in gblcks:
            gB.append([x-1 for x in b])
        return BlockDesign(v, gB, name="ProjectiveGeometryDesign")
    def points_from_gap(self):
        """
        Literally pushes this block design over to GAP and returns the
        points of that. Other than debugging, usefulness is unclear.

        REQUIRES: GAP's Design package.

        EXAMPLES::

            sage: from sage.combinat.designs.block_design import BlockDesign
            sage: BD = BlockDesign(7,[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]])
            sage: BD.points_from_gap()      # optional - gap_packages (design package)
            doctest:1: DeprecationWarning: Unless somebody protests this method will be removed, as nobody seems to know why it is there.
            See http://trac.sagemath.org/14499 for details.
            [1, 2, 3, 4, 5, 6, 7]
        """
        from sage.misc.superseded import deprecation
        deprecation(14499,
                    ('Unless somebody protests this method will be '
                     'removed, as nobody seems to know why it is there.'))
        from sage.interfaces.gap import gap
        gap.load_package("design")
        gD = self._gap_()
        gP = gap.eval("BlockDesignPoints(" + gD + ")").replace("..", ",")
        return range(eval(gP)[0], eval(gP)[1] + 1)
예제 #8
0
    def dual(self, algorithm=None):
        """
        Return the dual of the incidence structure.

        INPUT:

        - ``algorithm`` -- whether to use Sage's implementation
          (``algorithm=None``, default) or use GAP's (``algorithm="gap"``).

          .. NOTE::

              The ``algorithm="gap"`` option requires GAP's Design package
              (included in the gap_packages Sage spkg).

        EXAMPLES:

        The dual of a projective plane is a projective plane::

            sage: PP = designs.DesarguesianProjectivePlaneDesign(4)
            sage: PP.dual().is_t_design(return_parameters=True)
            (True, (2, 21, 5, 1))

        TESTS::

            sage: D = designs.IncidenceStructure(4, [[0,2],[1,2,3],[2,3]])
            sage: D
            Incidence structure with 4 points and 3 blocks
            sage: D.dual()
            Incidence structure with 3 points and 4 blocks
            sage: print D.dual(algorithm="gap")       # optional - gap_packages
            IncidenceStructure<points=[0, 1, 2], blocks=[[0], [0, 1, 2], [1], [1, 2]]>
            sage: blocks = [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]
            sage: BD = designs.IncidenceStructure(7, blocks, name="FanoPlane");
            sage: BD
            Incidence structure with 7 points and 7 blocks
            sage: print BD.dual(algorithm="gap")         # optional - gap_packages
            IncidenceStructure<points=[0, 1, 2, 3, 4, 5, 6], blocks=[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]]>
            sage: BD.dual()
            Incidence structure with 7 points and 7 blocks

        REFERENCE:

        - Soicher, Leonard, Design package manual, available at
          http://www.gap-system.org/Manuals/pkg/design/htm/CHAP003.htm
        """
        if algorithm == "gap":
            from sage.interfaces.gap import gap
            gap.load_package("design")
            gD = self._gap_()
            gap.eval("DD:=DualBlockDesign(" + gD + ")")
            v = eval(gap.eval("DD.v"))
            gblcks = eval(gap.eval("DD.blocks"))
            gB = []
            for b in gblcks:
                gB.append([x - 1 for x in b])
            return IncidenceStructure(range(v), gB, name=None, check=False)
        else:
            return IncidenceStructure(
                incidence_matrix=self.incidence_matrix().transpose(),
                check=False)
예제 #9
0
    def dual_incidence_structure(self, algorithm=None):
        """
        Wraps GAP Design's DualBlockDesign (see [1]). The dual of a block
        design may not be a block design.

        Also can be called with ``dual_design``.

        .. NOTE:

        The algorithm="gap" option requires GAP's Design package (included in
        the gap_packages Sage spkg).

        EXAMPLES::

            sage: from sage.combinat.designs.block_design import BlockDesign
            sage: D = BlockDesign(4, [[0,2],[1,2,3],[2,3]], test=False)
            sage: D
            Incidence structure with 4 points and 3 blocks
            sage: D.dual_design()
            Incidence structure with 3 points and 4 blocks
            sage: print D.dual_design(algorithm="gap")       # optional - gap_design
            IncidenceStructure<points=[0, 1, 2], blocks=[[0], [0, 1, 2], [1], [1, 2]]>
            sage: BD = IncidenceStructure(range(7),[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]], name="FanoPlane")
            sage: BD
            Incidence structure with 7 points and 7 blocks
            sage: print BD.dual_design(algorithm="gap")         # optional - gap_design
            IncidenceStructure<points=[0, 1, 2, 3, 4, 5, 6], blocks=[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]]>
            sage: BD.dual_incidence_structure()
            Incidence structure with 7 points and 7 blocks

        REFERENCE:

        - Soicher, Leonard, Design package manual, available at
          http://www.gap-system.org/Manuals/pkg/design/htm/CHAP003.htm
        """
        from sage.interfaces.gap import gap, GapElement
        from sage.sets.set import Set
        from sage.misc.flatten import flatten
        from sage.combinat.designs.block_design import BlockDesign
        from sage.misc.functional import transpose

        if algorithm == "gap":
            gap.load_package("design")
            gD = self._gap_()
            gap.eval("DD:=DualBlockDesign(" + gD + ")")
            v = eval(gap.eval("DD.v"))
            gblcks = eval(gap.eval("DD.blocks"))
            gB = []
            for b in gblcks:
                gB.append([x - 1 for x in b])
            return IncidenceStructure(range(v), gB, name=None, test=False)
        pts = self.blocks()
        M = transpose(self.incidence_matrix())
        blks = self.points()
        return IncidenceStructure(pts, blks, M, name=None, test=False)
예제 #10
0
    def dual_incidence_structure(self, algorithm=None):
        """
        Wraps GAP Design's DualBlockDesign (see [1]). The dual of a block
        design may not be a block design.

        Also can be called with ``dual_design``.

        .. NOTE:

        The algorithm="gap" option requires GAP's Design package (included in
        the gap_packages Sage spkg).

        EXAMPLES::

            sage: from sage.combinat.designs.block_design import BlockDesign
            sage: D = BlockDesign(4, [[0,2],[1,2,3],[2,3]], test=False)
            sage: D
            Incidence structure with 4 points and 3 blocks
            sage: D.dual_design()
            Incidence structure with 3 points and 4 blocks
            sage: print D.dual_design(algorithm="gap")       # optional - gap_design
            IncidenceStructure<points=[0, 1, 2], blocks=[[0], [0, 1, 2], [1], [1, 2]]>
            sage: BD = IncidenceStructure(range(7),[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]], name="FanoPlane")
            sage: BD
            Incidence structure with 7 points and 7 blocks
            sage: print BD.dual_design(algorithm="gap")         # optional - gap_design
            IncidenceStructure<points=[0, 1, 2, 3, 4, 5, 6], blocks=[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]]>
            sage: BD.dual_incidence_structure()
            Incidence structure with 7 points and 7 blocks

        REFERENCE:

        - Soicher, Leonard, Design package manual, available at
          http://www.gap-system.org/Manuals/pkg/design/htm/CHAP003.htm
        """
        from sage.interfaces.gap import gap, GapElement
        from sage.sets.set import Set
        from sage.misc.flatten import flatten
        from sage.combinat.designs.block_design import BlockDesign
        from sage.misc.functional import transpose
        if algorithm=="gap":
            gap.load_package("design")
            gD = self._gap_()
            gap.eval("DD:=DualBlockDesign("+gD+")")
            v = eval(gap.eval("DD.v"))
            gblcks = eval(gap.eval("DD.blocks"))
            gB = []
            for b in gblcks:
                gB.append([x-1 for x in b])
            return IncidenceStructure(range(v), gB, name=None, test=False)
        pts = self.blocks()
        M = transpose(self.incidence_matrix())
        blks = self.points()
        return IncidenceStructure(pts, blks, M, name=None, test=False)
예제 #11
0
def ProjectiveGeometryDesign(n, d, F, algorithm=None):
    """
    INPUT:

    - ``n`` is the projective dimension

    - ``v`` is the number of points `PPn(GF(q))`

    - ``d`` is the dimension of the subspaces of `P = PPn(GF(q))` which
      make up the blocks

    - ``b`` is the number of `d`-dimensional subspaces of `P`

    Wraps GAP Design's PGPointFlatBlockDesign. Does *not* require
    GAP's Design.

    EXAMPLES::

        sage: designs.ProjectiveGeometryDesign(2, 1, GF(2))
        Incidence structure with 7 points and 7 blocks
        sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm="gap") # optional - gap_packages (design package)
        sage: BD.is_block_design()                                     # optional - gap_packages (design package)
        (True, [2, 7, 3, 1])
    """
    q = F.order()
    from sage.interfaces.gap import gap, GapElement
    from sage.sets.set import Set
    if algorithm == None:
        V = VectorSpace(F, n + 1)
        points = list(V.subspaces(1))
        flats = list(V.subspaces(d + 1))
        blcks = []
        for p in points:
            b = []
            for i in range(len(flats)):
                if p.is_subspace(flats[i]):
                    b.append(i)
            blcks.append(b)
        v = (q**(n + 1) - 1) / (q - 1)
        return BlockDesign(v, blcks, name="ProjectiveGeometryDesign")
    if algorithm == "gap":  # Requires GAP's Design
        gap.load_package("design")
        gap.eval("D := PGPointFlatBlockDesign( %s, %s, %d )" % (n, q, d))
        v = eval(gap.eval("D.v"))
        gblcks = eval(gap.eval("D.blocks"))
        gB = []
        for b in gblcks:
            gB.append([x - 1 for x in b])
        return BlockDesign(v, gB, name="ProjectiveGeometryDesign")
예제 #12
0
def ProjectiveGeometryDesign(n, d, F, algorithm=None):
    """
    INPUT:

    - ``n`` is the projective dimension

    - ``v`` is the number of points `PPn(GF(q))`

    - ``d`` is the dimension of the subspaces of `P = PPn(GF(q))` which
      make up the blocks

    - ``b`` is the number of `d`-dimensional subspaces of `P`

    Wraps GAP Design's PGPointFlatBlockDesign. Does *not* require
    GAP's Design.

    EXAMPLES::

        sage: designs.ProjectiveGeometryDesign(2, 1, GF(2))
        Incidence structure with 7 points and 7 blocks
        sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm="gap") # optional - gap_packages (design package)
        sage: BD.is_block_design()                                     # optional - gap_packages (design package)
        (True, [2, 7, 3, 1])
    """
    q = F.order()
    from sage.interfaces.gap import gap, GapElement
    from sage.sets.set import Set
    if algorithm == None:
        V = VectorSpace(F, n+1)
        points = list(V.subspaces(1))
        flats = list(V.subspaces(d+1))
        blcks = []
        for p in points:
            b = []
            for i in range(len(flats)):
                if p.is_subspace(flats[i]):
                    b.append(i)
            blcks.append(b)
        v = (q**(n+1)-1)/(q-1)
        return BlockDesign(v, blcks, name="ProjectiveGeometryDesign")
    if algorithm == "gap":   # Requires GAP's Design
        gap.load_package("design")
        gap.eval("D := PGPointFlatBlockDesign( %s, %s, %d )"%(n,q,d))
        v = eval(gap.eval("D.v"))
        gblcks = eval(gap.eval("D.blocks"))
        gB = []
        for b in gblcks:
            gB.append([x-1 for x in b])
        return BlockDesign(v, gB, name="ProjectiveGeometryDesign")
예제 #13
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.parameters()      # optional - gap_packages (design package)
        (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)
        WittDesign<points=[0, 1, 2, 3, 4, 5, 6, 7, 8], blocks=[[0, 1, 7], [0, 2, 5], [0, 3, 4], [0, 6, 8], [1, 2, 6], [1, 3, 5], [1, 4, 8], [2, 3, 8], [2, 4, 7], [3, 6, 7], [4, 5, 6], [5, 7, 8]]>
        sage: BD = designs.WittDesign(12)  # optional - gap_packages (design package)
        sage: BD.parameters(t=5)   # optional - gap_packages (design package)
        (5, 12, 6, 1)
    """
    from sage.interfaces.gap import gap, GapElement
    gap.load_package("design")
    gap.eval("B:=WittDesign(%s)" % n)
    v = eval(gap.eval("B.v"))
    gblcks = eval(gap.eval("B.blocks"))
    gB = []
    for b in gblcks:
        gB.append([x - 1 for x in b])
    return BlockDesign(v, gB, name="WittDesign", test=True)
예제 #14
0
def ProjectiveGeometryDesign(n, d, F, algorithm=None, check=True):
    """
    Return a projective geometry design.

    A projective geometry design of parameters `n,d,F` has for points the lines
    of `F^{n+1}`, and for blocks the `d+1`-dimensional subspaces of `F^{n+1}`,
    each of which contains `\\frac {|F|^{d+1}-1} {|F|-1}` lines.

    INPUT:

    - ``n`` is the projective dimension

    - ``d`` is the dimension of the subspaces of `P = PPn(F)` which
      make up the blocks.

    - ``F`` is a finite field.

    - ``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.

    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,'z'))
        sage: PG.is_t_design(return_parameters=True)
        (True, (2, 85, 5, 1))

    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))
    """
    if algorithm is None:
        from sage.matrix.echelon_matrix import reduced_echelon_matrix_iterator
        from copy import copy

        points = {}
        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)
        return BlockDesign(len(points),
                           blocks,
                           name="ProjectiveGeometryDesign",
                           check=check)
    if algorithm == "gap":  # Requires GAP's Design
        from sage.interfaces.gap import gap
        gap.load_package("design")
        gap.eval("D := PGPointFlatBlockDesign( %s, %s, %d )" %
                 (n, F.order(), d))
        v = eval(gap.eval("D.v"))
        gblcks = eval(gap.eval("D.blocks"))
        gB = []
        for b in gblcks:
            gB.append([x - 1 for x in b])
        return BlockDesign(v, gB, name="ProjectiveGeometryDesign", check=check)
예제 #15
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 six.iteritems(points)})

    elif algorithm == "gap":   # Requires GAP's Design
        from sage.interfaces.gap import gap
        gap.load_package("design")
        gap.eval("D := PGPointFlatBlockDesign( %s, %s, %d )"%(n,F.order(),d))
        v = eval(gap.eval("D.v"))
        gblcks = eval(gap.eval("D.blocks"))
        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
예제 #16
0
    def dual_incidence_structure(self, algorithm=None):
        """
        Returns the dual of the incidence structure.

        Note that the dual of a block design may not be a block design.

        INPUT:

        - ``algorithm`` -- whether to use Sage's implementation
          (``algorithm=None``, default) or use GAP's (``algorithm="gap"``).

          .. NOTE::

              The ``algorithm="gap"`` option requires GAP's Design package
              (included in the gap_packages Sage spkg).

        Also can be called with ``dual_design``.

        EXAMPLES:

        The dual of a projective plane is a projective plane::

            sage: PP = designs.ProjectivePlaneDesign(4)
            sage: PP.dual_design().is_block_design()
            (True, [2, 21, 5, 1])
            sage: PP = designs.ProjectivePlaneDesign(4)             # optional - gap_packages
            sage: PP.dual_design(algorithm="gap").is_block_design() # optional - gap_packages
            (True, [2, 21, 5, 1])

        TESTS::

            sage: from sage.combinat.designs.block_design import BlockDesign
            sage: D = BlockDesign(4, [[0,2],[1,2,3],[2,3]], test=False)
            sage: D
            Incidence structure with 4 points and 3 blocks
            sage: D.dual_design()
            Incidence structure with 3 points and 4 blocks
            sage: print D.dual_design(algorithm="gap")       # optional - gap_packages
            IncidenceStructure<points=[0, 1, 2], blocks=[[0], [0, 1, 2], [1], [1, 2]]>
            sage: BD = IncidenceStructure(range(7),[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]], name="FanoPlane")
            sage: BD
            Incidence structure with 7 points and 7 blocks
            sage: print BD.dual_design(algorithm="gap")         # optional - gap_packages
            IncidenceStructure<points=[0, 1, 2, 3, 4, 5, 6], blocks=[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]]>
            sage: BD.dual_incidence_structure()
            Incidence structure with 7 points and 7 blocks

        REFERENCE:

        - Soicher, Leonard, Design package manual, available at
          http://www.gap-system.org/Manuals/pkg/design/htm/CHAP003.htm
        """
        if algorithm == "gap":
            from sage.interfaces.gap import gap
            gap.load_package("design")
            gD = self._gap_()
            gap.eval("DD:=DualBlockDesign("+gD+")")
            v = eval(gap.eval("DD.v"))
            gblcks = eval(gap.eval("DD.blocks"))
            gB = []
            for b in gblcks:
                gB.append([x-1 for x in b])
            return IncidenceStructure(range(v), gB, name=None, test=False)
        else:
            M = self.incidence_matrix()
            new_blocks = [list(r.dict(copy=False)) for r in M.rows()]
            return IncidenceStructure(range(M.ncols()), new_blocks, name=None, test=False)
예제 #17
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.iteritems()})

    elif algorithm == "gap":   # Requires GAP's Design
        from sage.interfaces.gap import gap
        gap.load_package("design")
        gap.eval("D := PGPointFlatBlockDesign( %s, %s, %d )"%(n,F.order(),d))
        v = eval(gap.eval("D.v"))
        gblcks = eval(gap.eval("D.blocks"))
        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
    def dual_incidence_structure(self, algorithm=None):
        """
        Returns the dual of the incidence structure.

        Note that the dual of a block design may not be a block design.

        INPUT:

        - ``algorithm`` -- whether to use Sage's implementation
          (``algorithm=None``, default) or use GAP's (``algorithm="gap"``).

          .. NOTE::

              The ``algorithm="gap"`` option requires GAP's Design package
              (included in the gap_packages Sage spkg).

        Also can be called with ``dual_design``.

        EXAMPLES:

        The dual of a projective plane is a projective plane::

            sage: PP = designs.DesarguesianProjectivePlaneDesign(4)
            sage: PP.dual_design().is_block_design()
            (True, [2, 21, 5, 1])
            sage: PP = designs.DesarguesianProjectivePlaneDesign(4) # optional - gap_packages
            sage: PP.dual_design(algorithm="gap").is_block_design() # optional - gap_packages
            (True, [2, 21, 5, 1])

        TESTS::

            sage: from sage.combinat.designs.block_design import BlockDesign
            sage: D = BlockDesign(4, [[0,2],[1,2,3],[2,3]], test=False)
            sage: D
            Incidence structure with 4 points and 3 blocks
            sage: D.dual_design()
            Incidence structure with 3 points and 4 blocks
            sage: print D.dual_design(algorithm="gap")       # optional - gap_packages
            IncidenceStructure<points=[0, 1, 2], blocks=[[0], [0, 1, 2], [1], [1, 2]]>
            sage: BD = IncidenceStructure(range(7),[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]], name="FanoPlane")
            sage: BD
            Incidence structure with 7 points and 7 blocks
            sage: print BD.dual_design(algorithm="gap")         # optional - gap_packages
            IncidenceStructure<points=[0, 1, 2, 3, 4, 5, 6], blocks=[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]]>
            sage: BD.dual_incidence_structure()
            Incidence structure with 7 points and 7 blocks

        REFERENCE:

        - Soicher, Leonard, Design package manual, available at
          http://www.gap-system.org/Manuals/pkg/design/htm/CHAP003.htm
        """
        if algorithm == "gap":
            from sage.interfaces.gap import gap
            gap.load_package("design")
            gD = self._gap_()
            gap.eval("DD:=DualBlockDesign(" + gD + ")")
            v = eval(gap.eval("DD.v"))
            gblcks = eval(gap.eval("DD.blocks"))
            gB = []
            for b in gblcks:
                gB.append([x - 1 for x in b])
            return IncidenceStructure(range(v), gB, name=None, test=False)
        else:
            M = self.incidence_matrix()
            new_blocks = [list(r.dict(copy=False)) for r in M.rows()]
            return IncidenceStructure(range(M.ncols()),
                                      new_blocks,
                                      name=None,
                                      test=False)
예제 #19
0
def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, check=True):
    """
    Return a projective geometry design.

    A projective geometry design of parameters `n,d,F` has for points the lines
    of `F^{n+1}`, and for blocks the `d+1`-dimensional subspaces of `F^{n+1}`,
    each of which contains `\\frac {|F|^{d+1}-1} {|F|-1}` lines.

    INPUT:

    - ``n`` is the projective dimension

    - ``d`` is the dimension of the subspaces of `P = PPn(F)` which
      make up the blocks.

    - ``F`` is a finite field.

    - ``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 `F^{n+1}`.
      Otherwise the ground set is indexed by integers,

    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,'z'))
        sage: PG.is_t_design(return_parameters=True)
        (True, (2, 85, 5, 1))

    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))
    """
    if algorithm is None:
        from sage.matrix.echelon_matrix import reduced_echelon_matrix_iterator
        from copy import copy

        points = {}
        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.iteritems()})
        return B
    if algorithm == "gap":   # Requires GAP's Design
        from sage.interfaces.gap import gap
        gap.load_package("design")
        gap.eval("D := PGPointFlatBlockDesign( %s, %s, %d )"%(n,F.order(),d))
        v = eval(gap.eval("D.v"))
        gblcks = eval(gap.eval("D.blocks"))
        gB = []
        for b in gblcks:
            gB.append([x-1 for x in b])
        return BlockDesign(v, gB, name="ProjectiveGeometryDesign", check=check)