LTLA / BiocSingular

Clone of the Bioconductor repository for the BiocSingular package.

Home Page:https://bioconductor.org/packages/devel/bioc/html/BiocSingular.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Feature request: Generalize `runExactSVD`, `runIrlbaSVD` ... and other SVD functions, make methods depend on the matrix type

Yunuuuu opened this issue · comments

I'm implementing the BPCells backend Bioconductor/DelayedArray#110, the BPCells procide a method to runSVD in cpp, it would be awosome if runSVD can dispatch methods depending on the underlying matrix class.

#' @export
#' @import methods
methods::setClass("SpectraParam",
    contains = "BiocSingularParam",
    slots = c(deferred = "logical", fold = "numeric")
)

#' @export
SpectraParam <- function() {
    methods::new("SpectraParam", deferred = FALSE, fold = Inf)
}

#' @export
#' @importMethodsFrom BiocSingular runSVD
methods::setMethod(
    "runSVD", "SpectraParam",
    function(x, k, nu = k, nv = k, center = FALSE, scale = FALSE, ncv = NULL,
             tol = 1e-10, maxitr = 1000, threads = 0L, ..., BSPARAM) {
        svds(
            x = x, k = k, nu = nu, nv = nv,
            center = center, scale = scale, ncv = ncv,
            tol = tol, maxitr = maxitr,
            threads = threads
        )
    }
)

methods::setGeneric("svds", function(x, ...) standardGeneric("svds"))
methods::setMethod(
    "svds", "ANY",
    function(x, k, nu, nv, center, scale, ncv, tol, maxitr, threads) {
        ncv <- ncv %||% min(min(nrow(x), ncol(x)), max(2 * k + 1, 20))
        out <- RSpectra::svds(
            A = x, k = k, nu = nu, nv = nv,
            opts = list(
                ncv = ncv, tol = tol, maxitr = maxitr,
                center = center, scale = scale
            )
        )
        out[c("d", "u", "v")]
    }
)

methods::setMethod(
    "svds", "IterableMatrix",
    function(x, k, nu, nv, center, scale, ncv, tol, maxitr, threads) {
        ncv <- ncv %||% min(min(nrow(x), ncol(x)), max(2 * k + 1, 20))
        out <- BPCells::svds(
            A = x, k = k, nu = nu, nv = nv,
            opts = list(ncv = ncv, tol = tol, maxitr = maxitr),
            threads = threads
        )
        out[c("d", "u", "v")]
    }
)

By the way, if it's possible to add SpectraParam function into BiocSingular