Как вычислить огромную диагональную обратную матрицу (dim 14000*14000)

Как вычислить обратную огромную (тусклую 14000 * 14000) матрицу? Я пытаюсь это сделать с R, и сообщение об ошибке было показано как:

Error: cannot allocate vector of size 762.9 Mb

Я знаю, что это указывает на отказ в получении памяти. Любая помощь будет оценена по достоинству.

Даже когда я пытался инвертировать скалярную единичную матрицу, R не мог ее решить. Матрица, обратная скалярной единичной матрице, будет той же самой матрицей, но R не может ее решить.

> solve(diag(1,10000,10000))
Error: cannot allocate vector of size 762.9 Mb

person user3478948    schedule 21.05.2014    source источник
comment
Также обратите внимание, что для диагонали m это просто 1 / m.   -  person Julius Vainora    schedule 22.05.2014
comment
Если ваша матрица не разреженная, это будет просто невозможно (или, по крайней мере, очень, очень, очень сложно). В зависимости от того, что вы пытаетесь сделать, часто есть вычислительные сокращения для решения задачи, которые на самом деле не требуют обращения матрицы (например, решение линейных систем, вычисление собственных значений и т. д.).   -  person Ben Bolker    schedule 22.05.2014


Ответы (3)


Для больших разреженных матриц используйте Пакет Matrix:

library(Matrix)

## Construct a memory-efficient representation of a large, sparse, diagonal matrix
dmat <- Diagonal(x=1:14000)

## Finding the inverse is fast and painless
system.time(dmat.inv <- solve(dmat))
#   user  system elapsed 
#      0       0       0 

## Check  that it worked
dmat.inv[c(1:3, 13998:14000), c(1:3, 13998:14000)]
# 6 x 6 diagonal matrix of class "ddiMatrix"
#      [,1] [,2] [,3]      [,4]         [,5]         [,6]        
# [1,]    1    .         .            .            .            .
# [2,]    .  0.5         .            .            .            .
# [3,]    .    . 0.3333333            .            .            .
# [4,]    .    .         . 7.143878e-05            .            .
# [5,]    .    .         .            . 7.143367e-05            .
# [6,]    .    .         .            .            . 7.142857e-05
person Josh O'Brien    schedule 21.05.2014

Прежде всего, обязательно используйте 64-битную версию R и машину с большим объемом оперативной памяти.

Хотя инверсия матриц является вычислительно сложной операцией, требующей O(n^3) арифметических операций, она далеко не невозможна для n = 10000 и даже n = 16000. На моем не очень современном ПК я запускаю R с библиотекой Intel® Math Kernel Library (Revolution Р) Я наблюдаю следующее.

При n = 10000 он выполняется за 1,5 минуты и использует 3,2 ГБ оперативной памяти:

system.time({
  z = solve(diag(1,10000,10000))
});

  user  system elapsed 
341.89    0.63   87.22 

Для n = 16000 он завершается за 6 минут и использует 8 ГБ ОЗУ.

system.time({
  z = solve(diag(1,16000,16000))
});

   user  system elapsed 
1388.80    2.34  353.95
person Andrey Shabalin    schedule 22.05.2014

Это базовая алгебра: если ваша матрица X действительно диагональна, обратная матрица Y — это диагональная матрица, диагональными элементами которой являются Y_{i,i} = 1/X_{i,i}.

Так что просто сделайте:

x = diag(rnorm(14E3))
inv = diag(1/diag(x))
person catastrophic-failure    schedule 14.09.2016