Home > Back-end >  Program to sum multiple multidimensional arrays at the same time
Program to sum multiple multidimensional arrays at the same time

Time:09-07

I have 5 multidimensional arrays

A = [ [1,2,3,4,5,6]
      [3,4,5,6,7,8]
      [5,6,7,8,9,0] ]

B = [ [11,12,13,14,15,16]
      [21,22,23,24,25,26]
      [13,14,15,16,17,18] ]

C = [ [31,32,33,34,35,36]
      [12,13,14,15,16,17]
      [20,21,22,23,24,25] ]

D = [ [2,3,4,5,6,7]
      [3,4,5,6,7,8]
      [6,7,8,9,0,11] ]

Base = [ [11,22,33,44,55,66]
         [12,23,34,45,56,67]
         [33,44,55,66,77,88]
         [1,2,3,4,5,6] ]

So I want to multiply the array A, B, C, and D by the Base array. Which will produce output like the following

Output = [ [A[0]*Base[0]   B[0]*Base[1]   C[0]*Base[2]   D[0]*Base[3] ], (this is summed)

           [A[1]*Base[0]   B[1]*Base[1]   C[1]*Base[2]   D[1]*Base[3] ], (this is summed)

           [A[2]*Base[0]   B[2]*Base[1]   C[2]*Base[2]   D[2]*Base[3] ], (this is summed)

           [A[3]*Base[0]   B[3]*Base[1]   C[3]*Base[2]   D[3]*Base[3] ]  (this is summed)
         ]

what I've been trying to do is to use an algorithm like the following. Multiply them one by one,

Output 1 = A*Base[0]
Output 2 = B*Base[1]
Output 3 = C*Base[2]
Output 4 = D*Base[3]

then add them up one by one

Sum1 = sum(Output1[0])
Sum2 = sum[Output1[1])
Sum3 = sum(Output1[2])
Sum4 = sum(Output2[0])
Sum5 = sum(Output2[1])
...
...
...
...

So I get the output by adding them up : [Sum1 Sum4 .....], [Sum2 Sum5 ....]....

Is there a simpler and shorter way to do this, apart from multiplying them one by one?

Sorry I'm just learning to use python. Please help Thank you

CodePudding user response:

It's not very clear what operation result you want with multiplying arrays, but just use numpy to make your life easier.

A, B, C, D, Base = np.array(A), np.array(B), np.array(C), np.array(D), np.array(Base)

For instance, the following operation multiplies and sum A * Base resulting in 4 * 3 sum arrays:

[sum(list(base_list * A_list)) for base_list in Base for A_list in A]

[1001, 1463, 1265, 1022, 1496, 1300, 1463, 2189, 2035, 91, 133, 115]

Then just sum the results to obtain the full sum of A*Base in 1/2 lines (and do the same with the remaining ones)

sum([1001, 1463, 1265, 1022, 1496, 1300, 1463, 2189, 2035, 91, 133, 115])

13573

CodePudding user response:

numpy is really useful for this type of operation. Here a code snippet for what you want to do:

import numpy as np

A = [[1, 2, 3, 4, 5, 6],
     [3, 4, 5, 6, 7, 8],
     [5, 6, 7, 8, 9, 0]]

B = [[11, 12, 13, 14, 15, 16],
     [21, 22, 23, 24, 25, 26],
     [13, 14, 15, 16, 17, 18]]

C = [[31, 32, 33, 34, 35, 36],
     [12, 13, 14, 15, 16, 17],
     [20, 21, 22, 23, 24, 25]]

D = [[2, 3, 4, 5, 6, 7],
     [3, 4, 5, 6, 7, 8],
     [6, 7, 8, 9, 0, 11]]

Base = [
    [11, 22, 33, 44, 55, 66],
    [12, 23, 34, 45, 56, 67],
    [33, 44, 55, 66, 77, 88],
    [1, 2, 3, 4, 5, 6]
]

A = np.asarray(A)
B = np.asarray(B)
C = np.asarray(C)
D = np.asarray(D)
Base = np.asarray(Base)

Output = np.asarray([
    [A[0] * Base[0]   B[0] * Base[1]   C[0] * Base[2]   D[0] * Base[3]],
    [A[1] * Base[0]   B[1] * Base[1]   C[1] * Base[2]   D[1] * Base[3]],
    [A[2] * Base[0]   B[2] * Base[1]   C[2] * Base[2]   D[2] * Base[3]],
    # [A[3] * Base[0]   B[3] * Base[1]   C[3] * Base[2]   D[3] * Base[3]]  # IndexError: index 3 is out of bounds for axis 0 with size 3 -> the matrices A, B, C and D have only 3 rows
]).squeeze()

print(f"{A.shape = } {B.shape = } {C.shape = } {D.shape = } {Base.shape = }, {Output.shape = }")

# simple math
results_simple = A * Base[0]   B * Base[1]   C * Base[2]   D * Base[3]
print(f"{results_simple.shape = }")
print(f"{np.allclose(results_simple, Output) = }")

# result with more algebra
M = np.stack([A, B, C, D], axis=1)
print(f"{M.shape = }")
results_algebra = np.sum(M * Base, axis=1)
print(f"{results_algebra.shape = }")
print(f"{np.allclose(results_algebra, Output) = }")

# results with einsum
results_einsum = np.einsum("ijk,jk->ik", M, Base)
print(f"{results_einsum.shape = }")
print(f"{np.allclose(results_einsum, Output) = }")

out:

A.shape = (3, 6) B.shape = (3, 6) C.shape = (3, 6) D.shape = (3, 6) Base.shape = (4, 6), Output.shape = (3, 6)
results_simple.shape = (3, 6)
np.allclose(results_simple, Output) = True
M.shape = (3, 4, 6)
results_algebra.shape = (3, 6)
np.allclose(results_algebra, Output) = True
results_einsum.shape = (3, 6)
np.allclose(results_einsum, Output) = True

After this, you can get the sum of the output in a certain axis using the function numpy.sum. You will have something like this:

out_sum = np.sum(Output, axis=-1)
  • Related