R: Permutation matrices

pMatrix-class {Matrix} | R Documentation

## Permutation matrices

### Description

The `"pMatrix"` class is the class of permutation matrices, stored as 1-based integer permutation vectors.

Matrix (vector) multiplication with permutation matrices is equivalent to row or column permutation, and is implemented that way in the Matrix package, see the ‘Details’ below.

### Details

Matrix multiplication with permutation matrices is equivalent to row or column permutation. Here are the four different cases for an arbitrary matrix M and a permutation matrix P (where we assume matching dimensions):

MP | = | `M %*% P` | = | `M[, i(p)]`
PM | = | `P %*% M` | = | `M[ p , ]`
P'M | = | `crossprod(P,M)` (~=`t(P) %*% M`) | = | `M[i(p), ]`
MP' | = | `tcrossprod(M,P)` (~=`M %*% t(P)`) | = | `M[ , p ]`

where `p` is the “permutation vector” corresponding to the permutation matrix `P` (see first note), and `i(p)` is short for `invPerm(p)`.

Also one could argue that these are really only two cases if you take into account that inversion (`solve`) and transposition (`t`) are the same for permutation matrices P.

### Objects from the Class

Objects can be created by calls of the form `new("pMatrix", ...)` or by coercion from an integer permutation vector, see below.

### Slots

`perm`:

  An integer, 1-based permutation vector, i.e. an integer vector of length `Dim[1]` whose elements form a permutation of `1:Dim[1]`.

`Dim`:

  Object of class `"integer"`. The dimensions of the matrix which must be a two-element vector of equal, non-negative integers.

`Dimnames`:

  list of length two; each component containing NULL or a `character` vector length equal the corresponding `Dim` element.

### Extends

Class `"indMatrix"`, directly.

### Methods

%*%

  `signature(x = "matrix", y = "pMatrix")` and other signatures (use `showMethods("%*%", class="pMatrix")`): ...

coerce

  `signature(from = "integer", to = "pMatrix")`: This is enables typical `"pMatrix"` construction, given a permutation vector of `1:n`, see the first example.

coerce

  `signature(from = "numeric", to = "pMatrix")`: a user convenience, to allow `as(perm, "pMatrix")` for numeric `perm` with integer values.

coerce

  `signature(from = "pMatrix", to = "matrix")`: coercion to a traditional FALSE/TRUE `matrix` of `mode` `logical`. (in earlier version of Matrix, it resulted in a 0/1-integer matrix; `logical` makes slightly more sense, corresponding better to the “natural” sparseMatrix counterpart, `"ngTMatrix"`.)

coerce

  `signature(from = "pMatrix", to = "ngTMatrix")`: coercion to sparse logical matrix of class `ngTMatrix`.

determinant

  `signature(x = "pMatrix", logarithm="logical")`: Since permutation matrices are orthogonal, the determinant must be +1 or -1. In fact, it is exactly the sign of the permutation.

solve

  `signature(a = "pMatrix", b = "missing")`: return the inverse permutation matrix; note that `solve(P)` is identical to `t(P)` for permutation matrices. See `solve-methods` for other methods.

t

  `signature(x = "pMatrix")`: return the transpose of the permutation matrix (which is also the inverse of the permutation matrix).

### Note

For every permutation matrix `P`, there is a corresponding permutation vector `p` (of indices, 1:n), and these are related by

     P <- as(p, "pMatrix")
     p <- P@perm

see also the ‘Examples’. “Row-indexing” a permutation matrix typically returns an `"indMatrix"`. See `"indMatrix"` for all other subsetting/indexing and subassignment (`A[..] <- v`) operations.

### See Also

`invPerm(p)` computes the inverse permutation of an integer (index) vector `p`.

### Examples

    (pm1 <- as(as.integer(c(2,3,1)), "pMatrix"))
    t(pm1) # is the same as
    solve(pm1)
    pm1 %*% t(pm1) # check that the transpose is the inverse
    stopifnot(all(diag(3) == as(pm1 %*% t(pm1), "matrix")),
              is.logical(as(pm1, "matrix")))

    set.seed(11)
    ## random permutation matrix :
    (p10 <- as(sample(10),"pMatrix"))

    ## Permute rows / columns of a numeric matrix :
    (mm <- round(array(rnorm(3 * 3), c(3, 3)), 2))
    mm %*% pm1
    pm1 %*% mm
    try(as(as.integer(c(3,3,1)), "pMatrix"))# Error: not a permutation

    as(pm1, "ngTMatrix")
    p10[1:7, 1:4] # gives an "ngTMatrix" (most economic!)

    ## row-indexing of a <pMatrix> keeps it as an <indMatrix>:
    p10[1:3, ]

[Package Matrix version 1.1-4 Index]