2012-02-01 18 views
5

Say I tienen la siguiente matriz MAT, que es una matriz indicador binario:Matrix con pares diagonales de de 1

estera < -matrix (c (1, 1, 0, 0, 0, 0, 0 , 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1), byrow = T, nrow = 3)

> 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 

Esta matriz tiene sólo 3 filas. Necesito crear uno con 10000 filas, con el mismo patrón de pares de 1 en las diagonales. P. ej. durante 5 filas, espero una matriz de 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 

¿Alguien sabe una forma sencilla de hacer eso? Muchas gracias

+0

es decir, tomar la matriz de identidad y duplicar cada columna – smci

Respuesta

1

Cuando no proporciona suficientes elementos para llenar la matriz, se reciclan: si proporciona dos unos y n ceros (la primera fila y los primeros dos elementos de la segunda fila), obtendrá la matriz deseada

n <- 5 
matrix( 
    c(1,1,rep(0,2*n)), 
    byrow=TRUE, nr=n, nc=2*n 
) 
+0

Muchas gracias por su respuesta rápida. Mi pregunta estaba mal definida. Lo edité Mejor/Fan – user1182757

+0

@ user1182757: He editado mi respuesta para que coincida con su pregunta. –

+0

¡Agradable! Muchas gracias :) – user1182757

4

Ésta es una matriz dispersa, y, como tal, que va a hacer mucho mejor hacer referencia a las entradas distintas de cero: esto le ahorrará memoria RAM y hacer que sea más fácil para generar automáticamente la matriz.

Cada entrada está indexada como (i, j, x), haciendo referencia a la fila, columna y valor. Supongamos que tiene N (digamos N = 10) filas que desea llenar, entonces está produciendo 2 entradas por fila (indexadas por i, en el código a continuación); cada columna se usa solo una vez, por lo que hay 2 * N valores de columna únicos. Cada entrada no cero es 1.

El código para la producción de esto es:

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

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

La matriz resultante es:

> 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 

sólo tiene que utilizar el código anterior y conjunto N = 10.000, y Tendrás tu matriz.

Como una ventaja adicional: su matriz deseada (N = 1E5) consume solo 321424 bytes. Por el contrario, una matriz densa estándar de tamaño 10K x 20K tendrá 1,6 GB, usando entradas numéricas (es decir, 8 bytes). Como dijeron en "Contacto": eso parece una terrible pérdida de espacio, ¿verdad?

1

A menos que tenga la intención de completar muchos otros valores en la matriz, probablemente desee la escasa solución de matriz de Iterator. Dicho esto, aquí está una manera linda de generar una versión no escasa de la matriz:

double_diag <- function(n) 
{ 
    matrix(rep(diag(n), each = 2), byrow = TRUE, nrow = n) 
} 
double_diag(5) 
+0

+1 ¡Realmente agradable! – Tommy

1

@VincentZooneKynd tiene una buena solución, pero le da una advertencia. Aquí hay una variante que evita la advertencia:

n <- 5 
matrix(rep(c(1,1,rep(0,2*n)), len=2*n*n), n, byrow=TRUE) 
0

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