Nothing
#' @title Summarize topological data
#'
#' @description These miscellaneous functions are used by various
#' `get_*_range()` functions to [finalize][dials::finalize()] hyperparameter
#' ranges.
#'
#' @details The functions compute the following summaries:
#'
#' \itemize{
#' \item `ph_dim()`:
#' Dimension of a data set for purposes of PH
#' \item `pairs_min()`:
#' Minimum number of persistent pairs of any degree
#' \item `pairs_max()`:
#' Maximum number of persistent pairs of any degree
#' \item `birth_range()`:
#' Range of finite birth values for a given degree
#' \item `pers_max()`:
#' Maximum positive finite persistence for a given degree
#' \item `pers_min()`:
#' Minimum positive finite persistence for a given degree
#' \item `pers_range()`:
#' Range of positive finite persistence for a given degree
#' \item `life_support()`:
#' Range of union of birth--death ranges for a given degree
#' }
#'
#' @name vpd-summarizers
#' @param x Persistence data in a recognizable format.
#' @param hom_degree,hom_degrees Integer (vector) of homological degree(s).
#' @returns A vector of one or two numeric values.
NULL
check_param <- getFromNamespace("check_param", "dials")
subset_positive_finite <- function(x) x[is.finite(x) & x > 0]
# FIXME: should be informed by engine & method, e.g. `ripserr::vietoris_rips()`
# versus `ripserr::cubical()` treat a 2-column matrix as a coordinate matrix and
# as a 2D image, respectively
# FIXME: This is designed for input data but should also apply to persistence
# data.
#' @rdname vpd-summarizers
#' @export
ph_dim <- function(x) {
UseMethod("ph_dim")
}
#' @rdname vpd-summarizers
#' @export
ph_dim.default <- function(x) ncol(as.matrix(x))
#' @rdname vpd-summarizers
#' @export
ph_dim.matrix <- function(x) ncol(x)
#' @rdname vpd-summarizers
#' @export
ph_dim.array <-
function(x) if (is.matrix(x)) ph_dim.default(x) else length(dim(x))
#' @rdname vpd-summarizers
#' @export
ph_dim.data.frame <- function(x) ncol(x)
#' @rdname vpd-summarizers
#' @export
ph_dim.dist <- function(x) as.integer(attr(x, "Size"))
#' @rdname vpd-summarizers
#' @export
ph_dim.ts <- ph_dim.default
#' @rdname vpd-summarizers
#' @export
pairs_min <- function(x, hom_degrees) {
UseMethod("pairs_min")
}
#' @rdname vpd-summarizers
#' @export
pairs_min.default <- function(x, hom_degrees) {
stop("Unrecognized persistent homology class.")
}
#' @rdname vpd-summarizers
#' @export
pairs_min.matrix <- function(x, hom_degrees) {
if (is.null(hom_degrees)) {
min(unname(table(x[, 1L])))
} else {
min(unname(table(x[x[, 1L] %in% hom_degrees, 1L])))
}
}
#' @rdname vpd-summarizers
#' @export
pairs_min.data.frame <-
function(x, hom_degrees) pairs_min.matrix(x, hom_degrees)
#' @rdname vpd-summarizers
#' @export
pairs_min.diagram <-
function(x, hom_degrees) pairs_min.matrix(unclass(x), hom_degrees)
#' @rdname vpd-summarizers
#' @export
pairs_min.PHom <-
function(x, hom_degrees) pairs_min.data.frame(x, hom_degrees)
#' @rdname vpd-summarizers
#' @export
pairs_min.persistence <- function(x, hom_degrees) {
if (is.null(hom_degrees)) {
min(vapply(x$pairs, nrow, 0L))
} else {
min(vapply(x$pairs[hom_degrees + 1L], nrow, 0L))
}
}
#' @rdname vpd-summarizers
#' @export
pairs_max <- function(x, hom_degrees) {
UseMethod("pairs_max")
}
#' @rdname vpd-summarizers
#' @export
pairs_max.default <- function(x, hom_degrees) {
stop("Unrecognized persistent homology class.")
}
#' @rdname vpd-summarizers
#' @export
pairs_max.matrix <- function(x, hom_degrees) {
if (is.null(hom_degrees)) {
max(unname(table(x[, 1L])))
} else {
max(unname(table(x[x[, 1L] %in% hom_degrees, 1L])))
}
}
#' @rdname vpd-summarizers
#' @export
pairs_max.data.frame <-
function(x, hom_degrees) pairs_max.matrix(x, hom_degrees)
#' @rdname vpd-summarizers
#' @export
pairs_max.diagram <-
function(x, hom_degrees) pairs_max.matrix(unclass(x), hom_degrees)
#' @rdname vpd-summarizers
#' @export
pairs_max.PHom <-
function(x, hom_degrees) pairs_max.data.frame(x, hom_degrees)
#' @rdname vpd-summarizers
#' @export
pairs_max.persistence <- function(x, hom_degrees) {
if (is.null(hom_degrees)) {
max(vapply(x$pairs, nrow, 0L))
} else {
max(vapply(x$pairs[hom_degrees + 1L], nrow, 0L))
}
}
#' @rdname vpd-summarizers
#' @export
birth_range <- function(x, hom_degree) {
UseMethod("birth_range")
}
#' @rdname vpd-summarizers
#' @export
birth_range.default <- function(x, hom_degree) {
stop("Unrecognized persistent homology class.")
}
#' @rdname vpd-summarizers
#' @export
birth_range.matrix <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(x[is.finite(x[, 2L]), 2L])
} else {
deg <- x[, 1L] == hom_degree
range(x[deg, 2L][is.finite(x[deg, 2L])])
}
}
#' @rdname vpd-summarizers
#' @export
birth_range.data.frame <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(x[[2L]][is.finite(x[[2L]])])
} else {
deg <- x[[1L]] == hom_degree
range(x[[2L]][deg][is.finite(x[[2L]][deg])])
}
}
#' @rdname vpd-summarizers
#' @export
birth_range.diagram <-
function(x, hom_degree) birth_range.matrix(unclass(x), hom_degree)
#' @rdname vpd-summarizers
#' @export
birth_range.PHom <-
function(x, hom_degree) birth_range.data.frame(x, hom_degree)
#' @rdname vpd-summarizers
#' @export
birth_range.persistence <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(sapply(x$pairs, function(y) {
range(y[is.finite(y[, 1L]), 1L])
}, simplify = TRUE))
} else {
val <- x$pairs[[hom_degree + 1L]][, 1L]
range(val[is.finite(val)])
}
}
#' @rdname vpd-summarizers
#' @export
pers_max <- function(x, hom_degree) {
UseMethod("pers_max")
}
#' @rdname vpd-summarizers
#' @export
pers_max.default <- function(x, hom_degree) {
stop("Unrecognized persistent homology class.")
}
#' @rdname vpd-summarizers
#' @export
pers_max.matrix <- function(x, hom_degree) {
if (is.null(hom_degree)) {
max(subset_positive_finite(x[, 3L] - x[, 2L]))
} else {
deg <- x[, 1L] == hom_degree
max(subset_positive_finite(x[deg, 3L] - x[deg, 2L]))
}
}
#' @rdname vpd-summarizers
#' @export
pers_max.data.frame <- function(x, hom_degree) {
if (is.null(hom_degree)) {
max(subset_positive_finite(x[[3L]] - x[[2L]]))
} else {
deg <- x[[1L]] == hom_degree
max(subset_positive_finite(x[[3L]][deg] - x[[2L]][deg]))
}
}
#' @rdname vpd-summarizers
#' @export
pers_max.diagram <-
function(x, hom_degree) pers_max.matrix(unclass(x), hom_degree)
#' @rdname vpd-summarizers
#' @export
pers_max.PHom <-
function(x, hom_degree) pers_max.data.frame(x, hom_degree)
#' @rdname vpd-summarizers
#' @export
pers_max.persistence <- function(x, hom_degree) {
if (is.null(hom_degree)) {
max(sapply(x$pairs, function(y) {
max(subset_positive_finite(y[, 2L] - y[, 1L]))
}, simplify = TRUE))
} else {
max(subset_positive_finite(x$pairs[[hom_degree + 1L]][, 2L] -
x$pairs[[hom_degree + 1L]][, 1L]))
}
}
#' @rdname vpd-summarizers
#' @export
pers_min <- function(x, hom_degree) {
UseMethod("pers_min")
}
#' @rdname vpd-summarizers
#' @export
pers_min.default <- function(x, hom_degree) {
stop("Unrecognized persistent homology class.")
}
#' @rdname vpd-summarizers
#' @export
pers_min.matrix <- function(x, hom_degree) {
if (is.null(hom_degree)) {
min(subset_positive_finite(x[, 3L] - x[, 2L]))
} else {
deg <- x[, 1L] == hom_degree
min(subset_positive_finite(x[deg, 3L] - x[deg, 2L]))
}
}
#' @rdname vpd-summarizers
#' @export
pers_min.data.frame <- function(x, hom_degree) {
if (is.null(hom_degree)) {
min(subset_positive_finite(x[[3L]] - x[[2L]]))
} else {
deg <- x[[1L]] == hom_degree
min(subset_positive_finite(x[[3L]][deg] - x[[2L]][deg]))
}
}
#' @rdname vpd-summarizers
#' @export
pers_min.diagram <-
function(x, hom_degree) pers_min.matrix(unclass(x), hom_degree)
#' @rdname vpd-summarizers
#' @export
pers_min.PHom <-
function(x, hom_degree) pers_min.data.frame(x, hom_degree)
#' @rdname vpd-summarizers
#' @export
pers_min.persistence <- function(x, hom_degree) {
if (is.null(hom_degree)) {
min(sapply(x$pairs, function(y) {
min(subset_positive_finite(y[, 2L] - y[, 1L]))
}, simplify = TRUE))
} else {
min(subset_positive_finite(x$pairs[[hom_degree + 1L]][, 2L] -
x$pairs[[hom_degree + 1L]][, 1L]))
}
}
#' @rdname vpd-summarizers
#' @export
pers_range <- function(x, hom_degree) {
UseMethod("pers_range")
}
#' @rdname vpd-summarizers
#' @export
pers_range.default <- function(x, hom_degree) {
stop("Unrecognized persistent homology class.")
}
#' @rdname vpd-summarizers
#' @export
pers_range.matrix <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(subset_positive_finite(abs(x[, 3L] - x[, 2L])))
} else {
deg <- x[, 1L] == hom_degree
range(subset_positive_finite(abs(x[deg, 3L] - x[deg, 2L])))
}
}
#' @rdname vpd-summarizers
#' @export
pers_range.data.frame <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(subset_positive_finite(abs(x[[3L]] - x[[2L]])))
} else {
deg <- x[[1L]] == hom_degree
range(subset_positive_finite(abs(x[[3L]][deg] - x[[2L]][deg])))
}
}
#' @rdname vpd-summarizers
#' @export
pers_range.diagram <-
function(x, hom_degree) pers_range.matrix(unclass(x), hom_degree)
#' @rdname vpd-summarizers
#' @export
pers_range.PHom <-
function(x, hom_degree) pers_range.data.frame(x, hom_degree)
#' @rdname vpd-summarizers
#' @export
pers_range.persistence <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(sapply(x$pairs, function(y) {
range(subset_positive_finite(abs(y[, 2L] - y[, 1L])))
}, simplify = TRUE))
} else {
range(subset_positive_finite(abs(x$pairs[[hom_degree + 1L]][, 2L] -
x$pairs[[hom_degree + 1L]][, 1L])))
}
}
#' @rdname vpd-summarizers
#' @export
life_support <- function(x, hom_degree) {
UseMethod("life_support")
}
#' @rdname vpd-summarizers
#' @export
life_support.default <- function(x, hom_degree) {
stop("Unrecognized persistent homology class.")
}
#' @rdname vpd-summarizers
#' @export
life_support.matrix <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(as.vector(x[, c(2L, 3L)]))
} else {
range(as.vector(x[x[, 1L] == hom_degree, c(2L, 3L)]))
}
}
#' @rdname vpd-summarizers
#' @export
life_support.data.frame <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(c(x[[2L]], x[[3L]]))
} else {
r <- x[[1L]] == hom_degree
range(c(x[[2L]][r], x[[3L]][r]))
}
}
#' @rdname vpd-summarizers
#' @export
life_support.diagram <-
function(x, hom_degree) life_support.matrix(unclass(x), hom_degree)
#' @rdname vpd-summarizers
#' @export
life_support.PHom <-
function(x, hom_degree) life_support.data.frame(x, hom_degree)
#' @rdname vpd-summarizers
#' @export
life_support.persistence <- function(x, hom_degree) {
if (is.null(hom_degree)) {
range(do.call(c, x$pairs))
} else {
range(x$pairs[[hom_degree + 1L]])
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.