The general problem I'm facing could be translated as follows:
Code a NxN matrix in which mxm sub-matrices of values x or y are regularly alternated.
For example, let's say I need to make a 6x6 matrix with 2x2 sub-matrices of 0 or 1 are alternated, the result should be the matrix below:
0 0 1 1 0 0
0 0 1 1 0 0
1 1 0 0 1 1
1 1 0 0 1 1
0 0 1 1 0 0
0 0 1 1 0 0
For now, I only managed to get this:
0 0 1 0 0 0
0 0 1 0 0 0
1 1 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
with the code :
b = numpy.zeros((6, 6))
b[:2, 2:6:4] = 1
b[2:6:4, :2] = 1
print(b)
I managed to find a solution but it has four for-loop so it is hard to read and takes a bit of time. The code for this possible answer is:
c = np.array([])
for k in range(3):
for l in range (2):
for i in range(3):
for j in range (2):
if (k i)%2 == 0:
c = np.append(c, 0)
else:
c = np.append(c, 1)
print("c = ", np.reshape(c, (6, 6)))
Isn't there a better way to give the expected output without using loops or with 1 or 2 loops max ?
CodePudding user response:
import numpy as np
m = 8
n = 4
c = np.zeros(shape=(m,m))
assert not m%n #m must be divisible by n
for row_i in range(m):
for col_i in range(m):
if (row_i//n col_i//n)%2:
c[row_i][col_i] = 1
print(c)
[[0. 0. 0. 0. 1. 1. 1. 1.]
[0. 0. 0. 0. 1. 1. 1. 1.]
[0. 0. 0. 0. 1. 1. 1. 1.]
[0. 0. 0. 0. 1. 1. 1. 1.]
[1. 1. 1. 1. 0. 0. 0. 0.]
[1. 1. 1. 1. 0. 0. 0. 0.]
[1. 1. 1. 1. 0. 0. 0. 0.]
[1. 1. 1. 1. 0. 0. 0. 0.]]
CodePudding user response:
I think you're on the right track with using python array slicing. Here is an example for 2x2 submatrices (works with any even-square sized matrix b).
# first block for submatrices starting at column and row index 0
# 0::4 - every 4th column/row starting from column 0
# so this results in 1 0 0 0 1 0 and so on
b[0::4, 0::4] = 1
# 1::4 - every 4th column starting from column 1
# so this results in 0 1 0 0 0 1 and so on
b[0::4, 1::4] = 1
b[1::4, 0::4] = 1
b[1::4, 1::4] = 1
# second block for submatrices starting from column and row index 2
b[2::4, 2::4] = 1
b[2::4, 3::4] = 1
b[3::4, 2::4] = 1
b[3::4, 3::4] = 1
Now for larger submatrices you have just to increase the distance between the entries. For submatrices of size n
, the distance must be 2 * n
, because that is the sheme for the repetition of 1
in the matrix. Each block then has size n
. Try to write a procedure. If you do not succeed I will help further.
CodePudding user response:
I cut down your for-loop to 2:
def create_mxm_from_NxN(N,m):
"""N has to be divisible by m"""
b = np.zeros((N,N))
skip = N // m
for i in range(0,N 1,m):
for s in range(1,skip 1,2):
b[i:i m, i s*m:i (s 1)*m] = 1
b[i s*m:i (s 1)*m, i:i m] = 1
return b.astype(int)
Output:
create_mxm_from_NxN(6,2)
[[0 0 1 1 0 0]
[0 0 1 1 0 0]
[1 1 0 0 1 1]
[1 1 0 0 1 1]
[0 0 1 1 0 0]
[0 0 1 1 0 0]]
create_mxm_from_NxN(9,3)
[[0 0 0 1 1 1 0 0 0]
[0 0 0 1 1 1 0 0 0]
[0 0 0 1 1 1 0 0 0]
[1 1 1 0 0 0 1 1 1]
[1 1 1 0 0 0 1 1 1]
[1 1 1 0 0 0 1 1 1]
[0 0 0 1 1 1 0 0 0]
[0 0 0 1 1 1 0 0 0]
[0 0 0 1 1 1 0 0 0]]