simplify {DelayedArray} | R Documentation

## Simplify a tree of delayed operations

### Description

NOTE: The tools documented in this man page are primarily intended for developers. End users of DelayedArray objects will typically not need them.

`simplify` can be used to simplify this tree.

`contentIsPristine` can be used to know whether the operations in this tree leave the values of the array elements intact or not.

`netSubsetAndAperm` returns an object that represents the net subsetting and net dimension rearrangement of all the operations in this tree.

### Usage

    simplify(x, incremental=FALSE)

    contentIsPristine(x)
    netSubsetAndAperm(x, as.DelayedOp=FALSE)

### Arguments

`x` | Typically a DelayedArray object but can also be a DelayedOp object.
`incremental` | For internal use.
`as.DelayedOp` | `TRUE` or `FALSE`. Control the form of the returned object. See details below.

### Details

`netSubsetAndAperm` is only supported on a DelayedArray object `x` with a single seed i.e. if `nseed(x) == 1`.

The mapping between the array elements of `x` and the array elements of its seed is affected by the following delayed operations carried by `x`: `[`, `drop()`, and `aperm()`. `x` can carry any number of each of these operations in any order but their net result can always be described by a net subsetting followed by a net dimension rearrangement.

`netSubsetAndAperm(x)` returns an object that represents the net subsetting and net dimension rearrangement. The `as.DelayedOp` argument controls in what form this object should be returned:

- If `as.DelayedOp` is `FALSE` (the default), the returned object is a list of subscripts that describes the net subsetting. The list contains one subscript per dimension in the seed. Each subscript can be either a vector of positive integers or a `NULL`. A `NULL` indicates a missing subscript. In addition, if `x` carries delayed operations that rearrange its dimensions (i.e. operations that drop and/or permute some of the original dimensions), the net dimension rearrangement is described in a `dimmap` attribute added to the list. This attribute is an integer vector parallel to `dim(x)` that reports how the dimensions of `x` are mapped to the dimensions of its seed.

- If `as.DelayedOp` is `TRUE`, the returned object is a linear tree with 2 DelayedOp nodes and a leaf node. The leaf node is the seed of `x`. Walking the tree from the seed, the 2 DelayedOp nodes are of type DelayedSubset and DelayedAperm, in that order (this reflects the order in which the operations apply). More precisely, the returned object is a DelayedAperm object with one child (the DelayedSubset object), and one grandchid (the seed of `x`). The DelayedSubset and DelayedAperm nodes represent the net subsetting and net dimension rearrangement, respectively. Either or both of them can be a no-op.

Note that the returned object describes how the array elements of `x` map to their corresponding array element in `seed(x)`.

### Value

The simplified object for `simplify`.

`TRUE` or `FALSE` for `contentIsPristine`.

An ordinary list (possibly with the `dimmap` attribute on it) for `netSubsetAndAperm`. Unless `as.DelayedOp` is set to `TRUE`, in which case a DelayedAperm object is returned (see Details section above for more information).

### See Also

- `showtree` to visualize and access the leaves of a tree of delayed operations carried by a DelayedArray object.

- DelayedOp objects.

- DelayedArray objects.

### Examples

    ## ---------------------------------------------------------------------
    ## Simplification of the tree of delayed operations
    ## ---------------------------------------------------------------------
    m1 <- matrix(runif(150), nrow=15, ncol=10)
    M1 <- DelayedArray(m1)
    showtree(M1)

    ## By default, the tree of delayed operations carried by a DelayedArray
    ## object gets simplified each time a delayed operation is added to it.
    ## This can be disabled via a global option:
    options(DelayedArray.simplify=FALSE)
    M2 <- log(t(M1[5:1, c(TRUE, FALSE)] + 10))[-1, ]
    showtree(M2)  # linear tree

    ## Note that as part of the simplification process, some operations
    ## can be reordered:
    options(DelayedArray.simplify=TRUE)
    M2 <- log(t(M1[5:1, c(TRUE, FALSE)] + 10))[-1, ]
    showtree(M2)  # linear tree

    options(DelayedArray.simplify=FALSE)

    dimnames(M1) <- list(letters[1:15], LETTERS[1:10])
    showtree(M1)  # linear tree

    m2 <- matrix(1:20, nrow=10)
    Y <- cbind(t(M1[ , 10:1]), DelayedArray(m2), M1[6:15, "A", drop=FALSE])
    showtree(Y)   # non-linear tree

    Z <- t(Y[10:1, ])[1:15, ] + 0.4 * M1
    showtree(Z)   # non-linear tree

    Z@seed@seeds
    Z@seed@seeds[[2]]@seed                      # reaching to M1
    Z@seed@seeds[[1]]@seed@seed@seed@seed@seed  # reaching to Y

    ## ---------------------------------------------------------------------
    ## contentIsPristine()
    ## ---------------------------------------------------------------------
    a <- array(1:120, c(4, 5, 2))
    A <- DelayedArray(a)

    stopifnot(contentIsPristine(A))
    stopifnot(contentIsPristine(A[1, , ]))
    stopifnot(contentIsPristine(t(A[1, , ])))
    stopifnot(contentIsPristine(cbind(A[1, , ], A[2, , ])))
    dimnames(A) <- list(LETTERS[1:4], letters[1:5], NULL)
    stopifnot(contentIsPristine(A))

    contentIsPristine(log(A))     # FALSE
    contentIsPristine(A - 11:14)  # FALSE
    contentIsPristine(A * A)      # FALSE

    ## ---------------------------------------------------------------------
    ## netSubsetAndAperm()
    ## ---------------------------------------------------------------------
    a <- array(1:120, c(4, 5, 2))
    M <- aperm(DelayedArray(a)[ , -1, ] / 100)[ , , 3] + 99:98
    M
    showtree(M)

    netSubsetAndAperm(M)  # 1st dimension was dropped, 2nd and 3rd
                          # dimension were permuted (transposition)

    op2 <- netSubsetAndAperm(M, as.DelayedOp=TRUE)
    op2                   # 2 nested delayed operations
    op1 <- op2@seed
    class(op1)            # DelayedSubset
    class(op2)            # DelayedAperm
    op1@index
    op2@perm

    DelayedArray(op2)     # same as M from a [, drop(), and aperm() point of
                          # view but the individual array elements are now
                          # reset to their original values i.e. to the values
                          # they have in the seed
    stopifnot(contentIsPristine(DelayedArray(op2)))

    ## A simple function that returns TRUE if a DelayedArray object carries
    ## no "net subsetting" and no "net dimension rearrangement":
    is_aligned_with_seed <- function(x)
    {
        if (nseed(x) != 1L)
            return(FALSE)
        op2 <- netSubsetAndAperm(x, as.DelayedOp=TRUE)
        op1 <- op2@seed
        is_noop(op1) && is_noop(op2)
    }

    M <- DelayedArray(a[ , , 1])
    is_aligned_with_seed(log(M + 11:14) > 3)            # TRUE
    is_aligned_with_seed(M[4:1, ])                      # FALSE
    is_aligned_with_seed(M[4:1, ][4:1, ])               # TRUE
    is_aligned_with_seed(t(M))                          # FALSE
    is_aligned_with_seed(t(t(M)))                       # TRUE
    is_aligned_with_seed(t(0.5 * t(M[4:1, ])[ , 4:1]))  # TRUE

    options(DelayedArray.simplify=TRUE)

[Package DelayedArray version 0.10.0 Index]