Вычисление нулевого пространства большой матрицы в R

Я не могу найти какую-либо функцию или пакет для вычисления нулевого пространства или (QR-разложения) в bigmatrix (из library(bigmemory)) в R. Например:

library(bigmemory)

a <- big.matrix(1000000, 1000, type='double', init=0)

Я попробовал следующее, но получил показанные ошибки. Как найти нулевое пространство объекта bigmemory?

a.qr <- Matrix::qr(a)
# Error in as.vector(data) : 
#   no method for coercing this S4 class to a vector
q.null <- MASS::Null(a)
# Error in as.vector(data) : 
#   no method for coercing this S4 class to a vector

Ответы

Ответ 1

Если вы хотите вычислить полное SVD матрицы, вы можете использовать пакет bigstatsr для выполнения вычислений по блоку. A FBM означает "Матрица с резервным копированием" и является объектом, подобным файловому объекту big.matrix с пакетом bigmemory.

library(bigstatsr)
options(bigstatsr.block.sizeGB = 0.5)

# Initialize FBM with random numbers
a <- FBM(1e6, 1e3)
big_apply(a, a.FUN = function(X, ind) {
  X[, ind] <- rnorm(nrow(X) * length(ind))
  NULL
}, a.combine = 'c')

# Compute t(a) * a
K <- big_crossprodSelf(a, big_scale(center = FALSE, scale = FALSE))

# Get v and d where a = u * d * t(v) the SVD of a
eig <- eigen(K[])
v <- eig$vectors
d <- sqrt(eig$values)

# Get u if you need it. It will be of the same size of u
# so that I store it as a FBM.
u <- FBM(nrow(a), ncol(a))
big_apply(u, a.FUN = function(X, ind, a, v, d) {
  X[ind, ] <- sweep(a[ind, ] %*% v, 2, d, "/")
  NULL
}, a.combine = 'c', block.size = 50e3, ind = rows_along(u),
a = a, v = v, d = d)

# Verification
ind <- sample(nrow(a), 1000)
all.equal(a[ind, ], tcrossprod(sweep(u[ind, ], 2, d, "*"), v))

Это занимает около 10 минут на моем компьютере.

Ответ 2

@Mahon @user20650 @F.Privė Для ясности я пинговал команду bigmemory и спросил

По существу, существует ли реализация QR-функции (QR Decomposition), которая работает с большими матрицами памяти?

Я чувствовал, что полезно получить ясность по первоначальному вопросу. @F.Privė - хороший ответ. Надеюсь, ваш ответ и их ответ помогут вести людей в будущем. Их ответ ниже:

Спасибо за примечание. В настоящее время реализация qr-декомпозиции отсутствует. В идеале вы бы реализовали это, используя рефлексы Householder (если матрица плотная) или вращение Гивенса (если оно разрежено).

Пакет irlba совместим с bigmemory. Он обеспечивает усеченное разложение по сингулярным значениям. Итак, если ваша матрица относительно редка, вы можете усечь в ранге матрицы. Вероятно, это ваш лучший вариант. Если вы не знаете ранга, вы можете использовать пакет для обновления обрезания итеративно.

Обратите внимание, что если ваша матрица (высокая и тощая, короткая и жирная), то решение SO в порядке. Однако в любое время, когда вы прибегаете к вычислению перекрестного продукта, вы теряете некоторую числовую стабильность. Это может быть проблемой, если вы планируете инвертировать матрицу.