Allows arithmetic operators to be used for manipulation of permutation objects such as addition, multiplication, division, integer powers, etc.

```
# S3 method for permutation
Ops(e1, e2)
cycle_power(x,pow)
cycle_power_single(x,pow)
cycle_sum(e1,e2)
cycle_sum_single(c1,c2)
group_action(e1,e2)
word_equal(e1,e2)
word_prod(e1,e2)
word_prod_single(e1,e2)
permprod(x)
vps(vec,pow)
ccps(n,pow)
helper(e1,e2)
```

x,e1,e2

Objects of class “`permutation`

”

c1,c2

Objects of class `cycle`

pow

Integer vector of powers

vec

In function `vps()`

, a vector of integers
corresponding to a cycle

n

In function `ccps()`

, the integer power to which
`cycle(seq_len(n))`

is to be raised; may be positive or
negative.

None of these functions are really intended for the end user: use the ops as shown in the examples section.

The function `Ops.permutation()`

passes binary arithmetic
operators (“`+`

”, “`*`

”, “`/`

”,
“`^`

”, and “`==`

”) to the appropriate
specialist function.

Multiplication, as in `a*b`

, is effectively
`word_prod(a,b)`

; it coerces its arguments to word form (because
`a*b = b[a]`

).

Raising permutations to integer powers, as in `a^n`

, is
`cycle_power(a,n)`

; it coerces `a`

to cycle form and returns
a cycle. Negative and zero values of `n`

operate as expected.
Function `cycle_power()`

is vectorized; it calls
`cycle_power_single()`

, which is not. This calls `vps()`

(“Vector Power Single”), which checks for simple cases such as
`pow=0`

or the identity permutation; and function `vps()`

calls function `ccps()`

which performs the actual
number-theoretic manipulation to raise a cycle to a power.

Raising a permutation to the power of another permutation, as in
`a^b`

, is idiom for `inverse(b)*a*b`

, sometimes known as
group action; the notation is motivated by the identities
`x^(yz)=(x^y)^z`

and `(xy)^z=x^z*y^z`

.

Permutation addition, as in `a+b`

, is defined if the cycle
representations of the addends are disjoint. The sum is defined as
the permutation given by juxtaposing the cycles of `a`

with those
of `b`

. Note that this operation is commutative. If `a`

and `b`

do not have disjoint cycle representations, an error is
returned. This is useful if you want to guarantee that two
permutations commute (NB: permutation `a`

commutes with
`a^i`

for `i`

any integer, and in particular `a`

commutes with itself. But `a+a`

returns an error: the operation
checks for disjointness, not commutativity).

Permutation “division”, as in `a/b`

, is
`a*inverse(b)`

. Note that `a/b*c`

is evaluated left to
right so is equivalent to `a*inverse(b)*c`

. See note.

Function `helper()`

sorts out recycling for binary functions, the
behaviour of which is inherited from `cbind()`

, which also
handles the names of the returned permutation.

# NOT RUN { x <- rperm(20,9) # word form y <- rperm(20,9) # word form x*y # word form x^5 # coerced to cycle form x^as.cycle(1:5) # group action; coerced to word. x*inverse(x) == id # all TRUE # the 'sum' of two permutations is defined if their cycles are disjoint: as.cycle(1:4) + as.cycle(7:9) data(megaminx) megaminx[1] + megaminx[7:12] # }