# 2 Core

The basic engine behind the APL array manipulation functions is the pair aplDecode() and aplEncode(). They make it easy to go back and forth between multidimensional arrays and the one-dimensional vectors that store their elements.

Suppose a is the array

## , , 1
##
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
##
## , , 2
##
##      [,1] [,2] [,3]
## [1,]    7    9   11
## [2,]    8   10   12
##
## , , 3
##
##      [,1] [,2] [,3]
## [1,]   13   15   17
## [2,]   14   16   18
##
## , , 4
##
##      [,1] [,2] [,3]
## [1,]   19   21   23
## [2,]   20   22   24

with shape equal to

## [1] 2 3 4

and rank

## [1] 3

Of course the length of a is the product of the elements of its shape. If r is an integer between 1 and length(a) then aplEncode(r,aplShape(a)) returns the index vector k such that element with indices k of a is a[r].

aplSelect(a, aplEncode (1, aplShape(a)), drop = TRUE)
## [1] 1
aplSelect(a, aplEncode (10, aplShape(a)), drop = TRUE)
## [1] 10
aplSelect(a, aplEncode (24, aplShape(a)), drop = TRUE)
## [1] 24

If k is an admissible index vector then aplDecode(k,aplShape(a)) returns an integer such that element with indices k of a is a[aplDecode(k,dims)]

a[aplDecode (c(1,1,1), aplShape(a))]
## [1] 1
a[aplDecode (c(2,2,2), aplShape(a))]
## [1] 10
a[aplDecode (c(2,3,4), aplShape(a))]
## [1] 24

Note that aplDecode() and aplEncode() are inverses of each other because

r <- 2
r == aplDecode(aplEncode(r, aplShape(a)), aplShape(a))
## [1] TRUE
k <- c(1,2,3)
all(k == aplEncode(aplDecode(k, aplShape(a)), aplShape(a)))
## [1] TRUE

and this is true for all admissible r and k.