(Although apparently non-standard, here a hypercube is defined to have
dimension \(d\) and order \(n\)---and thus has \(n^d\)
elements).
A semimagic hypercube has all “rook's move” sums
equal to the magic constant (that is, each \(\sum
a[i_1,i_2,\ldots,i_{r-1},,i_{r+1}, \ldots,i_d]\) with \(1\leq r\leq d\) is equal to the magic constant for all values of the
\(i\)'s). In is.semimagichypercube()
, if
give.answers
is TRUE
, the sums returned are in the
form of an array of dimension c(rep(n,d-1),d)
. The first
d-1
dimensions are the coordinates of the projection of the
summed elements onto the surface hypercube. The last dimension
indicates the dimension along which the sum was taken over.
Optional argument func
, defaulting to sum()
, indicates
the function to be taken over each of the d
dimensions.
Currently requires func
to return a scalar.
A Latin hypercube is one in which each line of elements
whose coordinates differ in only one dimension comprises the numbers
\(1\) to \(n\) (or \(0\) to \(n-1\)), not necessarily in
that order. Each integer thus appears \(n^{d-1}\) times.
A magic hypercube is a semimagic hypercube with the
additional requirement that all \(2^{d-1}\) long (ie
extreme point-to-extreme point) diagonals sum correctly. Correct
diagonal summation is tested by is.diagonally.correct()
; by
specifying a function other than sum()
, criteria other than
the diagonals returning the correct sum may be tested.
An Alice hypercube is a different generalization of a
semimagic square to higher dimensions. It is named for A. M. Hankin
(“Alice”), who originally suggested it.
A semimagic hypercube has all one-dimensional subhypercubes (ie
lines) summing correctly. An Alice hypercube is one in which all
ndim
-dimensional subhypercubes have the same sum, where
ndim
is a fixed integer argument. Thus, if a
is a
hypercube of size \(n^d\), is.alicehypercube(a,ndim)
returns TRUE
if all n^{d-ndim}
subhypercubes have the
same sum.
For example, if a
is four-dimensional with dimension
\(5\times 5\times 5\times 5\) then
is.alicehypercube(a,1)
is TRUE
if and only if a
is a semimagic hypercube: all \({4\choose 1}5^3=500\)
one-dimensional subhypercubes have the same sum. Then
is.alicehypercube(a,2)
is TRUE
if all 2-dimensional
subhypercubes (ie all \({4\choose 2}\times 5^2=150\) of
the \(5\times 5\) squares, for example a[,2,4,]
and
a[1,1,,]
) have the same sum. Then
is.alicehypercube(a,3)
means that all 3d subhypercubes (ie
all \({4\choose 3}\times 5^1=20\) of the \(5\times
5\times 5\) cubes, for example a[,,1,]
and
a[4,,,]
) have the same sum. For any hypercube a
,
is.alicehypercube(a,dim(a))
returns TRUE
.
A semimagic hypercube is an Alice hypercube for any value of
ndim
.
A perfect magic hypercube (use is.perfect()
) is
a magic hypercube with all nonbroken diagonals summing correctly.
This is a seriously restrictive requirement for high dimensional
hypercubes. As yet, this function does not take a
give.answers
argument.
A pandiagonal magic hypercube, also Nasik
hypercube (or sometimes just a perfect hypercube) is a
semimagic hypercube with all diagonals, including broken diagonals,
summing correctly. This is not implemented.
The terminology in this area is pretty confusing.
In is.magichypercube()
, if argument give.answers=TRUE
then a list is returned. The first element of this list is Boolean
with TRUE
if the array is a magic hypercube. The second
element and third elements are answers
fromis.semimagichypercube()
and is.diagonally.correct()
respectively.
In is.diagonally.correct()
, if argument
give.answers=TRUE
, the function also returns an array of
dimension c(q,rep(2,d))
(that is, \(q\times 2^d\)
elements), where \(q\) is the length of func()
applied to a
long diagonal of a
(if \(q=1\), the first dimension is
dropped). If \(q=1\), then in dimension d
having index 1
means func()
is applied to elements of a
with the
\(d^{\rm th}\) dimension running over 1:n
; index 2
means to run over n:1
. If \(q>1\), the index of the first
dimension gives the index of func()
, and subsequent dimensions
have indices of 1 or 2 as above and are interpreted in the same way.
An example of a function for which these two are not identical is
given below.
If func=f
where f
is a function returning a vector of
length i
, is.diagonally.correct()
returns an array
out
of dimension c(i,rep(2,d))
, with
out[,i_1,i_2,...,i_d]
being f(x)
where x
is the
appropriate long diagonal. Thus the \(2^d\) equalities
out[,i_1,i_2,...,i_d]==out[,3-i_1,3-i_2,...,3-i_d]
hold if and
only if identical(f(x),f(rev(x)))
is TRUE
for each long
diagonal (a condition met, for example, by sum()
but not by the
identity function or function(x){x[1]}
).