def symmetric_conference_matrix(n, check=True): r""" Tries to construct a symmetric conference matrix A conference matrix is an `n\times n` matrix `C` with 0s on the main diagonal and 1s and -1s elsewhere, satisfying `CC^\top=(n-1)I`. If `C=C^\top$ then `n \cong 2 \mod 4` and `C` is Seidel adjacency matrix of a graph, whose descendent graphs are strongly regular graphs with parameters `(n-1,(n-2)/2,(n-6)/4,(n-2)/4)`, see Sec.10.4 of [BH12]_. Thus we build `C` from the Seidel adjacency matrix of the latter by adding row and column of 1s. INPUT: - ``n`` (integer) -- dimension of the matrix - ``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.matrices.hadamard_matrix import symmetric_conference_matrix sage: C=symmetric_conference_matrix(10); C [ 0 1 1 1 1 1 1 1 1 1] [ 1 0 -1 -1 1 -1 1 1 1 -1] [ 1 -1 0 -1 1 1 -1 -1 1 1] [ 1 -1 -1 0 -1 1 1 1 -1 1] [ 1 1 1 -1 0 -1 -1 1 -1 1] [ 1 -1 1 1 -1 0 -1 1 1 -1] [ 1 1 -1 1 -1 -1 0 -1 1 1] [ 1 1 -1 1 1 1 -1 0 -1 -1] [ 1 1 1 -1 -1 1 1 -1 0 -1] [ 1 -1 1 1 1 -1 1 -1 -1 0] sage: C^2==9*identity_matrix(10) and C==C.T True """ from sage.graphs.strongly_regular_db import strongly_regular_graph as srg try: m = srg(n - 1, (n - 2) / 2, (n - 6) / 4, (n - 2) / 4) except ValueError: raise C = matrix([0] + [1] * (n - 1)).stack( matrix([1] * (n - 1)).stack(m.seidel_adjacency_matrix()).T) if check: assert (C == C.T and C**2 == (n - 1) * I(n)) return C
def symmetric_conference_matrix(n, check=True): r""" Tries to construct a symmetric conference matrix A conference matrix is an `n\times n` matrix `C` with 0s on the main diagonal and 1s and -1s elsewhere, satisfying `CC^\top=(n-1)I`. If `C=C^\top$ then `n \cong 2 \mod 4` and `C` is Seidel adjacency matrix of a graph, whose descendent graphs are strongly regular graphs with parameters `(n-1,(n-2)/2,(n-6)/4,(n-2)/4)`, see Sec.10.4 of [BH12]_. Thus we build `C` from the Seidel adjacency matrix of the latter by adding row and column of 1s. INPUT: - ``n`` (integer) -- dimension of the matrix - ``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.matrices.hadamard_matrix import symmetric_conference_matrix sage: C=symmetric_conference_matrix(10); C [ 0 1 1 1 1 1 1 1 1 1] [ 1 0 -1 -1 1 -1 1 1 1 -1] [ 1 -1 0 -1 1 1 -1 -1 1 1] [ 1 -1 -1 0 -1 1 1 1 -1 1] [ 1 1 1 -1 0 -1 -1 1 -1 1] [ 1 -1 1 1 -1 0 -1 1 1 -1] [ 1 1 -1 1 -1 -1 0 -1 1 1] [ 1 1 -1 1 1 1 -1 0 -1 -1] [ 1 1 1 -1 -1 1 1 -1 0 -1] [ 1 -1 1 1 1 -1 1 -1 -1 0] sage: C^2==9*identity_matrix(10) and C==C.T True """ from sage.graphs.strongly_regular_db import strongly_regular_graph as srg try: m = srg(n-1,(n-2)/2,(n-6)/4,(n-2)/4) except ValueError: raise C = matrix([0]+[1]*(n-1)).stack(matrix([1]*(n-1)).stack(m.seidel_adjacency_matrix()).T) if check: assert (C==C.T and C**2==(n-1)*I(n)) return C
def rshcd_from_prime_power_and_conference_matrix(n): r""" Return a `((n-1)^2,1)`-RSHCD if `n` is prime power, and symmetric `(n-1)`-conference matrix exists The construction implemented here is Theorem 16 (and Corollary 17) from [WW72]_. In [SWW72]_ this construction (Theorem 5.15 and Corollary 5.16) is reproduced with a typo. Note that [WW72]_ refers to [Sz69]_ for the construction, provided by :func:`szekeres_difference_set_pair`, of complementary difference sets, and the latter has a typo. From a :func:`symmetric_conference_matrix`, we only need the Seidel adjacency matrix of the underlying strongly regular conference (i.e. Paley type) graph, which we construct directly. INPUT: - ``n`` -- an integer .. SEEALSO:: :func:`regular_symmetric_hadamard_matrix_with_constant_diagonal` EXAMPLES: A 36x36 example :: sage: from sage.combinat.matrices.hadamard_matrix import rshcd_from_prime_power_and_conference_matrix sage: from sage.combinat.matrices.hadamard_matrix import is_hadamard_matrix sage: H = rshcd_from_prime_power_and_conference_matrix(7); H 36 x 36 dense matrix over Integer Ring (use the '.str()' method to see the entries) sage: H==H.T and is_hadamard_matrix(H) and H.diagonal()==[1]*36 and list(sum(H))==[6]*36 True Bigger examples, only provided by this construction :: sage: H = rshcd_from_prime_power_and_conference_matrix(27) # long time sage: H == H.T and is_hadamard_matrix(H) # long time True sage: H.diagonal()==[1]*676 and list(sum(H))==[26]*676 # long time True In this example the conference matrix is not Paley, as 45 is not a prime power :: sage: H = rshcd_from_prime_power_and_conference_matrix(47) # not tested (long time) REFERENCE: .. [WW72] \J. Wallis and A.L. Whiteman, Some classes of Hadamard matrices with constant diagonal, Bull. Austral. Math. Soc. 7(1972), 233-249 """ from sage.graphs.strongly_regular_db import strongly_regular_graph as srg if is_prime_power(n) and 2==(n-1)%4: try: M = srg(n-2,(n-3)//2,(n-7)//4) except ValueError: return m = (n-3)//4 Q,X,Y = szekeres_difference_set_pair(m) B = typeI_matrix_difference_set(Q,X) A = -typeI_matrix_difference_set(Q,Y) # must be symmetric W = M.seidel_adjacency_matrix() f = J(1,4*m+1) e = J(1,2*m+1) JJ = J(2*m+1, 2*m+1) II = I(n-2) Ib = I(2*m+1) J4m = J(4*m+1,4*m+1) H34 = -(B+Ib).tensor_product(W)+Ib.tensor_product(J4m)+(Ib-JJ).tensor_product(II) A_t_W = A.tensor_product(W) e_t_f = e.tensor_product(f) H = block_matrix([ [J(1,1), f, e_t_f, -e_t_f], [f.T, J4m, e.tensor_product(W-II), e.tensor_product(W+II)], [ e_t_f.T, (e.T).tensor_product(W-II), A_t_W+JJ.tensor_product(II), H34], [-e_t_f.T, (e.T).tensor_product(W+II), H34.T, -A_t_W+JJ.tensor_product(II)]]) return H
def rshcd_from_prime_power_and_conference_matrix(n): r""" Return a `((n-1)^2,1)`-RSHCD if `n` is prime power, and symmetric `(n-1)`-conference matrix exists The construction implemented here is Theorem 16 (and Corollary 17) from [WW72]_. In [SWW72]_ this construction (Theorem 5.15 and Corollary 5.16) is reproduced with a typo. Note that [WW72]_ refers to [Sz69]_ for the construction, provided by :func:`szekeres_difference_set_pair`, of complementary difference sets, and the latter has a typo. From a :func:`symmetric_conference_matrix`, we only need the Seidel adjacency matrix of the underlying strongly regular conference (i.e. Paley type) graph, which we construct directly. INPUT: - ``n`` -- an integer .. SEEALSO:: :func:`regular_symmetric_hadamard_matrix_with_constant_diagonal` EXAMPLES: A 36x36 example :: sage: from sage.combinat.matrices.hadamard_matrix import rshcd_from_prime_power_and_conference_matrix sage: from sage.combinat.matrices.hadamard_matrix import is_hadamard_matrix sage: H = rshcd_from_prime_power_and_conference_matrix(7); H 36 x 36 dense matrix over Integer Ring (use the '.str()' method to see the entries) sage: H==H.T and is_hadamard_matrix(H) and H.diagonal()==[1]*36 and list(sum(H))==[6]*36 True Bigger examples, only provided by this construction :: sage: H = rshcd_from_prime_power_and_conference_matrix(27) # long time sage: H == H.T and is_hadamard_matrix(H) # long time True sage: H.diagonal()==[1]*676 and list(sum(H))==[26]*676 # long time True In this example the conference matrix is not Paley, as 45 is not a prime power :: sage: H = rshcd_from_prime_power_and_conference_matrix(47) # not tested (long time) REFERENCE: .. [WW72] \J. Wallis and A.L. Whiteman, Some classes of Hadamard matrices with constant diagonal, Bull. Austral. Math. Soc. 7(1972), 233-249 """ from sage.graphs.strongly_regular_db import strongly_regular_graph as srg if is_prime_power(n) and 2 == (n - 1) % 4: try: M = srg(n - 2, (n - 3) // 2, (n - 7) // 4) except ValueError: return m = (n - 3) // 4 Q, X, Y = szekeres_difference_set_pair(m) B = typeI_matrix_difference_set(Q, X) A = -typeI_matrix_difference_set(Q, Y) # must be symmetric W = M.seidel_adjacency_matrix() f = J(1, 4 * m + 1) e = J(1, 2 * m + 1) JJ = J(2 * m + 1, 2 * m + 1) II = I(n - 2) Ib = I(2 * m + 1) J4m = J(4 * m + 1, 4 * m + 1) H34 = -(B + Ib).tensor_product(W) + Ib.tensor_product(J4m) + ( Ib - JJ).tensor_product(II) A_t_W = A.tensor_product(W) e_t_f = e.tensor_product(f) H = block_matrix( [[J(1, 1), f, e_t_f, -e_t_f], [f.T, J4m, e.tensor_product(W - II), e.tensor_product(W + II)], [ e_t_f.T, (e.T).tensor_product(W - II), A_t_W + JJ.tensor_product(II), H34 ], [ -e_t_f.T, (e.T).tensor_product(W + II), H34.T, -A_t_W + JJ.tensor_product(II) ]]) return H