Posted on March 10, 2018 by Stéphane Laurent

Nothing really exciting in this post. But these days I did some graphics dealing with hypercubes, and the functions I show below simplified my job. Perhaps it is worth to share.

This Haskell function generates the vertices of the hypercube of a given dimension $$n$$:

ncube :: Int -> [[Int]]
ncube n = concatMap (mapM (\x -> [x,-x])) [replicate n 1]

For example:

> ncube 3
[[1,1,1],[1,1,-1],[1,-1,1],[1,-1,-1],[-1,1,1],[-1,1,-1],[-1,-1,1],[-1,-1,-1]]

It can be useful to have the indices of the vertices. The indexed function of the nice Data.List.Index package is appropriate for that. I also import Text.Show.Pretty to get a pretty output thanks to the pPrint function.

import           Data.List.Index              (indexed)
import           Text.Show.Pretty
> pPrint $indexed$ ncube 3
[ ( 0 , [ 1 , 1 , 1 ] )
, ( 1 , [ 1 , 1 , -1 ] )
, ( 2 , [ 1 , -1 , 1 ] )
, ( 3 , [ 1 , -1 , -1 ] )
, ( 4 , [ -1 , 1 , 1 ] )
, ( 5 , [ -1 , 1 , -1 ] )
, ( 6 , [ -1 , -1 , 1 ] )
, ( 7 , [ -1 , -1 , -1 ] )

Sometimes I prefer to have the index at the second position. Then I use swap:

import           Data.Tuple.Extra             (swap)
> pPrint $map swap$ indexed $ncube 3 [ ( [ 1 , 1 , 1 ] , 0 ) , ( [ 1 , 1 , -1 ] , 1 ) , ( [ 1 , -1 , 1 ] , 2 ) , ( [ 1 , -1 , -1 ] , 3 ) , ( [ -1 , 1 , 1 ] , 4 ) , ( [ -1 , 1 , -1 ] , 5 ) , ( [ -1 , -1 , 1 ] , 6 ) , ( [ -1 , -1 , -1 ] , 7 ) The vertices are not enough to get a graph. We need the hypercube graph $$Q_n$$. It is available in the HaskellForMaths library: import Math.Combinatorics.Graph cubicalgraph :: Graph Int cubicalgraph = q 3 edgesIdxs :: [(Int,Int)] edgesIdxs = map toPair$ edges cubicalgraph
where
toPair x = (x!!0, x!!1)
> pPrint edgesIdxs
[ ( 0 , 1 )
, ( 0 , 2 )
, ( 0 , 4 )
, ( 1 , 3 )
, ( 1 , 5 )
, ( 2 , 3 )
, ( 2 , 6 )
, ( 3 , 7 )
, ( 4 , 5 )
, ( 4 , 6 )
, ( 5 , 7 )
, ( 6 , 7 )
]