Моор-Пенроуз обобщен обратный к большой разреженной матрице

У меня квадратная матрица с несколькими десятками тысяч строк и столбцов с несколькими 1 рядом с т 0, поэтому я использую пакет Matrix для эффективного хранения этого в R. Объект base::matrix не может обрабатывать количество ячеек, поскольку у меня заканчивается память.

Моя проблема в том, что мне нужен обратный, а также Моор-Пенроуз, обобщенный инверсный для таких матриц, который я не могу вычислить в настоящее время.

Что я пробовал:

  • solve дает ошибку Error in LU.dgC(a) : cs_lu(A) failed: near-singular A (or out of memory)
  • MASS::ginv не совместим с классом Matrix
  • нет прямого способа конвертировать разреженный Matrix, например. bigmemory::big.matrix, и последнее не работает с MASS::ginv в любом случае
  • если я попытаюсь вычислить факторизацию Choleski матрицы, чтобы позже вызвать Matrix::chol2inv, я получаю следующее сообщение об ошибке:

    Error in .local(x, ...) : 
      internal_chm_factor: Cholesky factorization failed
    In addition: Warning message:
    In .local(x, ...) :
      Cholmod warning 'not positive definite' at file ../Cholesky/t_cholmod_rowfac.c, line 431
    
  • на основе связанного вопроса, я также попробовал пакет pbdDMAT на одном node, но pbdDMAT::chol дал Cholmod error 'out of memory' at file ../Core/cholmod_memory.c, line 147 сообщение об ошибке

Вопрос в двух словах: есть какой-либо способ вычислить обратный и обобщенный метод Мура-Пенроуза для такой разреженной матрицы, а также вернуться к использованию класса Matrix на компьютере с тоннами ОЗУ


Быстрый воспроизводимый пример:

library(Matrix)
n <- 1e5
m <- sparseMatrix(1:n, 1:n, x = 1)
m <- do.call(rBind, lapply(1:10, function(i) {
    set.seed(i)
    m[-sample(1:n, n/3), ]
}))
m <- t(m) %*% m

Некоторые описания (спасибо Габору Гротендику):

> dim(m)
[1] 100000 100000
> sum(m) / prod(dim(m))
[1] 6.6667e-05
> table(rowSums(m))

    0     1     2     3     4     5     6     7     8     9    10 
    5    28   320  1622  5721 13563 22779 26011 19574  8676  1701 
> table(colSums(m))

    0     1     2     3     4     5     6     7     8     9    10 
    5    28   320  1622  5721 13563 22779 26011 19574  8676  1701 

И некоторые сообщения об ошибках:

> Matrix::solve(m)
Error in LU.dgC(a) : cs_lu(A) failed: near-singular A (or out of memory)
> base::solve(m)
Error in asMethod(object) : 
  Cholmod error 'problem too large' at file ../Core/cholmod_dense.c, line 105
> MASS::ginv(m)
Error in MASS::ginv(m) : 'X' must be a numeric or complex matrix

Цель bounty состоит в том, чтобы найти способ вычисления обобщенного инверсного выражения Moore-Penrose для m с объемом памяти менее 8 ГБ (скорость и производительность не важны).

Ответ 1

Если у вас очень мало 1, то ваша матрица, вероятно, будет содержать не более 1 в любом столбце и в любой строке, и в этом случае обобщенный обратный равен транспонированию:

library(Matrix)
set.seed(123)
n <- 1e5
m <- sparseMatrix(sample(1:n, n/10), sample(1:n, n/10), x = 1, dims = c(n, n))

##############################################################################
# confirm that m has no more than one 1 in each row and column
##############################################################################
table(rowSums(m))  # here 90,000 rows are all zero, 10,000 have a single one
##     0     1 
## 90000 10000 

table(colSums(m))  # here 90,000 cols are all zero, 10,000 have a single one
##     0     1 
## 90000 10000 

##############################################################################
# calculate generalized inverse
##############################################################################
minv <- t(m)

##############################################################################
# check that when multiplied by minv it gives a diagonal matrix of 0 and 1's
##############################################################################
mm <- m %*% minv

table(diag(mm)) # diagonal has 90,000 zeros and 10,000 ones
##     0     1 
## 90000 10000 

diag(mm) <- 0
range(mm) # off diagonals are all zero
## [1] 0 0

ПЕРЕСМОТРЕННЫЙ Улучшенная презентация.