# Ops.permutation

##### Arithmetic Ops Group Methods for permutations

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

- Keywords
- symbolmath

##### Usage

```
# 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)
```

##### Arguments

- 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.

##### Details

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.

##### Value

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

##### Note

The class of the returned object is the appropriate one.

It would be nice to define a unary operator which inverted a
permutation. I do not like “`id/x`

” to represent a
permutation inverse: the idiom introduces an utterly redundant object
(“`id`

”), and forces the use of a binary operator where a
unary operator is needed.

The natural unary operator would be the exclamation mark, `!x`

.
However, redefining the exclamation mark to give permutation inverses,
while possible, is not desirable because its precedence is too low.
One would like `!x*y`

to return `inverse(x)*y`

but instead
standard precendence rules means that it returns `inverse(x*y)`

.
This caused such severe cognitive dissonance that I removed it.

There does not appear to be a way to define a new unary operator due to the construction of the parser.

##### Examples

```
# 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]
# }
```

*Documentation reproduced from package permutations, version 1.0-5, License: GPL-2*