#' Samples uniform from the Stiefel Manifold #' #' @param p row dim. #' @param q col dim. #' @return `(p, q)` semi-orthogonal matrix #' @examples #' V <- rStiefel(6, 4) #' @export rStiefl <- function(p, q) { return(qr.Q(qr(matrix(rnorm(p * q, 0, 1), p, q)))) } #' Null space basis of given matrix `V` #' #' @param V `(p, q)` matrix #' @return Semi-orthogonal `(p, p - q)` matrix spaning the null space of `V`. #' @keywords internal #' @export null <- function(V) { tmp <- qr(V) set <- if(tmp$rank == 0L) seq_len(ncol(V)) else -seq_len(tmp$rank) return(qr.Q(tmp, complete=TRUE)[, set, drop=FALSE]) } #' Creates a (numeric) matrix where each column contains #' an element to element matching. #' @param elements numeric vector of elements to match #' @return matrix of size `(2, n * (n - 1) / 2)` for a argument of lenght `n`. #' @keywords internal #' @examples #' elem.pairs(seq.int(2, 5)) #' @export elem.pairs <- function(elements) { # Number of elements to match. n <- length(elements) # Create all combinations. pairs <- rbind(rep(elements, each=n), rep(elements, n)) # Select unique combinations without self interaction. return(pairs[, pairs[1, ] < pairs[2, ]]) }