• 11 apr 2010

## Introduction

In cubes Murray explained how to represent a cube concisely: "Consider a ,: b where a is a vertex and a+b is the diagonally opposite vertex. An equivalent "cube" with vertex at the origin n would be n ,: b ."
The question now is how to derive the faces of the cube, represented in a similar way.

A k-face is a face of a cube of (arbitrary) dimension d with 0 ≤ k ≤ d . A 2-face is what is normally called "face", a 1-face is an edge and a 0-face is a vertex. A d-face is the complete cube.

## Solutions

### Nikitin

In Nikitin boxes the first general solution was given:

```require 'statfns'
kfaces=:4 : 0"0 2
n=.{:\$y
k=.x
id=.(i.n) (e."1) (n-k) comb n
,/(({.y) +"1 ({:y) *"1 (#^:_1"1 #:@i.@(2 ^ +/))"1 id) ,:"1 ({:y) *"1 -.id
)

C=.4 3 0 ,: _4 _3 _2
<"2 ] 0 kfaces C
┌─────┬──────┬─────┬──────┬─────┬──────┬─────┬──────┐
│4 3 0│4 3 _2│4 0 0│4 0 _2│0 3 0│0 3 _2│0 0 0│0 0 _2│
│0 0 0│0 0  0│0 0 0│0 0  0│0 0 0│0 0  0│0 0 0│0 0  0│
└─────┴──────┴─────┴──────┴─────┴──────┴─────┴──────┘
<"2 ] 1 kfaces C
┌──────┬──────┬──────┬──────┬──────┬───────┬──────┬───────┬──────┬───────┬──────┬───────┐
│4 3  0│4 0  0│0 3  0│0 0  0│4  3 0│4  3 _2│0  3 0│0  3 _2│ 4 3 0│ 4 3 _2│ 4 0 0│ 4 0 _2│
│0 0 _2│0 0 _2│0 0 _2│0 0 _2│0 _3 0│0 _3  0│0 _3 0│0 _3  0│_4 0 0│_4 0  0│_4 0 0│_4 0  0│
└──────┴──────┴──────┴──────┴──────┴───────┴──────┴───────┴──────┴───────┴──────┴───────┘
<"2 ] 2 kfaces C
┌───────┬───────┬───────┬───────┬───────┬────────┐
│4  3  0│0  3  0│ 4 3  0│ 4 0  0│ 4  3 0│ 4  3 _2│
│0 _3 _2│0 _3 _2│_4 0 _2│_4 0 _2│_4 _3 0│_4 _3  0│
└───────┴───────┴───────┴───────┴───────┴────────┘                                        ```

### Boss kfcs

However, as I showed in Boss boxes, kfaces did not work for k=d.

```   <"2 ] 3 kfaces C
|length error: kfaces
|   ,/(({.y)+"1({:y)*"1    (#^:_1"1#:@i.@(2^+/))"1 id),:"1({:y)*"1-.id```

Now I will derive my solution as posted Boss boxes.

Suppose C=: 10 20 30 40 ,: 1 2 3 4 is the origin (or original vertex) and the diagonal (vector) of a 4D cube.
Question is how to generate, say, the 2-faces of that cube.
Let the coordinates be (x,y,z,w).

It is obvious that the diagonal of a face (of the cube) is the projection of the (main) diagonal. So on a plane (z,w) = constant the diagonal is 1 2 0 0. The values these constant can take are one of (z,w) = 30 40, 30 44, 33 40 and 33 44. So these 2-faces can be represented by

```10 20 30 40
1  2  0  0

10 20 30 44
1  2  0  0

10 20 33 40
1  2  0  0

10 20 33 44
1  2  0  0```

So the general rule which can be derived from this is:
A. make the projections of the diagonal on all 2-faces
B. determine the origins of all 2-faces with such a projected diagonal.

A.
For a 2-face, we need 2 non-zeroes so first generate these:

```   [d1=:({:C) *"1 (#~ 2 = +/"1 ) t=. #:i.2^{:\$ C
0 0 3 4
0 2 0 4
0 2 3 0
1 0 0 4
1 0 3 0
1 2 0 0```

These are all the diagonals in the 2-faces.

B.
For each diagonal we get the origins by adding to {.C zero or more of the coordinates of the diagonal which have become 0 in the projection:

```  {: r1=: ({.C) +"1 ({:C) *"1 t ([ #~ 0 = [ +/@:*"(1) 0~:])"_ 1 d1
10 20 30 40
10 20 30 44
10 20 33 40
10 20 33 44```

A. and B. together give the required result:

```   {: r1 ,:"1"_1 d1
10 20 30 40
1  2  0  0

10 20 30 44
1  2  0  0

10 20 33 40
1  2  0  0

10 20 33 44
1  2  0  0```

Bringing this all together and smoothing things up a bit gives

```kfcs=: 3 : 0
(i.>:{:\$y) <@kfcs"0 _ y
:
t1=. (#~ x = +/"1 ) t=. #:i.2 ^ {:\$y
t2=. ({.y) +"1 ({:y) *"1 t1 (] #~ 0 = +/@:*"1)"1 _ t
t2 ,:"1"_1 ({:y) *"1  t1
)

<"2 ] 0 kfcs 4 3 0 ,: _4 _3 _2
+-----+------+-----+------+-----+------+-----+------+
|4 3 0|4 3 _2|4 0 0|4 0 _2|0 3 0|0 3 _2|0 0 0|0 0 _2|
|0 0 0|0 0  0|0 0 0|0 0  0|0 0 0|0 0  0|0 0 0|0 0  0|
+-----+------+-----+------+-----+------+-----+------+

<"2 ] 1 kfcs 4 3 0 ,: _4 _3 _2
+------+-------+------+-------+
|4 3  0|4 0  0 |0 3  0|0 0  0 |
|0 0 _2|0 0 _2 |0 0 _2|0 0 _2 |
+------+-------+------+-------+
|4  3 0|4  3 _2|0  3 0|0  3 _2|
|0 _3 0|0 _3  0|0 _3 0|0 _3  0|
+------+-------+------+-------+
| 4 3 0| 4 3 _2| 4 0 0| 4 0 _2|
|_4 0 0|_4 0  0|_4 0 0|_4 0  0|
+------+-------+------+-------+

<"2 ] 2 kfcs 4 3 0 ,: _4 _3 _2
+-------+--------+
|4  3  0|0  3  0 |
|0 _3 _2|0 _3 _2 |
+-------+--------+
| 4 3  0| 4 0  0 |
|_4 0 _2|_4 0 _2 |
+-------+--------+
| 4  3 0| 4  3 _2|
|_4 _3 0|_4 _3  0|
+-------+--------+

\$&.> kfcs C
+--------+-------+-------+-------+-------+
|1 16 2 4|4 8 2 4|6 4 2 4|4 2 2 4|1 1 2 4|
+--------+-------+-------+-------+-------+```

kfcs has the advantage that the faces were given in a natural order. Apart from that, it has a monad version which gave all the faces.

### Jacoby

Before this thread started, a thread on cubes was initialized by Miller, in which Jacoby already had remarked that it is rather simple to generate the faces of the cube 1 1 1 ,: 1 1 1 by ternary numbers. Here is how I extended it to arbitrary dimensions.

```   (3 : '(([:+/"(1) 0=]) </.]) 3 #.^:_1 i.3^y')4
+-------+-------+-------+-------+-------+
|0 0 0 0|0 0 0 1|0 0 1 1|0 1 1 1|1 1 1 1|
|       |0 0 0 2|0 0 1 2|0 1 1 2|1 1 1 2|
|       |0 0 1 0|0 0 2 1|0 1 2 1|1 1 2 1|
|       |0 0 2 0|0 0 2 2|0 1 2 2|1 1 2 2|
|       |0 1 0 0|0 1 0 1|0 2 1 1|1 2 1 1|
|       |0 2 0 0|0 1 0 2|0 2 1 2|1 2 1 2|
|       |1 0 0 0|0 1 1 0|0 2 2 1|1 2 2 1|
|       |2 0 0 0|0 1 2 0|0 2 2 2|1 2 2 2|
|       |       |0 2 0 1|1 0 1 1|2 1 1 1|
|       |       |0 2 0 2|1 0 1 2|2 1 1 2|
|       |       |0 2 1 0|1 0 2 1|2 1 2 1|
|       |       |0 2 2 0|1 0 2 2|2 1 2 2|
|       |       |1 0 0 1|1 1 0 1|2 2 1 1|
|       |       |1 0 0 2|1 1 0 2|2 2 1 2|
|       |       |1 0 1 0|1 1 1 0|2 2 2 1|
|       |       |1 0 2 0|1 1 2 0|2 2 2 2|
|       |       |1 1 0 0|1 2 0 1|       |
|       |       |1 2 0 0|1 2 0 2|       |
|       |       |2 0 0 1|1 2 1 0|       |
|       |       |2 0 0 2|1 2 2 0|       |
|       |       |2 0 1 0|2 0 1 1|       |
|       |       |2 0 2 0|2 0 1 2|       |
|       |       |2 1 0 0|2 0 2 1|       |
|       |       |2 2 0 0|2 0 2 2|       |
|       |       |       |2 1 0 1|       |
|       |       |       |2 1 0 2|       |
|       |       |       |2 1 1 0|       |
|       |       |       |2 1 2 0|       |
|       |       |       |2 2 0 1|       |
|       |       |       |2 2 0 2|       |
|       |       |       |2 2 1 0|       |
|       |       |       |2 2 2 0|       |
+-------+-------+-------+-------+-------+```

where each box contains the hyper planes of fixed dimension.

### Boss kfcs1

I succeeded in using this method of Jacoby to generate the faces of the cube in the Murray-representation. Since the ternary numbers already gave the structure, the only thing to be done was translating this structure into the desired representation. From now on these two representations will be called ternary for the Jacoby method and diagonal for the Murray-representation.

In a ternary vector as is used here, 0 is a wildcard character, 1 and 2 are just the numbers. So the vector 0 1 2 0 should be interpreted as the edge x2=1 ; x3=2  and x1 , x4 is arbitrary. And the same for other ternary vectors.
Now how must such a ternary vector be translated?

It is obvious that everywhere where a 0 occurs, the diagonal vector pops up.
On the other hand, where a 1 occurs we are in the original vertex and where a 2 occurs we have moved along that axis. An example will clarify.

```From ternary to diagonal:

[C=: 10 20 30 40 ,: 1 2 3 4
10 20 30 40
1  2  3  4

[t=: 0 1 2 0
0 1 2 0
NB. t is a ternary vector to be translated since it represents a 2-face, as can be seen from its both 0`s
NB. f is the corresponding face represented by a b c d ,: p q r s
NB.
NB. Where t ~: 0 we have 0 e.~ {:f or stated otherwise: q = 0 and r = 0
NB. the rest of {:f is such that {:f is the projection of the diagonal 1 2 3 4
NB. so f = a b c d ,: 1 0 0 4
NB.
NB. Now for {.f , where t e. 0 1 we have {.f is equal to the original vertex, which gives a b d = 10 20 40
NB. and where t e. 2 one has {.f equal to +/C, giving c = 33

[f=:10 20 33 40,:1 0 0 4
10 20 33 40
1  0  0  4```

Given a cube in diagonal representation, like C, let's generate all its faces. So first we have to look at its dimension and generate the ternary representation of all the faces of the cube. Then translating each into the diagonal one and we are done.

```   \$ 3 #.^:_1 i.3 ^ {:\$ C       NB. rather straightforward.
81 4

[f=: ((- *) ,: 2 + 0 = ]) t  NB. producing an origin vertex and a diagonal vector for face t
0 0 1 0
3 2 2 3
NB. the 3 gives where the diagonal has to be projected, 2 is to be replaced by 0
NB. the 0 is to be replaced by the original vertex, the 1 by the sum of diagonal and original vertex```

What I would like to do most is to use amend (}) on C  in a special shape, like

```   [c=. ({. , +/ , 0 ,: {:) C
10 20 30 40
11 22 33 44
0  0  0  0
1  2  3  4

f}c
|rank error
|       f}c```

Hui showed how to apply ranks to operators and now I can do

```   f 4 : 'x}y'"1 _ c
10 20 33 40
1  0  0  4```

which is the desired output. Making a verb out of it, I get

```kfcs1=: 3 : 0
(i.>:{:\$y) kfcs1 y
:
t=. (([: +/"(1) 0 = ]) </. ]) 3 #.^:_1 i.3 ^ {:\$y
t=. ((- *),: 2 + 0 = ])"(1) ; x { |.t
c=. ({. , +/ , 0 ,: {:) y
t 4 : 'x}y'"1 _ c
)

\$ kfcs1 C
81 2 4

({:"2</.]) 3 kfcs1 C
+-----------+-----------+-----------+-----------+
|10 20 30 40|10 20 30 40|10 20 30 40|10 20 30 40|
| 1  2  3  0| 1  2  0  4| 1  0  3  4| 0  2  3  4|
|           |           |           |           |
|10 20 30 44|10 20 33 40|10 22 30 40|11 20 30 40|
| 1  2  3  0| 1  2  0  4| 1  0  3  4| 0  2  3  4|
+-----------+-----------+-----------+-----------+```

It is obvious as a monad kfcs1 generates all faces, as a dyad only the x-faces.
kfcs1 is a bit pimped so as to generate lower dimensional faces in an easy way, but is essentially the same as described before.

RE Boss/J-blog/k-faces (last edited 2010-04-13 20:25:22 by RE Boss)