Mutually Orthogonal Latin Squares (MOLS)¶
The main function of this module is mutually_orthogonal_latin_squares()
and can be can be used to generate MOLS (or check that they exist):
sage: MOLS = designs.mutually_orthogonal_latin_squares(4,8)                         # needs sage.schemes
>>> from sage.all import *
>>> MOLS = designs.mutually_orthogonal_latin_squares(Integer(4),Integer(8))                         # needs sage.schemes
For more information on MOLS, see the Wikipedia entry on MOLS. If you are only
interested by latin squares, see latin.
The functions defined here are
| Return \(k\) Mutually Orthogonal \(n\times n\) Latin Squares. | |
| Check that the list  | |
| Return the product of two (or more) latin squares. | |
| Print the MOLS table. | 
Table of MOLS
Sage can produce a table of MOLS similar to the one from the Handbook of Combinatorial Designs [DesignHandbook] (available here).
sage: from sage.combinat.designs.latin_squares import MOLS_table
sage: MOLS_table(600) # long time
       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
    ________________________________________________________________________________
  0| +oo +oo   1   2   3   4   1   6   7   8   2  10   5  12   4   4  15  16   5  18
 20|   4   5   3  22   7  24   4  26   5  28   4  30  31   5   4   5   8  36   4   5
 40|   7  40   5  42   5   6   4  46   8  48   6   5   5  52   5   6   7   7   5  58
 60|   5  60   5   6  63   7   5  66   5   6   6  70   7  72   5   7   6   6   6  78
 80|   9  80   8  82   6   6   6   6   7  88   6   7   6   6   6   6   7  96   6   8
100|   8 100   6 102   7   7   6 106   6 108   6   6  13 112   6   7   6   8   6   6
120|   7 120   6   6   6 124   6 126 127   7   6 130   6   7   6   7   7 136   6 138
140|   6   7   6  10  10   7   6   7   6 148   6 150   7   8   8   7   6 156   7   6
160|   9   7   6 162   6   7   6 166   7 168   6   8   6 172   6   6  14   9   6 178
180|   6 180   6   6   7   9   6  10   6   8   6 190   7 192   6   7   6 196   6 198
200|   7   7   6   7   6   8   6   8  14  11  10 210   6   7   6   7   7   8   6  10
220|   6  12   6 222  13   8   6 226   6 228   6   7   7 232   6   7   6   7   6 238
240|   7 240   6 242   6   7   6  12   7   7   6 250   6  12   9   7 255 256   6  12
260|   6   8   8 262   7   8   7  10   7 268   7 270  15  16   6  13  10 276   6   9
280|   7 280   6 282   6  12   6   7  15 288   6   6   6 292   6   6   7  10  10  12
300|   7   7   7   7  15  15   6 306   7   7   7 310   7 312   7  10   7 316   7  10
320|  15  15   6  16   8  12   6   7   7   9   6 330   7   8   7   6   7 336   6   7
340|   6  10  10 342   7   7   6 346   6 348   8  12  18 352   6   9   7   9   6 358
360|   7 360   6   7   7   7   6 366  15  15   7  15   7 372   7  15   7  13   7 378
380|   7  12   7 382  15  15   7  15   7 388   7  16   7   7   7   7   8 396   7   7
400|  15 400   7  15  11   8   7  15   8 408   7  13   8  12  10   9  18  15   7 418
420|   7 420   7  15   7  16   6   7   7   7   6 430  15 432   6  15   6  18   7 438
440|   7  15   7 442   7  13   7  11  15 448   7  15   7   7   7  15   7 456   7  16
460|   7 460   7 462  15  15   7 466   8   8   7  15   7  15  10  18   7  15   6 478
480|  15  15   6  15   8   7   6 486   7  15   6 490   6  16   6   7  15  15   6 498
500|   7   8   9 502   7  15   6  15   7 508   6  15 511  18   7  15   8  12   8  15
520|   8 520  10 522  12  15   8  16  15 528   7  15   8  12   7  15   8  15  10  15
540|  12 540   7  15  18   7   7 546   7   8   7  18   7   7   7   7   7 556   7  12
560|  15   7   7 562   7   7   6   7   7 568   6 570   7   7  15  22   8 576   7   7
580|   7   8   7  10   7   8   7 586   7  18  17   7  15 592   8  15   7   7   8 598
>>> from sage.all import *
>>> from sage.combinat.designs.latin_squares import MOLS_table
>>> MOLS_table(Integer(600)) # long time
       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
    ________________________________________________________________________________
  0| +oo +oo   1   2   3   4   1   6   7   8   2  10   5  12   4   4  15  16   5  18
 20|   4   5   3  22   7  24   4  26   5  28   4  30  31   5   4   5   8  36   4   5
 40|   7  40   5  42   5   6   4  46   8  48   6   5   5  52   5   6   7   7   5  58
 60|   5  60   5   6  63   7   5  66   5   6   6  70   7  72   5   7   6   6   6  78
 80|   9  80   8  82   6   6   6   6   7  88   6   7   6   6   6   6   7  96   6   8
100|   8 100   6 102   7   7   6 106   6 108   6   6  13 112   6   7   6   8   6   6
120|   7 120   6   6   6 124   6 126 127   7   6 130   6   7   6   7   7 136   6 138
140|   6   7   6  10  10   7   6   7   6 148   6 150   7   8   8   7   6 156   7   6
160|   9   7   6 162   6   7   6 166   7 168   6   8   6 172   6   6  14   9   6 178
180|   6 180   6   6   7   9   6  10   6   8   6 190   7 192   6   7   6 196   6 198
200|   7   7   6   7   6   8   6   8  14  11  10 210   6   7   6   7   7   8   6  10
220|   6  12   6 222  13   8   6 226   6 228   6   7   7 232   6   7   6   7   6 238
240|   7 240   6 242   6   7   6  12   7   7   6 250   6  12   9   7 255 256   6  12
260|   6   8   8 262   7   8   7  10   7 268   7 270  15  16   6  13  10 276   6   9
280|   7 280   6 282   6  12   6   7  15 288   6   6   6 292   6   6   7  10  10  12
300|   7   7   7   7  15  15   6 306   7   7   7 310   7 312   7  10   7 316   7  10
320|  15  15   6  16   8  12   6   7   7   9   6 330   7   8   7   6   7 336   6   7
340|   6  10  10 342   7   7   6 346   6 348   8  12  18 352   6   9   7   9   6 358
360|   7 360   6   7   7   7   6 366  15  15   7  15   7 372   7  15   7  13   7 378
380|   7  12   7 382  15  15   7  15   7 388   7  16   7   7   7   7   8 396   7   7
400|  15 400   7  15  11   8   7  15   8 408   7  13   8  12  10   9  18  15   7 418
420|   7 420   7  15   7  16   6   7   7   7   6 430  15 432   6  15   6  18   7 438
440|   7  15   7 442   7  13   7  11  15 448   7  15   7   7   7  15   7 456   7  16
460|   7 460   7 462  15  15   7 466   8   8   7  15   7  15  10  18   7  15   6 478
480|  15  15   6  15   8   7   6 486   7  15   6 490   6  16   6   7  15  15   6 498
500|   7   8   9 502   7  15   6  15   7 508   6  15 511  18   7  15   8  12   8  15
520|   8 520  10 522  12  15   8  16  15 528   7  15   8  12   7  15   8  15  10  15
540|  12 540   7  15  18   7   7 546   7   8   7  18   7   7   7   7   7 556   7  12
560|  15   7   7 562   7   7   6   7   7 568   6 570   7   7  15  22   8 576   7   7
580|   7   8   7  10   7   8   7 586   7  18  17   7  15 592   8  15   7   7   8 598
Comparison with the results from the Handbook of Combinatorial Designs (2ed) [DesignHandbook]:
sage: MOLS_table(600,compare=True) # long time
        0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
    ________________________________________________________________________________
  0|                                                           +               +
 20|
 40|
 60|
 80|
100|
120|
140|
160|
180|
200|       -
220|
240|
260|
280|
300|
320|                                                                   -
340|
360|   -                   -
380|                                                       -
400|
420|                                       -
440|
460|
480|
500|       -
520|
540|
560|
580|
>>> from sage.all import *
>>> MOLS_table(Integer(600),compare=True) # long time
        0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
    ________________________________________________________________________________
  0|                                                           +               +
 20|
 40|
 60|
 80|
100|
120|
140|
160|
180|
200|       -
220|
240|
260|
280|
300|
320|                                                                   -
340|
360|   -                   -
380|                                                       -
400|
420|                                       -
440|
460|
480|
500|       -
520|
540|
560|
580|
Todo
Look at [ColDin01].
REFERENCES:
Douglas R. Stinson, Combinatorial designs: construction and analysis, Springer, 2004.
Charles Colbourn, Jeffrey Dinitz, Mutually orthogonal latin squares: a brief survey of constructions, Volume 95, Issues 1-2, Pages 9-48, Journal of Statistical Planning and Inference, Springer, 1 May 2001.
Functions¶
- sage.combinat.designs.latin_squares.MOLS_table(start, stop=None, compare=False, width=None)[source]¶
- Print the MOLS table that Sage can produce. - INPUT: - start,- stop– integers; print the table of MOLS for value of \(n\) such that- start<=n<stop. If only one integer is given as input, it is interpreted as the value of- stopwith- start=0(same behaviour as- range).
- compare– boolean; if sets to- Truethe MOLS displays with \(+\) and \(-\) entries its difference with the table from the Handbook of Combinatorial Designs (2ed).
- width– integer; the width of each column of the table. By default, it is computed from range of values determined by the parameters- startand- stop.
 - EXAMPLES: - sage: # needs sage.schemes sage: from sage.combinat.designs.latin_squares import MOLS_table sage: MOLS_table(100) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ________________________________________________________________________________ 0| +oo +oo 1 2 3 4 1 6 7 8 2 10 5 12 4 4 15 16 5 18 20| 4 5 3 22 7 24 4 26 5 28 4 30 31 5 4 5 8 36 4 5 40| 7 40 5 42 5 6 4 46 8 48 6 5 5 52 5 6 7 7 5 58 60| 5 60 5 6 63 7 5 66 5 6 6 70 7 72 5 7 6 6 6 78 80| 9 80 8 82 6 6 6 6 7 88 6 7 6 6 6 6 7 96 6 8 sage: MOLS_table(100, width=4) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ____________________________________________________________________________________________________ 0| +oo +oo 1 2 3 4 1 6 7 8 2 10 5 12 4 4 15 16 5 18 20| 4 5 3 22 7 24 4 26 5 28 4 30 31 5 4 5 8 36 4 5 40| 7 40 5 42 5 6 4 46 8 48 6 5 5 52 5 6 7 7 5 58 60| 5 60 5 6 63 7 5 66 5 6 6 70 7 72 5 7 6 6 6 78 80| 9 80 8 82 6 6 6 6 7 88 6 7 6 6 6 6 7 96 6 8 sage: MOLS_table(100, compare=True) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ________________________________________________________________________________ 0| + + 20| 40| 60| 80| sage: MOLS_table(50, 100, compare=True) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ________________________________________________________________________________ 40| 60| 80| - >>> from sage.all import * >>> # needs sage.schemes >>> from sage.combinat.designs.latin_squares import MOLS_table >>> MOLS_table(Integer(100)) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ________________________________________________________________________________ 0| +oo +oo 1 2 3 4 1 6 7 8 2 10 5 12 4 4 15 16 5 18 20| 4 5 3 22 7 24 4 26 5 28 4 30 31 5 4 5 8 36 4 5 40| 7 40 5 42 5 6 4 46 8 48 6 5 5 52 5 6 7 7 5 58 60| 5 60 5 6 63 7 5 66 5 6 6 70 7 72 5 7 6 6 6 78 80| 9 80 8 82 6 6 6 6 7 88 6 7 6 6 6 6 7 96 6 8 >>> MOLS_table(Integer(100), width=Integer(4)) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ____________________________________________________________________________________________________ 0| +oo +oo 1 2 3 4 1 6 7 8 2 10 5 12 4 4 15 16 5 18 20| 4 5 3 22 7 24 4 26 5 28 4 30 31 5 4 5 8 36 4 5 40| 7 40 5 42 5 6 4 46 8 48 6 5 5 52 5 6 7 7 5 58 60| 5 60 5 6 63 7 5 66 5 6 6 70 7 72 5 7 6 6 6 78 80| 9 80 8 82 6 6 6 6 7 88 6 7 6 6 6 6 7 96 6 8 >>> MOLS_table(Integer(100), compare=True) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ________________________________________________________________________________ 0| + + 20| 40| 60| 80| >>> MOLS_table(Integer(50), Integer(100), compare=True) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ________________________________________________________________________________ 40| 60| 80| 
- sage.combinat.designs.latin_squares.are_mutually_orthogonal_latin_squares(l, verbose=False)[source]¶
- Check whether the list of matrices in - lform mutually orthogonal latin squares.- INPUT: - verbose– if- Truethen print why the list of matrices provided are not mutually orthogonal latin squares
 - EXAMPLES: - sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: m1 = matrix([[0,1,2],[2,0,1],[1,2,0]]) sage: m2 = matrix([[0,1,2],[1,2,0],[2,0,1]]) sage: m3 = matrix([[0,1,2],[2,0,1],[1,2,0]]) sage: are_mutually_orthogonal_latin_squares([m1,m2]) True sage: are_mutually_orthogonal_latin_squares([m1,m3]) False sage: are_mutually_orthogonal_latin_squares([m2,m3]) True sage: are_mutually_orthogonal_latin_squares([m1,m2,m3], verbose=True) Squares 0 and 2 are not orthogonal False sage: m = designs.mutually_orthogonal_latin_squares(7,8) # needs sage.schemes sage: are_mutually_orthogonal_latin_squares(m) # needs sage.schemes True - >>> from sage.all import * >>> from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares >>> m1 = matrix([[Integer(0),Integer(1),Integer(2)],[Integer(2),Integer(0),Integer(1)],[Integer(1),Integer(2),Integer(0)]]) >>> m2 = matrix([[Integer(0),Integer(1),Integer(2)],[Integer(1),Integer(2),Integer(0)],[Integer(2),Integer(0),Integer(1)]]) >>> m3 = matrix([[Integer(0),Integer(1),Integer(2)],[Integer(2),Integer(0),Integer(1)],[Integer(1),Integer(2),Integer(0)]]) >>> are_mutually_orthogonal_latin_squares([m1,m2]) True >>> are_mutually_orthogonal_latin_squares([m1,m3]) False >>> are_mutually_orthogonal_latin_squares([m2,m3]) True >>> are_mutually_orthogonal_latin_squares([m1,m2,m3], verbose=True) Squares 0 and 2 are not orthogonal False >>> m = designs.mutually_orthogonal_latin_squares(Integer(7),Integer(8)) # needs sage.schemes >>> are_mutually_orthogonal_latin_squares(m) # needs sage.schemes True 
- sage.combinat.designs.latin_squares.latin_square_product(M, N, *others)[source]¶
- Return the product of two (or more) latin squares. - Given two Latin Squares \(M,N\) of respective sizes \(m,n\), the direct product \(M\times N\) of size \(mn\) is defined by \((M\times N)((i_1,i_2),(j_1,j_2))=(M(i_1,j_1),N(i_2,j_2))\) where \(i_1,j_1\in [m], i_2,j_2\in [n]\) - Each pair of values \((i,j)\in [m]\times [n]\) is then relabeled to \(in+j\). - This is Lemma 6.25 of [Stinson2004]. - INPUT: - M,- N,- *others– an arbitrary number of latin squares (greater than or equal to 2)
 - EXAMPLES: - sage: from sage.combinat.designs.latin_squares import latin_square_product sage: m=designs.mutually_orthogonal_latin_squares(3,4)[0] # needs sage.schemes sage: latin_square_product(m,m,m) # needs sage.schemes 64 x 64 sparse matrix over Integer Ring (use the '.str()' method to see the entries) - >>> from sage.all import * >>> from sage.combinat.designs.latin_squares import latin_square_product >>> m=designs.mutually_orthogonal_latin_squares(Integer(3),Integer(4))[Integer(0)] # needs sage.schemes >>> latin_square_product(m,m,m) # needs sage.schemes 64 x 64 sparse matrix over Integer Ring (use the '.str()' method to see the entries) 
- sage.combinat.designs.latin_squares.mutually_orthogonal_latin_squares(k, n, partitions=False, check=True)[source]¶
- Return \(k\) Mutually Orthogonal \(n\times n\) Latin Squares (MOLS). - For more information on Mutually Orthogonal Latin Squares, see - latin_squares.- INPUT: - k– integer; number of MOLS. If- kis- Noneit is set to the largest value available
- n– integer; size of the latin square
- partitions– boolean; a Latin Square can be seen as 3 partitions of the \(n^2\) cells of the array into \(n\) sets of size \(n\), respectively:- The partition of rows 
- The partition of columns 
- The partition of number (cells numbered with 0, cells numbered with 1, …) 
 - These partitions have the additional property that any two sets from different partitions intersect on exactly one element. - When - partitionsis set to- True, this function returns a list of \(k+2\) partitions satisfying this intersection property instead of the \(k+2\) MOLS (though the data is exactly the same in both cases).
- check– boolean (default:- True); whether to check that output is correct before returning it. As this is expected to be useless, you may want to disable it whenever you want speed.
 - EXAMPLES: - sage: designs.mutually_orthogonal_latin_squares(4,5) # needs sage.schemes [ [0 1 2 3 4] [0 1 2 3 4] [0 1 2 3 4] [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] [2 3 4 0 1] [4 0 1 2 3] [1 2 3 4 0] [3 4 0 1 2] [3 4 0 1 2] [1 2 3 4 0] [4 0 1 2 3] [2 3 4 0 1] [4 0 1 2 3], [3 4 0 1 2], [2 3 4 0 1], [1 2 3 4 0] ] sage: designs.mutually_orthogonal_latin_squares(3,7) # needs sage.schemes [ [0 1 2 3 4 5 6] [0 1 2 3 4 5 6] [0 1 2 3 4 5 6] [1 2 3 4 5 6 0] [2 3 4 5 6 0 1] [3 4 5 6 0 1 2] [2 3 4 5 6 0 1] [4 5 6 0 1 2 3] [6 0 1 2 3 4 5] [3 4 5 6 0 1 2] [6 0 1 2 3 4 5] [2 3 4 5 6 0 1] [4 5 6 0 1 2 3] [1 2 3 4 5 6 0] [5 6 0 1 2 3 4] [5 6 0 1 2 3 4] [3 4 5 6 0 1 2] [1 2 3 4 5 6 0] [6 0 1 2 3 4 5], [5 6 0 1 2 3 4], [4 5 6 0 1 2 3] ] sage: designs.mutually_orthogonal_latin_squares(2,5,partitions=True) # needs sage.schemes [[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22, 23, 24]], [[0, 5, 10, 15, 20], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]], [[0, 9, 13, 17, 21], [1, 5, 14, 18, 22], [2, 6, 10, 19, 23], [3, 7, 11, 15, 24], [4, 8, 12, 16, 20]], [[0, 8, 11, 19, 22], [1, 9, 12, 15, 23], [2, 5, 13, 16, 24], [3, 6, 14, 17, 20], [4, 7, 10, 18, 21]]] - >>> from sage.all import * >>> designs.mutually_orthogonal_latin_squares(Integer(4),Integer(5)) # needs sage.schemes [ [0 1 2 3 4] [0 1 2 3 4] [0 1 2 3 4] [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] [2 3 4 0 1] [4 0 1 2 3] [1 2 3 4 0] [3 4 0 1 2] [3 4 0 1 2] [1 2 3 4 0] [4 0 1 2 3] [2 3 4 0 1] [4 0 1 2 3], [3 4 0 1 2], [2 3 4 0 1], [1 2 3 4 0] ] >>> designs.mutually_orthogonal_latin_squares(Integer(3),Integer(7)) # needs sage.schemes [ [0 1 2 3 4 5 6] [0 1 2 3 4 5 6] [0 1 2 3 4 5 6] [1 2 3 4 5 6 0] [2 3 4 5 6 0 1] [3 4 5 6 0 1 2] [2 3 4 5 6 0 1] [4 5 6 0 1 2 3] [6 0 1 2 3 4 5] [3 4 5 6 0 1 2] [6 0 1 2 3 4 5] [2 3 4 5 6 0 1] [4 5 6 0 1 2 3] [1 2 3 4 5 6 0] [5 6 0 1 2 3 4] [5 6 0 1 2 3 4] [3 4 5 6 0 1 2] [1 2 3 4 5 6 0] [6 0 1 2 3 4 5], [5 6 0 1 2 3 4], [4 5 6 0 1 2 3] ] >>> designs.mutually_orthogonal_latin_squares(Integer(2),Integer(5),partitions=True) # needs sage.schemes [[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22, 23, 24]], [[0, 5, 10, 15, 20], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]], [[0, 9, 13, 17, 21], [1, 5, 14, 18, 22], [2, 6, 10, 19, 23], [3, 7, 11, 15, 24], [4, 8, 12, 16, 20]], [[0, 8, 11, 19, 22], [1, 9, 12, 15, 23], [2, 5, 13, 16, 24], [3, 6, 14, 17, 20], [4, 7, 10, 18, 21]]] - What is the maximum number of MOLS of size 8 that Sage knows how to build?: - sage: designs.orthogonal_arrays.largest_available_k(8)-2 # needs sage.schemes 7 - >>> from sage.all import * >>> designs.orthogonal_arrays.largest_available_k(Integer(8))-Integer(2) # needs sage.schemes 7 - If you only want to know if Sage is able to build a given set of MOLS, query the - orthogonal_arrays.*functions:- sage: designs.orthogonal_arrays.is_available(5+2, 5) # 5 MOLS of order 5 False sage: designs.orthogonal_arrays.is_available(4+2,6) # 4 MOLS of order 6 # needs sage.schemes False - >>> from sage.all import * >>> designs.orthogonal_arrays.is_available(Integer(5)+Integer(2), Integer(5)) # 5 MOLS of order 5 False >>> designs.orthogonal_arrays.is_available(Integer(4)+Integer(2),Integer(6)) # 4 MOLS of order 6 # needs sage.schemes False - Sage, however, is not able to prove that the second MOLS do not exist: - sage: designs.orthogonal_arrays.exists(4+2,6) # 4 MOLS of order 6 # needs sage.schemes Unknown - >>> from sage.all import * >>> designs.orthogonal_arrays.exists(Integer(4)+Integer(2),Integer(6)) # 4 MOLS of order 6 # needs sage.schemes Unknown - If you ask for such a MOLS then you will respectively get an informative - EmptySetErroror- NotImplementedError:- sage: designs.mutually_orthogonal_latin_squares(5, 5) Traceback (most recent call last): ... EmptySetError: there exist at most n-1 MOLS of size n if n>=2 sage: designs.mutually_orthogonal_latin_squares(4,6) # needs sage.schemes Traceback (most recent call last): ... NotImplementedError: I don't know how to build 4 MOLS of order 6 - >>> from sage.all import * >>> designs.mutually_orthogonal_latin_squares(Integer(5), Integer(5)) Traceback (most recent call last): ... EmptySetError: there exist at most n-1 MOLS of size n if n>=2 >>> designs.mutually_orthogonal_latin_squares(Integer(4),Integer(6)) # needs sage.schemes Traceback (most recent call last): ... NotImplementedError: I don't know how to build 4 MOLS of order 6