Random latin squares
latin.Rd
Various functionality for generating random latin squares. Function
latin()
itself is a synonym for circulant()
and is
documented at circulant.Rd
.
Usage
incidence(a)
is.incidence(a, include.improper)
is.incidence.improper(a)
unincidence(a)
inc_to_inc(a)
another_latin(a)
another_incidence(i)
rlatin(n,size=NULL,start=NULL,burnin=NULL)
Details
Function
latin()
, when called with aFunction
incidence()
takes an integer array (specifically, a latin square) and returns the incidence array as per Jacobson and Matthew 1996Function
is.incidence()
tests for an array being an incidence array; if argumentinclude.improper
isTRUE
, admit an improper arrayFunction
is.incidence.improper()
tests for an array being an improper arrayFunction
unincidence()
converts an incidence array to a latin squareFunction
another_latin()
takes a latin square and returns a different latin squareFunction
another_incidence()
takes an incidence array and returns a different incidence arrayFunction
rlatin()
generates a (Markov) sequence of random latin squares, arranged in a 3D array. Argumentn
specifies how many to generate; argumentsize
gives the size of latin squares generated; argumentstart
gives the start latin square (it must be latin and is checked withis.latin()
); argumentburnin
gives the burn-in value (number of Markov steps to discard).Default value of
NULL
for argumentsize
means to take the size of argumentstart
; default value ofNULL
for argumentstart
means to usecirculant(size)
As a special case, if argument
size
andstart
both take the default value ofNULL
, then argumentn
is interpreted as the size of a single random latin square to be returned; the other arguments take their default values. This ensures that “rlatin(n)
” returns a single random \(n\times n\) latin square.
A latin square is an \(n\)-by-\(n\) matrix containing integers \(1\) to \(n\) arranged so each number occurs exactly once in each row and once in each column.
From Jacobson and Matthew 1996, an \(n\times n\) latin square LS is equivalent to an \(n\times n\times n\) array A with entries 0 or 1; the dimensions of A are identified with the rows, columns and symbols of LS; a 1 appears in cell \((r,c,s)\) of A iffi the symbol \(s\) appears in row \(r\), column \(s\) of LS. Jacobson and Matthew call this an incidence cube.
The notation is readily generalized to latin hypercubes and
incidence()
is dimensionally vectorized.
An improper incidence cube is an incidence cube that includes a single \(-1\) entry; all other entries must be 0 or 1; and all line sums must equal 1.
References
M. T. Jacobson and P. Matthews 1996. “Generating uniformly distributed random latin squares”. Journal of Combinatorial Designs, volume 4, No. 6, pp405–437
Examples
rlatin(5)
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 5 3 4 2 1
#> [2,] 4 2 3 1 5
#> [3,] 2 1 5 3 4
#> [4,] 1 5 2 4 3
#> [5,] 3 4 1 5 2
rlatin(n=2, size=4, burnin=10)
#> , , 1
#>
#> [,1] [,2] [,3] [,4]
#> [1,] 3 2 1 4
#> [2,] 1 4 3 2
#> [3,] 2 3 4 1
#> [4,] 4 1 2 3
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4]
#> [1,] 3 2 1 4
#> [2,] 1 4 2 3
#> [3,] 2 3 4 1
#> [4,] 4 1 3 2
#>
# An example that allows one to optimize an objective function
# [here f()] over latin squares:
gr <- function(x){ another_latin(matrix(x,7,7)) }
set.seed(0)
index <- sample(49,20)
f <- function(x){ sum(x[index])}
jj <- optim(par=as.vector(latin(7)), fn=f, gr=gr, method="SANN", control=list(maxit=10))
best_latin <- matrix(jj$par,7,7)
print(best_latin)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 1 6 3 4 5 2 7
#> [2,] 5 1 2 3 4 7 6
#> [3,] 7 2 4 6 3 1 5
#> [4,] 6 5 7 1 2 3 4
#> [5,] 4 7 5 2 1 6 3
#> [6,] 3 4 1 7 6 5 2
#> [7,] 2 3 6 5 7 4 1
print(f(best_latin))
#> [1] 68
#compare starting value:
f(circulant(7))
#> [1] 73