15
\$\begingroup\$

Hadamard matrices is a square matrix whose entries are either +1 or −1 and whose rows are mutually orthogonal.

In other words, it means that each pair of rows has matching entries in exactly half of their columns and mismatched entries in the remaining columns. As a result, the same properties hold for columns as well as rows.

Examples

[ 1 1 1 1
 1 -1 1 -1
 1 1 -1 -1
 1 -1 -1 1 ]

This is a Hadamard matrix, because any pair of rows has matching entries in exactly half of their columns, like:

[ 1 1 1 1
 | / | /
 1 -1 1 -1
 ]

There are 2 |s (matching entries) and 2 /s (mismatched entries). The same logic also applies by columns:

[ 1 ― 1 
 1 ― 1 
 1 ~ -1 
 1 ~ -1 ]

There are two s (matching entries) and two ~s (mismatched entries).

This logic can be applied to every pair of rows and columns.

Another example:

[ 1 1
 1 -1 ]

This is a hadamard matrix, because there is only one pair of rows and one pair of columns, but their matching entries is still half of the size of the matrix.

A counterexample like:

[ 1 -1 1 -1
 -1 1 -1 1
 1 -1 1 -1
 -1 1 -1 1 ]

is not a Hadamard matrix, because two pair of rows match in all columns, and four rows don't match in any column. The same logic applies to pair of columns.

Note that

[ 1 ]

is also a Hadamard (1x1) matrix, and your code should handle that (See challenge).

Notes

  • The matrix inputs are always square

  • The matrix will only contain -1 or 1. No zeros.

Challenge

The shortest answer that checks if a matrix is a Hadamard matrix wins, because this is . You may not take input as 1d array, it must be 2d array if your language has a builtin 2d arrays.

asked Jul 7, 2024 at 21:11
\$\endgroup\$
10
  • \$\begingroup\$ Is the input matrix guaranteed to contain only 1 and -1? \$\endgroup\$ Commented Jul 7, 2024 at 21:19
  • \$\begingroup\$ @Arnauld yeah, only 1 and -1. No zeros. \$\endgroup\$ Commented Jul 7, 2024 at 21:21
  • 2
    \$\begingroup\$ You may not take input as 1d array, it must be 2d array - What about languages (like C) that don't have builtin 2d arrays? \$\endgroup\$ Commented Jul 7, 2024 at 21:52
  • 3
    \$\begingroup\$ Please edit the challenge to reflect the input restrictions (only plus/minus 1 values, matrix is square). They are too important to be buried in comments \$\endgroup\$ Commented Jul 7, 2024 at 22:14
  • 1
    \$\begingroup\$ @LuisMendo Okay, I added the notes to the challenge. \$\endgroup\$ Commented Jul 7, 2024 at 22:17

19 Answers 19

8
\$\begingroup\$

R, 36 bytes

\(H)any(H%*%t(H)-diag(n<-nrow(H))*n)

Attempt This Online!

Uses the characterization: \$HH^T=nI_n\$.

Outputs swapped TRUE/FALSE.

answered Jul 8, 2024 at 5:43
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Oh, duh. I'm too rusty! \$\endgroup\$ Commented Jul 9, 2024 at 11:39
8
\$\begingroup\$

Vyxal, 7 bytes

ÞḊ2$@Π=

Try it Online! -1 thanks to att.

ÞḊ # Is determinant 
 2 # squared
 = # equal to
 $@ # Length of input
 Π # To the power of itself?
answered Jul 7, 2024 at 22:54
\$\endgroup\$
1
  • 2
    \$\begingroup\$ -1 with det ÞḊ²$@Π= \$\endgroup\$ Commented Jul 9, 2024 at 6:36
6
\$\begingroup\$

Nekomata + -e, 4 bytes

Sđ∙Z

Attempt This Online!

This swaps truthy and falsy values. It outputs False if the input is a Hadamard matrix, and True otherwise.

Sđ∙Z
S Find a subset of the input
 đ whose length is 2
 ∙ and the dot product of the two elements
 Z is nonzero

-e checks if there is a solution.


Nekomata + -e, 6 bytes

o∙jZ!!*

Attempt This Online!

o∙jZ!!*
o∙ Outer product with dot product
 This is equivalent to multiplying the matrix by its transpose
 j Join the matrix into a single list
 Z!! Remove zeros
 * Check if it has the same length as the input
 Nekomata does not allow multiplying two lists of different lengths
answered Jul 8, 2024 at 3:52
\$\endgroup\$
5
\$\begingroup\$

JavaScript (ES6), 60 bytes

Returns false for Hadamard or true for non-Hadamard.

m=>m.some(p=>m.some(q=>p!=q&&p.reduce((t,v,x)=>t+v*q[x],0)))

Try it online!

Commented

m => // m[] = input matrix
m.some(p => // for each row p[] in m[]:
 m.some(q => // for each row q[] in m[]:
 p != q && // test whether p[] is not equal to q[]
 // (comparison of pointers)
 p.reduce( // for each value v at position x in p[],
 (t, v, x) => // using t as the accumulator:
 t + v * q[x], // add v * q[x] to the accumulator,
 // which gives 1 if v = q[x] or -1 otherwise
 0 // start with t = 0
 ) // end of reduce() -> gives 0 if and only if
 // exactly half of the values are matching
 ) // end of inner some()
) // end of outer some()
answered Jul 7, 2024 at 21:38
\$\endgroup\$
0
4
\$\begingroup\$

MATL, (削除) 9 (削除ここまで) 7 bytes

Thanks to @alephalpha for a correction (the transpose was originally missing).

t!Y*XR~

Inputs a matrix. Outputs a a matrix of ones (which is truthy) if the input is a Hadamard matrix, or a matrix containing at least a zero (which is falsy) otherwise.

Try it online! Or verify all test cases.

How it works

t % Implicit input: matrix M, of size n, with 1 or −1 entries. Duplicate
! % Transpose
Y* % Matrix product. This is a scalar matrix if and only if M is Hadamard
XR % Set entries on the diagonal and below to 0
~ % Negate each entry. Implicit display
answered Jul 7, 2024 at 22:21
\$\endgroup\$
0
4
\$\begingroup\$

Wolfram Language (Mathematica), 22 bytes

#^#&@Tr[1^#]==Det@#^2&

Try it online!

answered Jul 8, 2024 at 16:34
\$\endgroup\$
4
\$\begingroup\$

Google Sheets, 51 bytes

lambda(a,b,sum(byrow(b,lambda(r,sumproduct(a,r)))))

This is a Google Sheets lambda function that expects two parameters: a should point to a 2D array that contains the first row in the matrix, and b should point to a 2D array that holds the rest of the rows in the matrix.

The function assumes that the matrix in the format specified in the question, and returns 0 if it is a Hadamard matrix and a non-zero value otherwise. In the event of a 1x1 matrix like [[1]], a should point to the matrix and b should point to a null array of zero rows, and the formula will return 0.

screenshot

You can call the function like this:

=lambda(a, b, 
 sum(byrow(b, lambda(r, sumproduct(a, r)))) 
)(A1:D1, A2:D4)

...where a is A1:D1 and bis A2:D4.

answered Jul 8, 2024 at 19:12
\$\endgroup\$
2
  • \$\begingroup\$ I don't think the rules allow 2 inputs, unfortunately. \$\endgroup\$ Commented Jan 8 at 14:54
  • \$\begingroup\$ Yes, but the challenge is not about parsing the input. It is trivial to get the head and rest from a 2D array. The consensus is to always allow flexible input formats. \$\endgroup\$ Commented Jan 8 at 15:18
3
\$\begingroup\$

Charcoal, 12 bytes

×ばつιλ

Attempt This Online! Link is to verbose version of code. Outputs an inverted Charcoal boolean, i.e. - if not Hadamard, nothing if Hadamard, Explanation:

⊙ Input array
 θ Any row satisfies
 ⊙ Input array
 θ Any row satisfies
 κ Outer index
 − Does not equal
 μ Inner index
 ∧ Logical And
 ι Outer row
 ×ばつ Vectorised product with
 λ Inner row
 Σ Has nonzero sum
 Implicitly print
answered Jul 7, 2024 at 22:13
\$\endgroup\$
3
\$\begingroup\$

PARI/GP, 11 bytes

a->a*a~==#a

Attempt This Online!

Let \$A\$ be the input matrix. Since it is guaranteed to contain only 1 and -1, we only need to check if \$A A^T = n I\$, where \$n\$ is the number of rows in \$A\$. When comparing a matrix with a scalar, PARI/GP will automatically multiply the scalar by the identity matrix of the same size.

answered Jul 8, 2024 at 2:33
\$\endgroup\$
2
\$\begingroup\$

Python 3, 105 bytes

f=lambda a,x=2:x<1or all(sum(map(int.__eq__,i,j))*2==len(i)for i in a for j in{*a}-{i})*f([*zip(*a)],x-1)

Try it online!

answered Jul 8, 2024 at 7:42
\$\endgroup\$
2
\$\begingroup\$

05AB1E, (削除) 11 (削除ここまで) 10 bytes

δ*OZ/āDδQQ

Port of @alephalpha's PARI/GP answer, so make sure to upvote that answer as well!

Try it online or verify all test cases.

Explanation:

δ*O # Matrix multiplicate the (implicit) input with itself:
δ # Apply double-vectorized, using two times the (implicit) input-matrix:
 * # Vectorized multiply
 O # Sum each inner row together
 Z # Push the flattened maximum (without popping the matrix)
 / # Divide each inner value by this maximum
 āDδQ # Push an identity-matrix of the same size:
 ā # Push a list in the range [1,length] (without popping)
 D # Duplicate it
 δ # Apply double-vectorized again:
 Q # Check whether the values are equal
 Q # Check if the earlier matrix equals the identity-matrix
 # (after which the result is output implicitly)
answered Jul 8, 2024 at 7:56
\$\endgroup\$
2
\$\begingroup\$

Haskell, (削除) 47 (削除ここまで), 46 bytes

  • -1 byte thanks to xnor
f(x:y)=[]==y||all((0==).sum.zipWith(*)x)y&&f y

Try it online!

  • sum.zipWith(*) computes the scalar product of two vectors
  • x is the first row, y all the next rows
  • we check that for all other rows in y the scalar product with the current row x is zero
  • then we repeat the check discarding the first row (Haskell works well with recursion)
answered Jul 8, 2024 at 22:48
\$\endgroup\$
1
  • 1
    \$\begingroup\$ null y can be y==[] \$\endgroup\$ Commented Jul 9, 2024 at 3:54
1
\$\begingroup\$

Ruby, 58 bytes

->m{m.combination(2).all?{|r,s|s.zip(r).sum{|a,b|a*b}==0}}

Try it online!

answered Jul 8, 2024 at 10:59
\$\endgroup\$
1
\$\begingroup\$

APL+WIN, (削除) 19 (削除ここまで) 20 bytes

+1 to fix problem identified by att

Prompts for matrix. 1 = true, 0 = false

(×ばつ/⍴m)=×ばつ⍉m←⎕

Try it online! Thanks to Dyalog Classic

answered Jul 8, 2024 at 14:59
\$\endgroup\$
2
  • \$\begingroup\$ This doesn't work for e.g. ⍉4 4⍴1 1 1 ¯1 \$\endgroup\$ Commented Jul 9, 2024 at 5:07
  • \$\begingroup\$ @att. Thanks. Hopefully fixed. \$\endgroup\$ Commented Jul 9, 2024 at 7:28
1
\$\begingroup\$

Haskell + hgl, 19 bytes

mF(q0<sm)<xQ(zW ml)

Attempt This Online!

Explanation

This takes all pairs of rows \$(a,b)\$ where \$a\$ comes before \$b\$, computes the dot product and checks that the result is always zero.

  • xQ computes the pairs
  • zW ml multiplies the rows pairwise
  • sm performs the sum to get the dot product
  • q0 compares it to zero
  • mF folds using logical and.

Reflection

I'm pretty pleased with this overall. The library is not really built with a lot of linear algebra functions (yet). So this is not a task I should expect this to do very well at. It's not stellar, but it is passable considering everythign. I'm very happy that xQ exists.

  • There could be a dot product builtin. This would make this much shorter.
  • xQ should be refactored to take a foldable so this could operate on actual vector types instead of lists.
answered Jul 15, 2024 at 0:59
\$\endgroup\$
1
\$\begingroup\$

Setanta, 102 bytes

gniomh(m){b:=0le i idir(0,fad@m)le j idir(0,i){s:=0le k idir(0,fad@m)s+=m[i][k]*m[j][k]b=b|s}toradh!b}

try-setanta.ie link

answered Aug 13, 2024 at 4:30
\$\endgroup\$
1
\$\begingroup\$

Raku (Perl 6) (rakudo), 38 bytes

{!grep {[+] [Z*] $_},.combinations(2)}

Attempt This Online!

answered Aug 13, 2024 at 4:33
\$\endgroup\$
1
\$\begingroup\$

APL(NARS), 15 chars

{(*/⍴⍵)=×ばつ⍵}

One Hadamard matrix is a M matrix, each elment are +-1 (already proven by input restriction) is quadratic (already proven by input restrictions) that det(M)^2=n^n where nxn is the dimension of the matrix.

{(*/⍴⍵)=×ばつ⍵}
 | ^^ ^------- ×ばつ" make determinant of input ⍵
 | ||--------- ×ばつ⍨" make mult of input on right by itself will be det(⍵)^2 there
 | |------------"=" is equal to
 |----------------"*/⍴⍵" "⍴⍵" get dimensions of input ⍵ and "*/" elevate the first by the second

It should return 1 if the input is a Hadamard matrix, else should return 0; test:

 {((,1)≡∪∣,⍵)∧(*/⍴⍵)=×ばつ⍵}2 2⍴ 1 1 1 ̄1
1
 {(*/⍴⍵)=×ばつ⍵} 4 4⍴ 1 1 1 1 1 ̄1 1 ̄1 1 1 ̄1 ̄1 1 ̄1 ̄1 1
1
 {(*/⍴⍵)=×ばつ⍵} 2 2⍴ 1 1 1 ̄1
1
 {(*/⍴⍵)=×ばつ⍵} 4 4⍴ 1 ̄1 1 ̄1 ̄1 1 ̄1 1 1 ̄1 1 ̄1 ̄1 1 ̄1 1
0
 {(*/⍴⍵)=×ばつ⍵} 1 1⍴1
1
answered Jan 8 at 19:49
\$\endgroup\$
0
\$\begingroup\$

Jelly, 7 bytes

Œcḋ/€S¬

Try it online!

Finds all combinations of 2 rows (Œc), calculates the dot product for each (ḋ/€) and sums (S). If this sum is greater than 0, then there exists a pair of rows that is non-orthogonal. Finally, take the logical inverse (¬).

Alternative (8 bytes)

ÆḊ2=L*`$

Try it online!

Tests whether the square determinant (ÆḊ2) is equal to the length of the input, to the power of itself (L*`$). This works as \$\det(H)=\pm n^{n/2} \iff n\$ is a Hadamard matrix.

answered Jan 7 at 23:05
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.