`permutations`

packageTo cite the permutations package in publications, please use Hankin (2020). This vignette discusses the
concept of cyclists as used in the `permutations`

package. A
“cyclist” is an object corresponding to a permutation P. It is a list
with elements that are integer vectors corresponding to the cycles of P.
This object is informally known as a cyclist, but there is no S3 class
corresponding to it. For example

```
## [[1]]
## [1] 1 3 4
##
## [[2]]
## [1] 8 9
##
## [[3]]
## [1] 2 5
```

is a cyclist of three cycles: \((134)\), \((89)\), and \((25)\). It corresponds to the permutation \((134)(89)(25)\), or \(\left(\begin{array}{ccccccccc}1&2&3&4&5&6&7&8&9\\3&5&4&1&2&6&7&9&8\end{array}\right)\).

An object of S3 class `cycle`

is a (possibly named) list
of cyclists. NB: there is an unavoidable notational clash here. When
considering a single permutation, “cycle” means group-theoretic cycle;
when considering R objects, “cycle” means an R object of class
`cycle`

whose elements are permutations written in cycle
form. The elements of a cyclist are the disjoint group-theoretic cycles;
in the example above, the group-theoretic cycles were \((134)\), \((89)\), and \((25)\).

A cyclist may be poorly formed in a number of ways: the cycles may
include repeats, or contain elements which are common to more than one
cycle. Such problems are detected by `cyclist_valid()`

:

```
## Warning in cyclist_valid(list(c(1, -3, 4), c(8, 9), c(2, 5))): negative
## elements
```

`## [1] FALSE`

`## Warning in cyclist_valid(list(c(0, 3, 4), c(8, 9), c(2, 5))): zero element`

`## [1] FALSE`

```
## Warning in cyclist_valid(list(c(1.2, 3, 4), c(8, 9), c(2, 5))): non-integer
## entries
```

`## [1] FALSE`

`## Warning in cyclist_valid(list(c(3, 3, 4), c(8, 9), c(2, 5))): repeated value`

`## [1] FALSE`

`## Warning in cyclist_valid(list(c(1, 3, 4), c(1, 9), c(2, 5))): repeated value`

`## [1] FALSE`

Even a well-formed cyclist possesses numerous redundancies: firstly,
because the cycles commute, their order is immaterial (the problem is,
in R a list is ordered. It might have been better to represent a cyclist
as a *set* of (group theoretic) cycles). Secondly, the cycles
themselves are invariant under cyclic permutation: cycle
`(567)`

is identical to `(675)`

and
`(756)`

. In the package, we need cyclists to have a
standardised form. To this end, function `nicify_cyclist()`

takes a cyclist and puts it in a nice form but does not alter the
permutation. It takes a cyclist and orders each cycle so that the
smallest element appears first (that is, it changes `(523)`

to `(235)`

). It then orders the cycles by the smallest
element:

```
## [[1]]
## [1] 9 3 4
##
## [[2]]
## [1] 8 1
##
## [[3]]
## [1] 2 5
```

```
## [[1]]
## [1] 1 8
##
## [[2]]
## [1] 2 5
##
## [[3]]
## [1] 3 4 9
```

Also, there are less serious problems: the cycles may include
length-one cycles; the cycles may start with an element that is not the
smallest (these are not serious in the sense that their presence does
not destroy the interpretation of the argument as a permutation). These
issues are dealt with by `nicify_cyclist()`

, which calls
helper function `remove_length_one()`

:

```
## [[1]]
## [1] 9 3 4
##
## [[2]]
## [1] 7
##
## [[3]]
## [1] 8 1
##
## [[4]]
## [1] 2 5
```

```
## [[1]]
## [1] 1 8
##
## [[2]]
## [1] 2 5
##
## [[3]]
## [1] 3 4 9
```

Function `nicify_cyclist()`

is called automatically in the
package by `cycle()`

so we are guaranteed that
`cycle`

objects are nicified. The package includes
functionality to convert between word and cycle form and the low-level
helper function is `vec2cyclist_single()`

. This takes a
vector of integers, interpreted as a word, and converts it into a
cyclist. Length-one cycles are discarded:

`## [1] 1 2 4 3 5 9 6 7 8`

```
## [1] (34)(6987)
## [coerced from word form]
```

```
## [[1]]
## [1] 3 4
##
## [[2]]
## [1] 6 9 8 7
```

This function is potentially a bottleneck and one of my long-term
ideas is to write it in C. Function
`vec2cyclist_single_cpp()`

is placeholder function that is
not yet written.

Function `cyclist2word_single()`

takes a cyclist and
returns a vector corresponding to a single word. This function is not
intended for everyday use; function `cycle2word()`

is much
more user-friendly.

`## [1] 3 2 4 1 5 6 9 7 8`

The package includes some rudimentary functionality to coerce strings
to cycles. Function `char2cyclist_single()`

takes a character
string and returns a cyclist:

```
## [[1]]
## [1] 3
##
## [[2]]
## [1] 1 3 9
```

```
## [[1]]
## [1] 3 4 2
##
## [[2]]
## [1] 1 9
```

Above, note that the first call does not give a well-specified
cyclist (the number 3 is repeated). Function
`char2cyclist_single()`

does not return an error. To catch
this kind of problem use the more user-friendly function
`char2cycle()`

, which calls the validity checks. This
function returns a cyclist which is not necessarily canonicalized: it
might have length-one cycles, and the cycles themselves might start with
the wrong number. The function attempts to deal with absence of commas
in a sensible way, so `(18,19)(2,5)`

is dealt with
appropriately too. The function is insensitive to spaces.

The user-friendly version `char2cycle()`

performs
canonicalization and also checks for malformed cyclists.

Most users will not deal with cyclists directly. Function
`cycle()`

takes a list of cyclists and returns an object of
class `cycle`

. It nicifies its input before returning it:

```
## [[1]]
## [[1]][[1]]
## [1] 1 2 4
##
## [[1]][[2]]
## [1] 3 6
##
##
## [[2]]
## [[2]][[1]]
## [1] 1 2
##
## [[2]][[2]]
## [1] 3 4 5 6 7
```

`## [1] (124)(36) (12)(34567)`

However, it might be more convenient in practice to use
`as.cycle()`

:

`## [1] (124)(36) (12)(34567)`

Hankin, R. K. S. 2020. “Introducing the Permutations
R Package.” *SoftwareX* 11. https://doi.org/10.1016/j.softx.2020.100453.