Матрица с диагональными парами 1-х - PullRequest
5 голосов
/ 01 февраля 2012

Скажем, у меня есть следующий матричный мат, который является матрицей двоичного индикатора:

mat <-матрица (c (1, 1, 0, 0, 0, 0, 0, 0,1, 1, 0, 0, 0, 0, 0, 0, 1, 1), byrow = T, nrow = 3) </p>

> mat
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1    0    0    0    0
[2,]    0    0    1    1    0    0
[3,]    0    0    0    0    1    1

В этой матрице всего 3 строки.Мне нужно создать один с 10000 строк, с одинаковым рисунком пар 1 по диагонали.Например, для 5 строк я предполагаю матрицу 5 x 10:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    0    0    0    0    0    0    0     0
[2,]    0    0    1    1    0    0    0    0    0     0
[3,]    0    0    0    0    1    1    0    0    0     0
[4,]    0    0    0    0    0    0    1    1    0     0
[5,]    0    0    0    0    0    0    0    0    1     1

Кто-нибудь знает простой способ сделать это?Большое спасибо

Ответы [ 5 ]

4 голосов
/ 01 февраля 2012

Это разреженная матрица, и, как таковая, вы будете гораздо лучше ссылаться на ненулевые записи: это сэкономит вам ОЗУ и упростит автоматическое создание матрицы.

Каждая записьиндексируется как (i, j, x), ссылаясь на строку, столбец и значение.Предположим, что у вас есть N (скажем, N = 10) строк, которые вы хотите заполнить, тогда вы создаете 2 записи в строке (проиндексировано i, в коде ниже);каждый столбец используется только один раз, поэтому существует 2 * N уникальных значений столбца.Каждая ненулевая запись равна 1.

Код для ее создания:

N = 10
i = rep(1:N, each = 2)
j = 1:(2*N)
v = 1

library(Matrix)
mat = sparseMatrix(i = i, j = j, x = v)

Полученная матрица:

> mat
10 x 20 sparse Matrix of class "dgCMatrix"

 [1,] 1 1 . . . . . . . . . . . . . . . . . .
 [2,] . . 1 1 . . . . . . . . . . . . . . . .
 [3,] . . . . 1 1 . . . . . . . . . . . . . .
 [4,] . . . . . . 1 1 . . . . . . . . . . . .
 [5,] . . . . . . . . 1 1 . . . . . . . . . .
 [6,] . . . . . . . . . . 1 1 . . . . . . . .
 [7,] . . . . . . . . . . . . 1 1 . . . . . .
 [8,] . . . . . . . . . . . . . . 1 1 . . . .
 [9,] . . . . . . . . . . . . . . . . 1 1 . .
[10,] . . . . . . . . . . . . . . . . . . 1 1

Просто используйте код выше иустановите N = 10000, и у вас будет ваша матрица.

В качестве дополнительного бонуса: ваша желаемая матрица (N = 1E5) потребляет всего 321424 байта.Напротив, стандартная плотная матрица размером 10K x 20K займет 1,6 ГБ, используя числовые (т.е. 8-байтовые) записи.Как они сказали в «Контакте»: это похоже на ужасную трату пространства, верно?

1 голос
/ 01 февраля 2012

@ VincentZooneKynd имеет хорошее решение, но выдает предупреждение.Вот вариант, который избегает предупреждения:

n <- 5
matrix(rep(c(1,1,rep(0,2*n)), len=2*n*n), n, byrow=TRUE)
1 голос
/ 01 февраля 2012

Если вы не намереваетесь заполнить многие другие значения в матрице, вы, вероятно, захотите решение разреженной матрицы Итератора. Тем не менее, вот симпатичный способ создания не разреженной версии матрицы:

double_diag <- function(n)
{
  matrix(rep(diag(n), each = 2), byrow = TRUE, nrow = n)
}
double_diag(5)
1 голос
/ 01 февраля 2012

Если вы не предоставите достаточно элементов для заполнения матрицы, они будут переработаны: если вы предоставите два единицы и n нулей (первый ряд и первые два элемента второго ряда), вы получите желаемую матрицу.

n <- 5
matrix( 
  c(1,1,rep(0,2*n)), 
  byrow=TRUE, nr=n, nc=2*n 
)
0 голосов
/ 11 ноября 2017

Trickly:

> n <- 5
> t(model.matrix(~0+gl(n,2)))[,]
          1 2 3 4 5 6 7 8 9 10
gl(n, 2)1 1 1 0 0 0 0 0 0 0  0
gl(n, 2)2 0 0 1 1 0 0 0 0 0  0
gl(n, 2)3 0 0 0 0 1 1 0 0 0  0
gl(n, 2)4 0 0 0 0 0 0 1 1 0  0
gl(n, 2)5 0 0 0 0 0 0 0 0 1  1
...