0

suppose i have multiple 4x4 matrices which i want to add to a final 6x6 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 6x6 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)
Elta
  • 5
  • 2
  • 2
    Please post text. Don't use images, they stop knowledge propagation – Glauco Dec 22 '22 at 15:01
  • 1
    Show you r tedious code; best with examples that we can copy-n-paste. If there's rhyme or reason to the positions, you might be able reduce the tedium a bit. – hpaulj Dec 22 '22 at 16:54

3 Answers3

1

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.

mafedy
  • 58
  • 4
0

You will need to encode some way of where your 4x4 matrices end up in the final 6x6 matrix. Suppose you have N (=2 in your case) such 4x4 matrices. You can then define two new arrays (shape Nx4) that denote the row and col indices of the final 6x6 matrix that you want your 4x4 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.

Chrysophylaxs
  • 5,818
  • 3
  • 10
  • 21
  • thanks for your answer , as i am a bit of a beginner i wanted to ask why you used None in your indexing may be a silly question and also when you used the variable out i am not sure what exactly you're indexing. thanks very much for your help. – Elta Dec 23 '22 at 15:39
  • The answers to your questions are a bit complex to lay out in a comment here, but have a look at the numpy page of indexing ( https://numpy.org/doc/stable/user/basics.indexing.html ) and broadcasting ( https://numpy.org/doc/stable/user/basics.broadcasting.html ). In short, using `None` as index (or np.newaxis), will place a new dimension of size 1 in the array, which you can use to facilitate broadcasting. – Chrysophylaxs Dec 23 '22 at 16:24
0

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.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • i have updated it with my code i have the answer but it's just that it's a mathematical problem so sometimes the positions of the matrices will change i will be putting an if statement with the changing positions anyways, however i wanted to simplify the code – Elta Dec 23 '22 at 14:07