def dramadah(n, k=1): """ dramadah a (0,1) matrix whose inverse has large integer entries. An anti-hadamard matrix a is a matrix with elements 0 or 1 for which mu(a) := norm(inv(a),'fro') is maximal. a = dramadah(n, k) is an n-by-n (0,1) matrix for which mu(a) is relatively large, although not necessarily maximal. Available types (the default is k = 1): k = 1: a is toeplitz, with abs(det(a)) = 1, and mu(a) > c(1.75)^n, where c is a constant. k = 2: a is upper triangular and toeplitz. the inverses of both types have integer entries. Another interesting (0,1) matrix: K = 3: A has maximal determinant among (0,1) lower Hessenberg matrices: det(A) = the n'th Fibonacci number. A is Toeplitz. The eigenvalues have an interesting distribution in the complex plane. References: R.L. Graham and N.J.A. Sloane, Anti-Hadamard matrices, Linear Algebra and Appl., 62 (1984), pp. 113-137. L. Ching, The maximum determinant of an nxn lower Hessenberg (0,1) matrix, Linear Algebra and Appl., 183 (1993), pp. 147-153. """ if k == 1: # Toeplitz c = np.ones(n) for i in range(1, n, 4): m = min(1, n - i) c[i:i + m + 1] = 0 r = np.zeros(n) r[0:4] = np.array([1, 1, 0, 1]) if n < 4: r = r[0:n] a = rogues.toeplitz(c, r) elif k == 2: # Upper triangular and Toeplitz c = np.zeros(n) c[0] = 1 r = np.ones(n) r[2::2] = 0 a = rogues.toeplitz(c, r) elif k == 3: # Lower Hessenberg. c = np.ones(n) c[1::2] = 0 a = rogues.toeplitz(c, np.r_['1', np.array([1, 1]), np.zeros(n - 2)]) return a
def hadamard(n): """ HADAMARD Hadamard matrix. HADAMARD(N) is a Hadamard matrix of order N, that is, a matrix H with elements 1 or -1 such that H*H' = N*EYE(N). An N-by-N Hadamard matrix with N>2 exists only if REM(N,4) = 0. This function handles only the cases where N, N/12 or N/20 is a power of 2. Reference: S.W. Golomb and L.D. Baumert, The search for Hadamard matrices, Amer. Math. Monthly, 70 (1963) pp. 12-17. http://en.wikipedia.org/wiki/Hadamard_matrix Weisstein, Eric W. "Hadamard Matrix." From MathWorld-- A Wolfram Web Resource. http://mathworld.wolfram.com/HadamardMatrix.html """ f, e = np.frexp(np.array([n, n / 12., n / 20.])) try: # If more than one condition is satified, this will always # pick the first one. k = [i for i in range(3) if (f == 0.5)[i] and (e > 0)[i]].pop() except IndexError: raise ValueError('N, N/12 or N/20 must be a power of 2.') e = e[k] - 1 if k == 0: # N = 1 * 2^e; h = np.array([1]) elif k == 1: # N = 12 * 2^e; tp = rogues.toeplitz(np.array([-1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1]), np.array([-1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1])) h = np.vstack((np.ones((1, 12)), np.hstack((np.ones((11, 1)), tp)))) elif k == 2: # N = 20 * 2^e; hk = rogues.hankel( np.array([ -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1 ]), np.array([ 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1 ])) h = np.vstack((np.ones((1, 20)), np.hstack((np.ones((19, 1)), hk)))) # Kronecker product construction. mh = -1 * h for i in range(e): ht = np.hstack((h, h)) hb = np.hstack((h, mh)) h = np.vstack((ht, hb)) mh = -1 * h return h
def hadamard(n): """ HADAMARD Hadamard matrix. HADAMARD(N) is a Hadamard matrix of order N, that is, a matrix H with elements 1 or -1 such that H*H' = N*EYE(N). An N-by-N Hadamard matrix with N>2 exists only if REM(N,4) = 0. This function handles only the cases where N, N/12 or N/20 is a power of 2. Reference: S.W. Golomb and L.D. Baumert, The search for Hadamard matrices, Amer. Math. Monthly, 70 (1963) pp. 12-17. http://en.wikipedia.org/wiki/Hadamard_matrix Weisstein, Eric W. "Hadamard Matrix." From MathWorld-- A Wolfram Web Resource: http://mathworld.wolfram.com/HadamardMatrix.html """ f, e = np.frexp(np.array([n, n / 12., n / 20.])) try: # If more than one condition is satified, this will always # pick the first one. k = [i for i in range(3) if (f == 0.5)[i] and (e > 0)[i]].pop() except IndexError: raise ValueError('N, N/12 or N/20 must be a power of 2.') e = e[k] - 1 if k == 0: # N = 1 * 2^e; h = np.array([1]) elif k == 1: # N = 12 * 2^e; tp = rogues.toeplitz(np.array([-1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1]), np.array([-1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1])) h = np.vstack((np.ones((1, 12)), np.hstack((np.ones((11, 1)), tp)))) elif k == 2: # N = 20 * 2^e; hk = rogues.hankel( np.array([-1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1]), np.array([1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1])) h = np.vstack((np.ones((1, 20)), np.hstack((np.ones((19, 1)), hk)))) # Kronecker product construction. mh = -1 * h for i in range(e): ht = np.hstack((h, h)) hb = np.hstack((h, mh)) h = np.vstack((ht, hb)) mh = -1 * h return h
def test_toeplitz(): """ Simple test of toeplitz. This just checks that the known values of determinant for a simple form at a succession of matrix sizes """ dets = [] for i in range(3, 30): a = np.arange(1, i) b = rogues.toeplitz(a) dets.append(nl.det(b)) dets = np.array(dets) # Here are the known values of the determinants ans = np.array([(-1) ** (i - 1) * (i + 1) * (2 ** (i - 2)) for i in \ range(2, 29)]) # pretty bad round off for some values npt.assert_array_almost_equal(dets, ans, 5)