Path: blob/master/sage/combinat/matrices/hadamard_matrix.py
4072 views
r"""1Hadamard matrices23A Hadamard matrix is an nxn matrix H whose entries are either +1 or -1 and whose4rows are mutually orthogonal. For example, the matrix `H_2` defined by::56[ 1 1 ]7[ 1 -1 ]89is a Hadamard matrix. An nxn matrix H whose entries are either +1 or -110is a Hadamard matrix if and only if11(a) `|det(H)|=n^(n/2),` or12(b) `H*H^t = n\cdot I_n`, where `I_n` is the identity matrix.13In general, the tensor product of an mxm Hadamard matrix and an `n\times n` Hadamard14matrix is an `(mn)\times (mn)` matrix. In particular, if there is an nxn Hadamard15matrix then there is a `(2n)\times (2n)` Hadamard matrix (since one may tensor with `H_2`).16This particular case is sometimes called the Sylvester construction.17The Hadamard conjecture (possibly due to Paley) states that a Hadamard matrix of18order `n` exists if and only if `n=2` or `n` is a multiple of `4`.1920The module below implements the Paley constructions (see for example [3]_) and21the Sylvester construction. It also allows you to pull a Hadamard matrix22from the database at [1]_.2324AUTHOR::25-- David Joyner (2009-05-17): initial version2627REFERENCES::28.. [1] N.J.A. Sloane's Library of Hadamard Matrices, at29http://www.research.att.com/~njas/hadamard30.. [2] Hadamard matrices on Wikipedia, at http://en.wikipedia.org/wiki/Hadamard_matrix31.. [3] K. J. Horadam, Hadamard Matrices and Their Applications, Princeton University32Press, 2006.3334"""35from sage.rings.arith import kronecker_symbol36from sage.rings.integer_ring import IntegerRing37ZZ = IntegerRing()38from sage.matrix.constructor import matrix, block_matrix39import urllib40from sage.misc.functional import is_even41from sage.rings.arith import is_prime4243def H1(i,j,p):44"""45Returns the i,j-th entry of the Paley matrix, type I case.4647EXAMPLES::48sage: sage.combinat.matrices.hadamard_matrix.H1(1,2,3)49-150"""51if i==0:52return 153if j==0:54return -155if i==j:56return 157return kronecker_symbol(i-j,p)585960def H2(i,j,p):61"""62Returns the i,j-th entry of the Paley matrix, type II case.6364EXAMPLES::65sage: sage.combinat.matrices.hadamard_matrix.H1(1,2,5)6616768"""69if i==0 and j==0:70return 071if i==0 or j==0:72return 173if j==0:74return -175if i==j:76return 077return kronecker_symbol(i-j,p)7879def hadamard_matrix_paleyI(n):80"""81Implements the Paley type I construction.828384EXAMPLES::85sage: sage.combinat.matrices.hadamard_matrix.hadamard_matrix_paleyI(4)86[ 1 -1 -1 -1]87[ 1 1 1 -1]88[ 1 -1 1 1]89[ 1 1 -1 1]90"""91if is_prime(n-1) and (n-1)%4==3:92p = n-193else:94raise ValueError, "The order %s is not covered by the Paley type I construction."%n95return matrix(ZZ,[[H1(i,j,p) for i in range(n)] for j in range(n)])969798def hadamard_matrix_paleyII(n):99"""100Implements the Paley type II construction.101102103EXAMPLES::104sage: sage.combinat.matrices.hadamard_matrix.hadamard_matrix_paleyI(12).det()1052985984106sage: 12^61072985984108109"""110N = ZZ(n/2)111if is_prime(N-1) and (N-1)%4==1:112p = N-1113else:114raise ValueError, "The order %s is not covered by the Paley type II construction."%n115S = matrix(ZZ,[[H2(i,j,p) for i in range(N)] for j in range(N)])116return block_matrix([[S+1,S-1],[S-1,-S-1]])117118def hadamard_matrix(n):119"""120Tries to construct a Hadamard matrix using a combination of Paley and Sylvester121constructions.122123EXAMPLES::124sage: hadamard_matrix(12).det()1252985984126sage: 12^61272985984128sage: hadamard_matrix(2)129[ 1 1]130[ 1 -1]131sage: hadamard_matrix(8)132[ 1 1 1 1 1 1 1 1]133[ 1 -1 1 -1 1 -1 1 -1]134[ 1 1 -1 -1 1 1 -1 -1]135[ 1 -1 -1 1 1 -1 -1 1]136[ 1 1 1 1 -1 -1 -1 -1]137[ 1 -1 1 -1 -1 1 -1 1]138[ 1 1 -1 -1 -1 -1 1 1]139[ 1 -1 -1 1 -1 1 1 -1]140sage: hadamard_matrix(8).det()==8^4141True142143"""144if not(n%4==0) and not(n==2):145raise ValueError, "The Hadamard matrix of order %s does not exist"%n146if n==2:147return matrix([[1,1],[1,-1]])148if is_even(n):149N = ZZ(n/2)150elif n==1:151return matrix([1])152if is_prime(N-1) and (N-1)%4==1:153return hadamard_matrix_paleyII(n)154elif n==4 or n%8==0:155had = hadamard_matrix(ZZ(n/2))156chad1 = matrix([list(r)+list(r) for r in had.rows()])157mhad = (-1)*had158R = len(had.rows())159chad2 = matrix([list(had.rows()[i])+list(mhad.rows()[i]) for i in range(R)])160return chad1.stack(chad2)161elif is_prime(N-1) and (N-1)%4==3:162return hadamard_matrix_paleyI(n)163else:164raise ValueError, "The Hadamard matrix of order %s is not yet implemented."%n165166def hadamard_matrix_www(url_file, comments=False):167"""168Pulls file from Sloanes database and returns the corresponding Hadamard169matrix as a Sage matrix. You must input a filename of the form170"had.n.xxx.txt" as described on the webpage171http://www.research.att.com/~njas/hadamard/, where "xxx" could be172empty or a number of some characters.173174If comments=True then the "Automorphism..." line of the had.n.xxx.txt175file is printed if it exists. Otherwise nothing is done.176177EXAMPLES::178sage: hadamard_matrix_www("had.4.txt") # requires internet, optional179[ 1 1 1 1]180[ 1 -1 1 -1]181[ 1 1 -1 -1]182[ 1 -1 -1 1]183sage: hadamard_matrix_www("had.16.2.txt",comments=True) # requires internet, optional184Automorphism group has order = 49152 = 2^14 * 3185[ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]186[ 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1]187[ 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1]188[ 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1]189[ 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1]190[ 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1]191[ 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1]192[ 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1]193[ 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1]194[ 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1]195[ 1 1 -1 -1 1 -1 1 -1 -1 -1 1 1 -1 1 -1 1]196[ 1 1 -1 -1 -1 1 -1 1 -1 -1 1 1 1 -1 1 -1]197[ 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1]198[ 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1]199[ 1 -1 -1 1 1 1 -1 -1 -1 1 1 -1 -1 -1 1 1]200[ 1 -1 -1 1 -1 -1 1 1 -1 1 1 -1 1 1 -1 -1]201"""202n = eval(url_file.split(".")[1])203rws = []204url = "http://www.research.att.com/~njas/hadamard/"+url_file205f = urllib.urlopen(url)206s = f.readlines()207for i in range(n):208r = []209for j in range(n):210if s[i][j]=="+":211r.append(1)212else:213r.append(-1)214rws.append(r)215f.close()216if comments==True:217lastline = s[-1]218if lastline[0]=="A":219print lastline220return matrix(rws)221222223