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)
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)
def higher_level_UpGj(p, N, klist, m, modformsring, bound): r""" Returns a list ``[A_k]`` of square matrices over ``IntegerRing(p^m)`` parameterised by the weights k in ``klist``. The matrix `A_k` is the finite square matrix which occurs on input p,k,N and m in Step 6 of Algorithm 2 in [AGBL]_. Notational change from paper: In Step 1 following Wan we defined j by `k = k_0 + j(p-1)` with `0 \le k_0 < p-1`. Here we replace j by ``kdiv`` so that we may use j as a column index for matrices.) INPUT: - ``p`` -- prime at least 5. - ``N`` -- integer at least 2 and not divisible by p (level). - ``klist`` -- list of integers all congruent modulo (p-1) (the weights). - ``m`` -- positive integer. - ``modformsring`` -- True or False. - ``bound`` -- (even) positive integer. OUTPUT: - list of square matrices. EXAMPLES:: sage: from sage.modular.overconvergent.hecke_series import higher_level_UpGj sage: higher_level_UpGj(5,3,[4],2,true,6) [ [ 1 0 0 0 0 0] [ 0 1 0 0 0 0] [ 0 7 0 0 0 0] [ 0 5 10 20 0 0] [ 0 7 20 0 20 0] [ 0 1 24 0 20 0] ] """ t = cputime() # Step 1 k0 = klist[0] % (p - 1) n = floor(((p + 1) / (p - 1)) * (m + 1)) elldash = compute_elldash(p, N, k0, n) elldashp = elldash * p mdash = m + ceil(n / (p + 1)) verbose("done step 1", t) t = cputime() # Steps 2 and 3 e, Ep1 = higher_level_katz_exp(p, N, k0, m, mdash, elldash, elldashp, modformsring, bound) ell = dimension(transpose(e)[0].parent()) S = e[0, 0].parent() verbose("done steps 2+3", t) t = cputime() # Step 4 R = Ep1.parent() G = compute_G(p, Ep1) Alist = [] verbose("done step 4a", t) t = cputime() for k in klist: k = ZZ(k) # convert to sage integer kdiv = k // (p - 1) Gkdiv = G**kdiv T = matrix(S, ell, elldash) for i in xrange(ell): ei = R(e[i].list()) Gkdivei = Gkdiv * ei # act by G^kdiv for j in xrange(0, elldash): T[i, j] = Gkdivei[p * j] verbose("done steps 4b and 5", t) t = cputime() # Step 6: solve T = AE using fact E is upper triangular. # Warning: assumes that T = AE (rather than pT = AE) has # a solution over Z/(p^mdash). This has always been the case in # examples computed by the author, see Note 3.1. A = matrix(S, ell, ell) verbose("solving a square matrix problem of dimension %s" % ell) verbose("elldash is %s" % elldash) for i in xrange(0, ell): Ti = T[i] for j in xrange(0, ell): ej = Ti.parent()([e[j][l] for l in xrange(0, elldash)]) ejleadpos = ej.nonzero_positions()[0] lj = ZZ(ej[ejleadpos]) A[i, j] = S(ZZ(Ti[j]) / lj) Ti = Ti - A[i, j] * ej Alist.append(MatrixSpace(Zmod(p**m), ell, ell)(A)) verbose("done step 6", t) return Alist
def higher_level_UpGj(p,N,klist,m,modformsring,bound): r""" Returns a list ``[A_k]`` of square matrices over ``IntegerRing(p^m)`` parameterised by the weights k in ``klist``. The matrix `A_k` is the finite square matrix which occurs on input p,k,N and m in Step 6 of Algorithm 2 in [AGBL]_. Notational change from paper: In Step 1 following Wan we defined j by `k = k_0 + j(p-1)` with `0 \le k_0 < p-1`. Here we replace j by ``kdiv`` so that we may use j as a column index for matrices.) INPUT: - ``p`` -- prime at least 5. - ``N`` -- integer at least 2 and not divisible by p (level). - ``klist`` -- list of integers all congruent modulo (p-1) (the weights). - ``m`` -- positive integer. - ``modformsring`` -- True or False. - ``bound`` -- (even) positive integer. OUTPUT: - list of square matrices. EXAMPLES:: sage: from sage.modular.overconvergent.hecke_series import higher_level_UpGj sage: higher_level_UpGj(5,3,[4],2,true,6) [ [ 1 0 0 0 0 0] [ 0 1 0 0 0 0] [ 0 7 0 0 0 0] [ 0 5 10 20 0 0] [ 0 7 20 0 20 0] [ 0 1 24 0 20 0] ] """ t = cputime() # Step 1 k0 = klist[0] % (p-1) n = floor(((p+1)/(p-1)) * (m+1)) elldash = compute_elldash(p,N,k0,n) elldashp = elldash*p mdash = m + ceil(n/(p+1)) verbose("done step 1",t) t = cputime() # Steps 2 and 3 e,Ep1 = higher_level_katz_exp(p,N,k0,m,mdash,elldash,elldashp,modformsring,bound) ell = dimension(transpose(e)[0].parent()) S = e[0,0].parent() verbose("done steps 2+3", t) t = cputime() # Step 4 R = Ep1.parent() G = compute_G(p, Ep1) Alist = [] verbose("done step 4a", t) t = cputime() for k in klist: k = ZZ(k) # convert to sage integer kdiv = k // (p-1) Gkdiv = G**kdiv T = matrix(S,ell,elldash) for i in xrange(ell): ei = R(e[i].list()) Gkdivei = Gkdiv*ei; # act by G^kdiv for j in xrange(0, elldash): T[i,j] = Gkdivei[p*j] verbose("done steps 4b and 5", t) t = cputime() # Step 6: solve T = AE using fact E is upper triangular. # Warning: assumes that T = AE (rather than pT = AE) has # a solution over Z/(p^mdash). This has always been the case in # examples computed by the author, see Note 3.1. A = matrix(S,ell,ell) verbose("solving a square matrix problem of dimension %s" % ell) verbose("elldash is %s" % elldash) for i in xrange(0,ell): Ti = T[i] for j in xrange(0,ell): ej = Ti.parent()([e[j][l] for l in xrange(0,elldash)]) ejleadpos = ej.nonzero_positions()[0] lj = ZZ(ej[ejleadpos]) A[i,j] = S(ZZ(Ti[j])/lj) Ti = Ti - A[i,j]*ej Alist.append(MatrixSpace(Zmod(p**m),ell,ell)(A)) verbose("done step 6", t) return Alist