Algorithms for mutually orthogonal latin squares - a correct one?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite
1












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.










share|cite|improve this question



















  • 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














up vote
1
down vote

favorite
1












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.










share|cite|improve this question



















  • 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












up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





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.










share|cite|improve this question















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






share|cite|improve this question















share|cite|improve this question













share|cite|improve this question




share|cite|improve this question








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












  • 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










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)]





share|cite|improve this answer






















  • 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

















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$.






share|cite|improve this answer






















  • 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










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
);
);
, "mathjax-editing");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "69"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















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






























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)]





share|cite|improve this answer






















  • 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














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)]





share|cite|improve this answer






















  • 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












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)]





share|cite|improve this answer














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)]






share|cite|improve this answer














share|cite|improve this answer



share|cite|improve this answer








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
















  • 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










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$.






share|cite|improve this answer






















  • 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














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$.






share|cite|improve this answer






















  • 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












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$.






share|cite|improve this answer














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$.







share|cite|improve this answer














share|cite|improve this answer



share|cite|improve this answer








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
















  • 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

















 

draft saved


draft discarded















































 


draft saved


draft discarded














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













































































這個網誌中的熱門文章

How to combine Bézier curves to a surface?

Mutual Information Always Non-negative

Why am i infinitely getting the same tweet with the Twitter Search API?