Construyendo una matriz especial en números dinámicamente.

Por lo tanto, mi objective es el siguiente, dado el tamaño de la matriz s , estoy intentando crear una matriz similar a la siguiente, pero para el tamaño sxs :

 [1 1 0] [1 1 1] [0 1 1] 

Para el tamaño de 4×4, se vería algo como lo siguiente:

 [1 1 0 0] [1 1 1 0] [0 1 1 1] [0 0 1 1] 

Por lo tanto, puede observar un patrón: hay s-1 número s-1 de matrices superpuestas mini 2x2 superpuestas.

Estaba pensando en crear una matriz de 2x2 y luego usar una referencia dinámica (¿para un bucle?) Como B[:-1,:-1] = ones_matrix , donde B es la matriz de ceros de tamaño sxs . Pero no estoy seguro de cómo incorporar un bucle for aquí, porque si tomamos, por ejemplo, una matriz 4x4 , tendríamos que hacer referencia a B de tres maneras: B[:-1,:-1] = ones_matrix, B[1:-1,1:-1] = ones_matrix, B[2:,2:]=ones_matrix . Y no puedo encontrar una manera de hacerlo dinámicamente para una matriz de ceros de tamaño n . ¿Hay tal vez otra forma de hacer esto?

Método # 1: en lugar de un grupo de matrices 2×2, podría ser más fácil verlo como tres diagonales de 1 y combinarlas:

 >>> s = 3 >>> np.diag([1]*s,0) + np.diag([1]*(s-1),-1) + np.diag([1]*(s-1), 1) array([[1, 1, 0], [1, 1, 1], [0, 1, 1]]) >>> s = 4 >>> np.diag([1]*s,0) + np.diag([1]*(s-1),-1) + np.diag([1]*(s-1), 1) array([[1, 1, 0, 0], [1, 1, 1, 0], [0, 1, 1, 1], [0, 0, 1, 1]]) 

Método # 2: (inspirado en la respuesta de Divankar), podemos pensar en términos de distancia desde el centro:

 >>> s = 4 >>> i,j = np.indices((s,s)) >>> (abs(ij) <= 1).astype(int) array([[1, 1, 0, 0], [1, 1, 1, 0], [0, 1, 1, 1], [0, 0, 1, 1]]) 

Método # 3: podríamos aprovechar tril o triu y hacer algo de aritmética:

 >>> m = np.tril(np.ones((s,s)),1) >>> m * mT array([[ 1., 1., 0., 0., 0.], [ 1., 1., 1., 0., 0.], [ 0., 1., 1., 1., 0.], [ 0., 0., 1., 1., 1.], [ 0., 0., 0., 1., 1.]]) >>> m = np.tril(np.ones((s,s)),2) >>> m * mT array([[ 1., 1., 1., 0., 0.], [ 1., 1., 1., 1., 0.], [ 1., 1., 1., 1., 1.], [ 0., 1., 1., 1., 1.], [ 0., 0., 1., 1., 1.]]) 

Enfoque vectorizado con broadcasting .

 A = np.arange(s) out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int) 

Ejecución de la muestra

 In [60]: s = 3 ...: A = np.arange(s) ...: out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int) ...: In [61]: out Out[61]: array([[1, 1, 0], [1, 1, 1], [0, 1, 1]]) In [62]: s = 4 ...: A = np.arange(s) ...: out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int) ...: In [63]: out Out[63]: array([[1, 1, 0, 0], [1, 1, 1, 0], [0, 1, 1, 1], [0, 0, 1, 1]]) 

Podrías usar sympy.Matrix también:

 from sympy import Matrix Matrix(4, 4, lambda i,j: 1 if (-2