How to add a 4X4 matrix values into a 6×6 matrix using numpy

Question:

suppose i have multiple 4×4 matrices which i want to add to a final 6×6 zero matrix by adding some of the values in the designated coordination. how would i do this. I throughout of adding slices to np.zero 6×6 matrix , but i believe this may be quite tedious.

matrix 1 would go to this position first position and you have matrix 2 going to this position position 2. these two positions would be added and form the following final matrix Final position matrix

import numpy as np
from math import sqrt

#  Element 1
C_1= 3/5
S_1= 4/5
matrix_1 = np.matrix([[C_1**2, C_1*S_1,-C_1**2,-C_1*S_1],[C_1*S_1,S_1**2,-C_1*S_1,-S_1**2],
                    [-C_1**2,-C_1*S_1,C_1**2,C_1*S_1],[-C_1*S_1,-S_1**2,C_1*S_1,S_1**2]])
empty_mat1 = np.zeros((6,6))
empty_mat1[0:4 , 0:4] = empty_mat1[0:4 ,0:4] + matrix_1
#print(empty_mat1)
# Element 2

C_2 = 0
S_2 = 1
matrix_2 = 1.25*np.matrix([[C_2**2, C_2*S_2,-C_2**2,-C_2*S_2],[C_2*S_2,S_2**2,-C_2*S_2,-S_2**2],
                    [-C_2**2,-C_2*S_2,C_2**2,C_2*S_2],[-C_2*S_2,-S_2**2,C_2*S_2,S_2**2]])
empty_mat2 = np.zeros((6,6))
empty_mat2[0:2,0:2] = empty_mat2[0:2,0:2] + matrix_2[0:2,0:2]
empty_mat2[4:6,0:2] = empty_mat2[4:6,0:2] + matrix_2[2:4,0:2]
empty_mat2[0:2,4:6] = empty_mat2[0:2,4:6] + matrix_2[2:4,2:4]
empty_mat2[4:6,4:6] = empty_mat2[4:6,4:6] + matrix_2[0:2,0:2]

print(empty_mat1+empty_mat2)
Asked By: Elta

||

Answers:

Adding two arrays of differents dimensions is a little bit tricky with numpy.

However, with array comprehension, you could do it with the following "rustic" method :

Supposing M1 and M2 your 2 input arrays, M3 (from M1) and M4 (from M2) your temporary arrays and M5 the final array :

#Initalisation
M1 = np.array([[ 0.36,  0.48,  -0.36,  -0.48], [ 0.48,  0.64,  -0.48,  -0.64], [ -0.36, -0.48, 0.36, 0.48], [-0.48, -0.64, 0.48, 0.64]])
M2 = np.array([[ 0,  0,  0,  0], [ 0,  1.25,  0,  -1.25], [ 0,  0,  0,  0], [ 0,  -1.25,  0,  1.25]])
M3, M4 = np.zeros((6, 6)), np.zeros((6, 6))

#M3 and M4 operations
M3[0:4, 0:4] = M1[0:4, 0:4] + M3[0:4, 0:4]

M4[0:2, 0:2] = M2[0:2, 0:2]
M4[0:2, 4:6] = M2[0:2, 2:4]
M4[4:6, 0:2] = M2[2:4, 0:2]
M4[4:6, 4:6] = M2[2:4, 2:4]

#Final operation
M5 = M3+M4

print(M5)

Output :

[[ 0.36  0.48 -0.36 -0.48  0.    0.  ]
 [ 0.48  1.89 -0.48 -0.64  0.   -1.25]
 [-0.36 -0.48  0.36  0.48  0.    0.  ]
 [-0.48 -0.64  0.48  0.64  0.    0.  ]
 [ 0.    0.    0.    0.    0.    0.  ]
 [ 0.   -1.25  0.    0.    0.    1.25]]

Have a good day.

Answered By: mafedy

You will need to encode some way of where your 4×4 matrices end up in the final 6×6 matrix. Suppose you have N (=2 in your case) such 4×4 matrices. You can then define two new arrays (shape Nx4) that denote the row and col indices of the final 6×6 matrix that you want your 4×4 matrices to end up in. Finally, you use fancy indexing and broadcasting to build up a Nx6x6 array which you can sum over. Your example:

import numpy as np

N = 2
arr = np.array([[
    [0.36, 0.48, -0.36, -0.48],
    [0.48, 0.64, -0.48, -0.64],
    [-0.36, -0.48, 0.36, 0.48],
    [-0.48, -0.64, 0.48, 0.64],
], [
    [0, 0, 0, 0],
    [0, 1.25, 0, -1.25],
    [0, 0, 0, 0],
    [0, -1.25, 0, 1.25],
]])
rows = np.array([
    [0, 1, 2, 3],
    [0, 1, 4, 5]
])
cols = np.array([
    [0, 1, 2, 3],
    [0, 1, 4, 5]
])
i = np.arange(N)

out = np.zeros((N, 6, 6))
out[
    i[:, None, None],
    rows[:, :, None],
    cols[:, None, :]
] = arr
out = out.sum(axis=0)

Gives as output:

array([[ 0.36,  0.48, -0.36, -0.48,  0.  ,  0.  ],
       [ 0.48,  1.89, -0.48, -0.64,  0.  , -1.25],
       [-0.36, -0.48,  0.36,  0.48,  0.  ,  0.  ],
       [-0.48, -0.64,  0.48,  0.64,  0.  ,  0.  ],
       [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
       [ 0.  , -1.25,  0.  ,  0.  ,  0.  ,  1.25]])

If you want even more control over where each row/col ends up, you can pull off some more trickery as follows:

rows = np.array([
    [1, 2, 3, 4, 0, 0],
    [1, 2, 0, 0, 3, 4]
])
cols = np.array([
    [1, 2, 3, 4, 0, 0],
    [1, 2, 0, 0, 3, 4]
])
i = np.arange(N)

out = np.pad(arr, ((0, 0), (1, 0), (1, 0)))[
    i[:, None, None],
    rows[:, :, None],
    cols[:, None, :]
].sum(axis=0)

which has the same output. This would allow you to shuffle the rows/cols of arr by shuffling the values 1-4 in the rows, cols arrays. I would prefer option 1 though.

Answered By: Chrysophylaxs

I probably should wait for you to correct your question, but I’ll go ahead and give you some code – yes, in the most tedious form – based on your images

res = np.zeros((6,6))
# arr1, arr2 are (4,4) arrays
res[:4, :4] += arr1
idx = np.array([0,1,4,5])
res[idx[:,None], idx] += arr2

The first is contiguous block, so the 2 slices are enough.

The second is split up, so I’m using advanced indexing.

Answered By: hpaulj