Algorithms for mutually orthogonal latin squares - a correct one?
Clash Royale CLAN TAG#URR8PPP
up vote
1
down vote
favorite
I am very interested in using mutually orthogonal latin squares (MOLS) to reduce the number of test cases but I struggle to find a way how to implement the algorithm. In an article published in a foreign language, I did find a formula including the source code.
This is said to be a formula to construct a series of squares (if $n$ is a prime number):
For $k, i, j in 1,2, cdots, n$
$$A_k(i, j) = [k cdot (i-1) + (j-1)] mod n$$
Is this correct? I tried to find other sources but failed.
If this is correct, what is meant by $k$, $i$ and $j$? In the code, they pass "size" of the latin square to all of these variables.
combinatorics algorithms latin-square
add a comment |Â
up vote
1
down vote
favorite
I am very interested in using mutually orthogonal latin squares (MOLS) to reduce the number of test cases but I struggle to find a way how to implement the algorithm. In an article published in a foreign language, I did find a formula including the source code.
This is said to be a formula to construct a series of squares (if $n$ is a prime number):
For $k, i, j in 1,2, cdots, n$
$$A_k(i, j) = [k cdot (i-1) + (j-1)] mod n$$
Is this correct? I tried to find other sources but failed.
If this is correct, what is meant by $k$, $i$ and $j$? In the code, they pass "size" of the latin square to all of these variables.
combinatorics algorithms latin-square
1
Include the subject of you question in the body as well. Newspaper headlines don't state "President says X" and then, in the body, never mention the president nor X. The title is not the beginning of the question.
â Thomas Andrews
Jan 24 '16 at 12:42
This is a formula for what exactly?
â Morgan Rodgers
Jan 24 '16 at 12:42
Thanks, I updated the question. The formula should produce the squares required. (is there a way to show the image in the body instead as a link?)
â Pietross
Jan 24 '16 at 12:47
A notion of whether the algorithm is correct depends on the interpretation of inputs $i,j,k$, so it is preferred that you state for your Readers what these mean. I suspect that $k$ should be $0 lt k lt n$, so that $k$ is coprime to (prime) $n$. Then $A_k(i,j)$ should give you a matrix entry ($i$th row and $j$th column, or vice versa, as you wish to interpret).
â hardmath
Jan 24 '16 at 14:48
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I am very interested in using mutually orthogonal latin squares (MOLS) to reduce the number of test cases but I struggle to find a way how to implement the algorithm. In an article published in a foreign language, I did find a formula including the source code.
This is said to be a formula to construct a series of squares (if $n$ is a prime number):
For $k, i, j in 1,2, cdots, n$
$$A_k(i, j) = [k cdot (i-1) + (j-1)] mod n$$
Is this correct? I tried to find other sources but failed.
If this is correct, what is meant by $k$, $i$ and $j$? In the code, they pass "size" of the latin square to all of these variables.
combinatorics algorithms latin-square
I am very interested in using mutually orthogonal latin squares (MOLS) to reduce the number of test cases but I struggle to find a way how to implement the algorithm. In an article published in a foreign language, I did find a formula including the source code.
This is said to be a formula to construct a series of squares (if $n$ is a prime number):
For $k, i, j in 1,2, cdots, n$
$$A_k(i, j) = [k cdot (i-1) + (j-1)] mod n$$
Is this correct? I tried to find other sources but failed.
If this is correct, what is meant by $k$, $i$ and $j$? In the code, they pass "size" of the latin square to all of these variables.
combinatorics algorithms latin-square
combinatorics algorithms latin-square
edited Jan 24 '16 at 13:35
MickG
4,23731551
4,23731551
asked Jan 24 '16 at 12:40
Pietross
185
185
1
Include the subject of you question in the body as well. Newspaper headlines don't state "President says X" and then, in the body, never mention the president nor X. The title is not the beginning of the question.
â Thomas Andrews
Jan 24 '16 at 12:42
This is a formula for what exactly?
â Morgan Rodgers
Jan 24 '16 at 12:42
Thanks, I updated the question. The formula should produce the squares required. (is there a way to show the image in the body instead as a link?)
â Pietross
Jan 24 '16 at 12:47
A notion of whether the algorithm is correct depends on the interpretation of inputs $i,j,k$, so it is preferred that you state for your Readers what these mean. I suspect that $k$ should be $0 lt k lt n$, so that $k$ is coprime to (prime) $n$. Then $A_k(i,j)$ should give you a matrix entry ($i$th row and $j$th column, or vice versa, as you wish to interpret).
â hardmath
Jan 24 '16 at 14:48
add a comment |Â
1
Include the subject of you question in the body as well. Newspaper headlines don't state "President says X" and then, in the body, never mention the president nor X. The title is not the beginning of the question.
â Thomas Andrews
Jan 24 '16 at 12:42
This is a formula for what exactly?
â Morgan Rodgers
Jan 24 '16 at 12:42
Thanks, I updated the question. The formula should produce the squares required. (is there a way to show the image in the body instead as a link?)
â Pietross
Jan 24 '16 at 12:47
A notion of whether the algorithm is correct depends on the interpretation of inputs $i,j,k$, so it is preferred that you state for your Readers what these mean. I suspect that $k$ should be $0 lt k lt n$, so that $k$ is coprime to (prime) $n$. Then $A_k(i,j)$ should give you a matrix entry ($i$th row and $j$th column, or vice versa, as you wish to interpret).
â hardmath
Jan 24 '16 at 14:48
1
1
Include the subject of you question in the body as well. Newspaper headlines don't state "President says X" and then, in the body, never mention the president nor X. The title is not the beginning of the question.
â Thomas Andrews
Jan 24 '16 at 12:42
Include the subject of you question in the body as well. Newspaper headlines don't state "President says X" and then, in the body, never mention the president nor X. The title is not the beginning of the question.
â Thomas Andrews
Jan 24 '16 at 12:42
This is a formula for what exactly?
â Morgan Rodgers
Jan 24 '16 at 12:42
This is a formula for what exactly?
â Morgan Rodgers
Jan 24 '16 at 12:42
Thanks, I updated the question. The formula should produce the squares required. (is there a way to show the image in the body instead as a link?)
â Pietross
Jan 24 '16 at 12:47
Thanks, I updated the question. The formula should produce the squares required. (is there a way to show the image in the body instead as a link?)
â Pietross
Jan 24 '16 at 12:47
A notion of whether the algorithm is correct depends on the interpretation of inputs $i,j,k$, so it is preferred that you state for your Readers what these mean. I suspect that $k$ should be $0 lt k lt n$, so that $k$ is coprime to (prime) $n$. Then $A_k(i,j)$ should give you a matrix entry ($i$th row and $j$th column, or vice versa, as you wish to interpret).
â hardmath
Jan 24 '16 at 14:48
A notion of whether the algorithm is correct depends on the interpretation of inputs $i,j,k$, so it is preferred that you state for your Readers what these mean. I suspect that $k$ should be $0 lt k lt n$, so that $k$ is coprime to (prime) $n$. Then $A_k(i,j)$ should give you a matrix entry ($i$th row and $j$th column, or vice versa, as you wish to interpret).
â hardmath
Jan 24 '16 at 14:48
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
3
down vote
accepted
The info given in the OP is almost correct. As noted in Jyrki Lahtonen's answer $k$ cannot be congruent to $n$.
In $A_k(i,j)$, $k$ is the index of the square: the algorithm generates $n-1$ MOLS, one for each $k$ in $1,cdots,n-1$. Using normal matrix conventions, $i$ is the row index and $j$ is the column index, but the formula still works if those are swapped.
Here's some rudimentary Python code that uses that formula to generate a set of mutually orthogonal latin squares and then tests each combination for orthogonality. This code was developed using Python 2.6 but it should run correctly on Python 3.
In this code $i$ and $j$ run from 0 to $n-1$ and $k$ runs from 1 to $n-1$; note that $n$ must be prime.
from __future__ import print_function
def show_grid(g):
for row in g:
print(row)
print()
def test_mols(g):
''' check that all entries in g are unique '''
size = len(g) ** 2
a = set()
for row in g:
a.update(row)
return len(a) == size
def mols(n):
''' Generate a set of mutually orthogonal latin squares
n must be prime
'''
r = range(n)
#Generate each Latin square
allgrids =
for k in range(1, n):
grid =
for i in r:
row =
for j in r:
a = (k*i + j) % n
row.append(a)
grid.append(row)
allgrids.append(grid)
for g in allgrids:
show_grid(g)
print('- ' * 20 + 'n')
#Combine the squares to show their orthoganility
m = len(allgrids)
for i in range(m):
g0 = allgrids[i]
for j in range(i+1, m):
g1 = allgrids[j]
newgrid =
for r0, r1 in zip(g0, g1):
newgrid.append(zip(r0, r1))
print(test_mols(newgrid))
show_grid(newgrid)
mols(3)
output for n=3
[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]
[2, 0, 1]
[1, 2, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2)]
[(1, 2), (2, 0), (0, 1)]
[(2, 1), (0, 2), (1, 0)]
output for n=5
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 0]
[2, 3, 4, 0, 1]
[3, 4, 0, 1, 2]
[4, 0, 1, 2, 3]
[0, 1, 2, 3, 4]
[2, 3, 4, 0, 1]
[4, 0, 1, 2, 3]
[1, 2, 3, 4, 0]
[3, 4, 0, 1, 2]
[0, 1, 2, 3, 4]
[3, 4, 0, 1, 2]
[1, 2, 3, 4, 0]
[4, 0, 1, 2, 3]
[2, 3, 4, 0, 1]
[0, 1, 2, 3, 4]
[4, 0, 1, 2, 3]
[3, 4, 0, 1, 2]
[2, 3, 4, 0, 1]
[1, 2, 3, 4, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
Thank you very much! So the "n" has to be: n>=m and n-1 >=number of parameters. Where "m" is the number of values (e.g. a parameter can have 4 values). And that n has to be prime. So if I have 4 parameters that have 5 values, I will need squares of size 5.
â Pietross
Jan 24 '16 at 13:34
add a comment |Â
up vote
1
down vote
Yes, that formula works. If $n=p$ is a prime it gives you a set of $p-1$ MOLS - one for each $k=1,2,ldots,p-1$. The variables $i$ and $j$ stand for the row and column index respectively.
If $n=p^m$ is a power of a prime $p$, then there exists a similar formula for $n-1$ MOLS, but that requires you to do arithmetic in an extension field of integers modulo $p$.
Thanks. So "k" is the square and i and j are its rows and columns, if I get it right. Out of curiosity, why there is "A" in the formula?
â Pietross
Jan 24 '16 at 13:36
@Pietross: $A_k$ is just the name of the $k$th array.
â PM 2Ring
Jan 24 '16 at 13:39
@PM 2Ring Thanks. What if N=8? Or if that happens, should I go for the next closest prime number?
â Pietross
Jan 24 '16 at 14:48
@Pietross: Well, you could, but using the next prime, 11, gives you a lot of "wasted" combinations, since $11^2$ is almost double $8^2$. As Jyrki says, there are ways to generate MOLS for non-primes. It's pretty easy to generate a pair of MOLS for any odd $n$: that's a standard way to generate magic squares. But that's (possibly) a topic for a new question...
â PM 2Ring
Jan 24 '16 at 14:58
@PM 2Ring Thanks. One last thing - how do I know the value of K? Assume there are 4 parameters, some of which can have 5 values. So n=5. But when I want to code the actual algorithm, how do I determine k?
â Pietross
Jan 24 '16 at 15:01
 |Â
show 1 more comment
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
The info given in the OP is almost correct. As noted in Jyrki Lahtonen's answer $k$ cannot be congruent to $n$.
In $A_k(i,j)$, $k$ is the index of the square: the algorithm generates $n-1$ MOLS, one for each $k$ in $1,cdots,n-1$. Using normal matrix conventions, $i$ is the row index and $j$ is the column index, but the formula still works if those are swapped.
Here's some rudimentary Python code that uses that formula to generate a set of mutually orthogonal latin squares and then tests each combination for orthogonality. This code was developed using Python 2.6 but it should run correctly on Python 3.
In this code $i$ and $j$ run from 0 to $n-1$ and $k$ runs from 1 to $n-1$; note that $n$ must be prime.
from __future__ import print_function
def show_grid(g):
for row in g:
print(row)
print()
def test_mols(g):
''' check that all entries in g are unique '''
size = len(g) ** 2
a = set()
for row in g:
a.update(row)
return len(a) == size
def mols(n):
''' Generate a set of mutually orthogonal latin squares
n must be prime
'''
r = range(n)
#Generate each Latin square
allgrids =
for k in range(1, n):
grid =
for i in r:
row =
for j in r:
a = (k*i + j) % n
row.append(a)
grid.append(row)
allgrids.append(grid)
for g in allgrids:
show_grid(g)
print('- ' * 20 + 'n')
#Combine the squares to show their orthoganility
m = len(allgrids)
for i in range(m):
g0 = allgrids[i]
for j in range(i+1, m):
g1 = allgrids[j]
newgrid =
for r0, r1 in zip(g0, g1):
newgrid.append(zip(r0, r1))
print(test_mols(newgrid))
show_grid(newgrid)
mols(3)
output for n=3
[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]
[2, 0, 1]
[1, 2, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2)]
[(1, 2), (2, 0), (0, 1)]
[(2, 1), (0, 2), (1, 0)]
output for n=5
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 0]
[2, 3, 4, 0, 1]
[3, 4, 0, 1, 2]
[4, 0, 1, 2, 3]
[0, 1, 2, 3, 4]
[2, 3, 4, 0, 1]
[4, 0, 1, 2, 3]
[1, 2, 3, 4, 0]
[3, 4, 0, 1, 2]
[0, 1, 2, 3, 4]
[3, 4, 0, 1, 2]
[1, 2, 3, 4, 0]
[4, 0, 1, 2, 3]
[2, 3, 4, 0, 1]
[0, 1, 2, 3, 4]
[4, 0, 1, 2, 3]
[3, 4, 0, 1, 2]
[2, 3, 4, 0, 1]
[1, 2, 3, 4, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
Thank you very much! So the "n" has to be: n>=m and n-1 >=number of parameters. Where "m" is the number of values (e.g. a parameter can have 4 values). And that n has to be prime. So if I have 4 parameters that have 5 values, I will need squares of size 5.
â Pietross
Jan 24 '16 at 13:34
add a comment |Â
up vote
3
down vote
accepted
The info given in the OP is almost correct. As noted in Jyrki Lahtonen's answer $k$ cannot be congruent to $n$.
In $A_k(i,j)$, $k$ is the index of the square: the algorithm generates $n-1$ MOLS, one for each $k$ in $1,cdots,n-1$. Using normal matrix conventions, $i$ is the row index and $j$ is the column index, but the formula still works if those are swapped.
Here's some rudimentary Python code that uses that formula to generate a set of mutually orthogonal latin squares and then tests each combination for orthogonality. This code was developed using Python 2.6 but it should run correctly on Python 3.
In this code $i$ and $j$ run from 0 to $n-1$ and $k$ runs from 1 to $n-1$; note that $n$ must be prime.
from __future__ import print_function
def show_grid(g):
for row in g:
print(row)
print()
def test_mols(g):
''' check that all entries in g are unique '''
size = len(g) ** 2
a = set()
for row in g:
a.update(row)
return len(a) == size
def mols(n):
''' Generate a set of mutually orthogonal latin squares
n must be prime
'''
r = range(n)
#Generate each Latin square
allgrids =
for k in range(1, n):
grid =
for i in r:
row =
for j in r:
a = (k*i + j) % n
row.append(a)
grid.append(row)
allgrids.append(grid)
for g in allgrids:
show_grid(g)
print('- ' * 20 + 'n')
#Combine the squares to show their orthoganility
m = len(allgrids)
for i in range(m):
g0 = allgrids[i]
for j in range(i+1, m):
g1 = allgrids[j]
newgrid =
for r0, r1 in zip(g0, g1):
newgrid.append(zip(r0, r1))
print(test_mols(newgrid))
show_grid(newgrid)
mols(3)
output for n=3
[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]
[2, 0, 1]
[1, 2, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2)]
[(1, 2), (2, 0), (0, 1)]
[(2, 1), (0, 2), (1, 0)]
output for n=5
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 0]
[2, 3, 4, 0, 1]
[3, 4, 0, 1, 2]
[4, 0, 1, 2, 3]
[0, 1, 2, 3, 4]
[2, 3, 4, 0, 1]
[4, 0, 1, 2, 3]
[1, 2, 3, 4, 0]
[3, 4, 0, 1, 2]
[0, 1, 2, 3, 4]
[3, 4, 0, 1, 2]
[1, 2, 3, 4, 0]
[4, 0, 1, 2, 3]
[2, 3, 4, 0, 1]
[0, 1, 2, 3, 4]
[4, 0, 1, 2, 3]
[3, 4, 0, 1, 2]
[2, 3, 4, 0, 1]
[1, 2, 3, 4, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
Thank you very much! So the "n" has to be: n>=m and n-1 >=number of parameters. Where "m" is the number of values (e.g. a parameter can have 4 values). And that n has to be prime. So if I have 4 parameters that have 5 values, I will need squares of size 5.
â Pietross
Jan 24 '16 at 13:34
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
The info given in the OP is almost correct. As noted in Jyrki Lahtonen's answer $k$ cannot be congruent to $n$.
In $A_k(i,j)$, $k$ is the index of the square: the algorithm generates $n-1$ MOLS, one for each $k$ in $1,cdots,n-1$. Using normal matrix conventions, $i$ is the row index and $j$ is the column index, but the formula still works if those are swapped.
Here's some rudimentary Python code that uses that formula to generate a set of mutually orthogonal latin squares and then tests each combination for orthogonality. This code was developed using Python 2.6 but it should run correctly on Python 3.
In this code $i$ and $j$ run from 0 to $n-1$ and $k$ runs from 1 to $n-1$; note that $n$ must be prime.
from __future__ import print_function
def show_grid(g):
for row in g:
print(row)
print()
def test_mols(g):
''' check that all entries in g are unique '''
size = len(g) ** 2
a = set()
for row in g:
a.update(row)
return len(a) == size
def mols(n):
''' Generate a set of mutually orthogonal latin squares
n must be prime
'''
r = range(n)
#Generate each Latin square
allgrids =
for k in range(1, n):
grid =
for i in r:
row =
for j in r:
a = (k*i + j) % n
row.append(a)
grid.append(row)
allgrids.append(grid)
for g in allgrids:
show_grid(g)
print('- ' * 20 + 'n')
#Combine the squares to show their orthoganility
m = len(allgrids)
for i in range(m):
g0 = allgrids[i]
for j in range(i+1, m):
g1 = allgrids[j]
newgrid =
for r0, r1 in zip(g0, g1):
newgrid.append(zip(r0, r1))
print(test_mols(newgrid))
show_grid(newgrid)
mols(3)
output for n=3
[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]
[2, 0, 1]
[1, 2, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2)]
[(1, 2), (2, 0), (0, 1)]
[(2, 1), (0, 2), (1, 0)]
output for n=5
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 0]
[2, 3, 4, 0, 1]
[3, 4, 0, 1, 2]
[4, 0, 1, 2, 3]
[0, 1, 2, 3, 4]
[2, 3, 4, 0, 1]
[4, 0, 1, 2, 3]
[1, 2, 3, 4, 0]
[3, 4, 0, 1, 2]
[0, 1, 2, 3, 4]
[3, 4, 0, 1, 2]
[1, 2, 3, 4, 0]
[4, 0, 1, 2, 3]
[2, 3, 4, 0, 1]
[0, 1, 2, 3, 4]
[4, 0, 1, 2, 3]
[3, 4, 0, 1, 2]
[2, 3, 4, 0, 1]
[1, 2, 3, 4, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
The info given in the OP is almost correct. As noted in Jyrki Lahtonen's answer $k$ cannot be congruent to $n$.
In $A_k(i,j)$, $k$ is the index of the square: the algorithm generates $n-1$ MOLS, one for each $k$ in $1,cdots,n-1$. Using normal matrix conventions, $i$ is the row index and $j$ is the column index, but the formula still works if those are swapped.
Here's some rudimentary Python code that uses that formula to generate a set of mutually orthogonal latin squares and then tests each combination for orthogonality. This code was developed using Python 2.6 but it should run correctly on Python 3.
In this code $i$ and $j$ run from 0 to $n-1$ and $k$ runs from 1 to $n-1$; note that $n$ must be prime.
from __future__ import print_function
def show_grid(g):
for row in g:
print(row)
print()
def test_mols(g):
''' check that all entries in g are unique '''
size = len(g) ** 2
a = set()
for row in g:
a.update(row)
return len(a) == size
def mols(n):
''' Generate a set of mutually orthogonal latin squares
n must be prime
'''
r = range(n)
#Generate each Latin square
allgrids =
for k in range(1, n):
grid =
for i in r:
row =
for j in r:
a = (k*i + j) % n
row.append(a)
grid.append(row)
allgrids.append(grid)
for g in allgrids:
show_grid(g)
print('- ' * 20 + 'n')
#Combine the squares to show their orthoganility
m = len(allgrids)
for i in range(m):
g0 = allgrids[i]
for j in range(i+1, m):
g1 = allgrids[j]
newgrid =
for r0, r1 in zip(g0, g1):
newgrid.append(zip(r0, r1))
print(test_mols(newgrid))
show_grid(newgrid)
mols(3)
output for n=3
[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]
[2, 0, 1]
[1, 2, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2)]
[(1, 2), (2, 0), (0, 1)]
[(2, 1), (0, 2), (1, 0)]
output for n=5
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 0]
[2, 3, 4, 0, 1]
[3, 4, 0, 1, 2]
[4, 0, 1, 2, 3]
[0, 1, 2, 3, 4]
[2, 3, 4, 0, 1]
[4, 0, 1, 2, 3]
[1, 2, 3, 4, 0]
[3, 4, 0, 1, 2]
[0, 1, 2, 3, 4]
[3, 4, 0, 1, 2]
[1, 2, 3, 4, 0]
[4, 0, 1, 2, 3]
[2, 3, 4, 0, 1]
[0, 1, 2, 3, 4]
[4, 0, 1, 2, 3]
[3, 4, 0, 1, 2]
[2, 3, 4, 0, 1]
[1, 2, 3, 4, 0]
- - - - - - - - - - - - - - - - - - - -
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 3), (3, 4), (4, 0), (0, 1), (1, 2)]
[(4, 1), (0, 2), (1, 3), (2, 4), (3, 0)]
[(1, 4), (2, 0), (3, 1), (4, 2), (0, 3)]
[(3, 2), (4, 3), (0, 4), (1, 0), (2, 1)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(2, 4), (3, 0), (4, 1), (0, 2), (1, 3)]
[(4, 3), (0, 4), (1, 0), (2, 1), (3, 2)]
[(1, 2), (2, 3), (3, 4), (4, 0), (0, 1)]
[(3, 1), (4, 2), (0, 3), (1, 4), (2, 0)]
True
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
[(3, 4), (4, 0), (0, 1), (1, 2), (2, 3)]
[(1, 3), (2, 4), (3, 0), (4, 1), (0, 2)]
[(4, 2), (0, 3), (1, 4), (2, 0), (3, 1)]
[(2, 1), (3, 2), (4, 3), (0, 4), (1, 0)]
edited Aug 31 at 1:03
answered Jan 24 '16 at 13:18
PM 2Ring
3,145617
3,145617
Thank you very much! So the "n" has to be: n>=m and n-1 >=number of parameters. Where "m" is the number of values (e.g. a parameter can have 4 values). And that n has to be prime. So if I have 4 parameters that have 5 values, I will need squares of size 5.
â Pietross
Jan 24 '16 at 13:34
add a comment |Â
Thank you very much! So the "n" has to be: n>=m and n-1 >=number of parameters. Where "m" is the number of values (e.g. a parameter can have 4 values). And that n has to be prime. So if I have 4 parameters that have 5 values, I will need squares of size 5.
â Pietross
Jan 24 '16 at 13:34
Thank you very much! So the "n" has to be: n>=m and n-1 >=number of parameters. Where "m" is the number of values (e.g. a parameter can have 4 values). And that n has to be prime. So if I have 4 parameters that have 5 values, I will need squares of size 5.
â Pietross
Jan 24 '16 at 13:34
Thank you very much! So the "n" has to be: n>=m and n-1 >=number of parameters. Where "m" is the number of values (e.g. a parameter can have 4 values). And that n has to be prime. So if I have 4 parameters that have 5 values, I will need squares of size 5.
â Pietross
Jan 24 '16 at 13:34
add a comment |Â
up vote
1
down vote
Yes, that formula works. If $n=p$ is a prime it gives you a set of $p-1$ MOLS - one for each $k=1,2,ldots,p-1$. The variables $i$ and $j$ stand for the row and column index respectively.
If $n=p^m$ is a power of a prime $p$, then there exists a similar formula for $n-1$ MOLS, but that requires you to do arithmetic in an extension field of integers modulo $p$.
Thanks. So "k" is the square and i and j are its rows and columns, if I get it right. Out of curiosity, why there is "A" in the formula?
â Pietross
Jan 24 '16 at 13:36
@Pietross: $A_k$ is just the name of the $k$th array.
â PM 2Ring
Jan 24 '16 at 13:39
@PM 2Ring Thanks. What if N=8? Or if that happens, should I go for the next closest prime number?
â Pietross
Jan 24 '16 at 14:48
@Pietross: Well, you could, but using the next prime, 11, gives you a lot of "wasted" combinations, since $11^2$ is almost double $8^2$. As Jyrki says, there are ways to generate MOLS for non-primes. It's pretty easy to generate a pair of MOLS for any odd $n$: that's a standard way to generate magic squares. But that's (possibly) a topic for a new question...
â PM 2Ring
Jan 24 '16 at 14:58
@PM 2Ring Thanks. One last thing - how do I know the value of K? Assume there are 4 parameters, some of which can have 5 values. So n=5. But when I want to code the actual algorithm, how do I determine k?
â Pietross
Jan 24 '16 at 15:01
 |Â
show 1 more comment
up vote
1
down vote
Yes, that formula works. If $n=p$ is a prime it gives you a set of $p-1$ MOLS - one for each $k=1,2,ldots,p-1$. The variables $i$ and $j$ stand for the row and column index respectively.
If $n=p^m$ is a power of a prime $p$, then there exists a similar formula for $n-1$ MOLS, but that requires you to do arithmetic in an extension field of integers modulo $p$.
Thanks. So "k" is the square and i and j are its rows and columns, if I get it right. Out of curiosity, why there is "A" in the formula?
â Pietross
Jan 24 '16 at 13:36
@Pietross: $A_k$ is just the name of the $k$th array.
â PM 2Ring
Jan 24 '16 at 13:39
@PM 2Ring Thanks. What if N=8? Or if that happens, should I go for the next closest prime number?
â Pietross
Jan 24 '16 at 14:48
@Pietross: Well, you could, but using the next prime, 11, gives you a lot of "wasted" combinations, since $11^2$ is almost double $8^2$. As Jyrki says, there are ways to generate MOLS for non-primes. It's pretty easy to generate a pair of MOLS for any odd $n$: that's a standard way to generate magic squares. But that's (possibly) a topic for a new question...
â PM 2Ring
Jan 24 '16 at 14:58
@PM 2Ring Thanks. One last thing - how do I know the value of K? Assume there are 4 parameters, some of which can have 5 values. So n=5. But when I want to code the actual algorithm, how do I determine k?
â Pietross
Jan 24 '16 at 15:01
 |Â
show 1 more comment
up vote
1
down vote
up vote
1
down vote
Yes, that formula works. If $n=p$ is a prime it gives you a set of $p-1$ MOLS - one for each $k=1,2,ldots,p-1$. The variables $i$ and $j$ stand for the row and column index respectively.
If $n=p^m$ is a power of a prime $p$, then there exists a similar formula for $n-1$ MOLS, but that requires you to do arithmetic in an extension field of integers modulo $p$.
Yes, that formula works. If $n=p$ is a prime it gives you a set of $p-1$ MOLS - one for each $k=1,2,ldots,p-1$. The variables $i$ and $j$ stand for the row and column index respectively.
If $n=p^m$ is a power of a prime $p$, then there exists a similar formula for $n-1$ MOLS, but that requires you to do arithmetic in an extension field of integers modulo $p$.
answered Jan 24 '16 at 12:53
community wiki
Jyrki Lahtonen
Thanks. So "k" is the square and i and j are its rows and columns, if I get it right. Out of curiosity, why there is "A" in the formula?
â Pietross
Jan 24 '16 at 13:36
@Pietross: $A_k$ is just the name of the $k$th array.
â PM 2Ring
Jan 24 '16 at 13:39
@PM 2Ring Thanks. What if N=8? Or if that happens, should I go for the next closest prime number?
â Pietross
Jan 24 '16 at 14:48
@Pietross: Well, you could, but using the next prime, 11, gives you a lot of "wasted" combinations, since $11^2$ is almost double $8^2$. As Jyrki says, there are ways to generate MOLS for non-primes. It's pretty easy to generate a pair of MOLS for any odd $n$: that's a standard way to generate magic squares. But that's (possibly) a topic for a new question...
â PM 2Ring
Jan 24 '16 at 14:58
@PM 2Ring Thanks. One last thing - how do I know the value of K? Assume there are 4 parameters, some of which can have 5 values. So n=5. But when I want to code the actual algorithm, how do I determine k?
â Pietross
Jan 24 '16 at 15:01
 |Â
show 1 more comment
Thanks. So "k" is the square and i and j are its rows and columns, if I get it right. Out of curiosity, why there is "A" in the formula?
â Pietross
Jan 24 '16 at 13:36
@Pietross: $A_k$ is just the name of the $k$th array.
â PM 2Ring
Jan 24 '16 at 13:39
@PM 2Ring Thanks. What if N=8? Or if that happens, should I go for the next closest prime number?
â Pietross
Jan 24 '16 at 14:48
@Pietross: Well, you could, but using the next prime, 11, gives you a lot of "wasted" combinations, since $11^2$ is almost double $8^2$. As Jyrki says, there are ways to generate MOLS for non-primes. It's pretty easy to generate a pair of MOLS for any odd $n$: that's a standard way to generate magic squares. But that's (possibly) a topic for a new question...
â PM 2Ring
Jan 24 '16 at 14:58
@PM 2Ring Thanks. One last thing - how do I know the value of K? Assume there are 4 parameters, some of which can have 5 values. So n=5. But when I want to code the actual algorithm, how do I determine k?
â Pietross
Jan 24 '16 at 15:01
Thanks. So "k" is the square and i and j are its rows and columns, if I get it right. Out of curiosity, why there is "A" in the formula?
â Pietross
Jan 24 '16 at 13:36
Thanks. So "k" is the square and i and j are its rows and columns, if I get it right. Out of curiosity, why there is "A" in the formula?
â Pietross
Jan 24 '16 at 13:36
@Pietross: $A_k$ is just the name of the $k$th array.
â PM 2Ring
Jan 24 '16 at 13:39
@Pietross: $A_k$ is just the name of the $k$th array.
â PM 2Ring
Jan 24 '16 at 13:39
@PM 2Ring Thanks. What if N=8? Or if that happens, should I go for the next closest prime number?
â Pietross
Jan 24 '16 at 14:48
@PM 2Ring Thanks. What if N=8? Or if that happens, should I go for the next closest prime number?
â Pietross
Jan 24 '16 at 14:48
@Pietross: Well, you could, but using the next prime, 11, gives you a lot of "wasted" combinations, since $11^2$ is almost double $8^2$. As Jyrki says, there are ways to generate MOLS for non-primes. It's pretty easy to generate a pair of MOLS for any odd $n$: that's a standard way to generate magic squares. But that's (possibly) a topic for a new question...
â PM 2Ring
Jan 24 '16 at 14:58
@Pietross: Well, you could, but using the next prime, 11, gives you a lot of "wasted" combinations, since $11^2$ is almost double $8^2$. As Jyrki says, there are ways to generate MOLS for non-primes. It's pretty easy to generate a pair of MOLS for any odd $n$: that's a standard way to generate magic squares. But that's (possibly) a topic for a new question...
â PM 2Ring
Jan 24 '16 at 14:58
@PM 2Ring Thanks. One last thing - how do I know the value of K? Assume there are 4 parameters, some of which can have 5 values. So n=5. But when I want to code the actual algorithm, how do I determine k?
â Pietross
Jan 24 '16 at 15:01
@PM 2Ring Thanks. One last thing - how do I know the value of K? Assume there are 4 parameters, some of which can have 5 values. So n=5. But when I want to code the actual algorithm, how do I determine k?
â Pietross
Jan 24 '16 at 15:01
 |Â
show 1 more comment
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f1624841%2falgorithms-for-mutually-orthogonal-latin-squares-a-correct-one%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Include the subject of you question in the body as well. Newspaper headlines don't state "President says X" and then, in the body, never mention the president nor X. The title is not the beginning of the question.
â Thomas Andrews
Jan 24 '16 at 12:42
This is a formula for what exactly?
â Morgan Rodgers
Jan 24 '16 at 12:42
Thanks, I updated the question. The formula should produce the squares required. (is there a way to show the image in the body instead as a link?)
â Pietross
Jan 24 '16 at 12:47
A notion of whether the algorithm is correct depends on the interpretation of inputs $i,j,k$, so it is preferred that you state for your Readers what these mean. I suspect that $k$ should be $0 lt k lt n$, so that $k$ is coprime to (prime) $n$. Then $A_k(i,j)$ should give you a matrix entry ($i$th row and $j$th column, or vice versa, as you wish to interpret).
â hardmath
Jan 24 '16 at 14:48