4

Calculate each matrix element

 3 years ago
source link: https://www.codesd.com/item/calculate-each-matrix-element.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Calculate each matrix element

advertisements

Here is what I have the formula I have to compute for each element of my Numpy matrices :

Mi_j = Sum_v(Av * Xi_v) + Sum_v(Bv * Wj_v) + Sum_v(Gv * Zij_v)

I don't really see how to code it in a numpy way (in python it's too long) : vectorized / slicing / C Api.

What would you suggest and can you give me a simple example ? I'm new to numpy.

@Edited indices

  • A, B, G are arrays of one dimension [x,x,x]
  • same for Xi and Wj (X is a Matrix, W is a Matrix)
  • Zij is an array of one dimension

Let's work through a simple example:

If we define:

import numpy as np
N = 5
A = np.arange(N)
X = np.arange(N*N).reshape(N,N)

B = np.arange(N)
W = np.arange(N*N).reshape(N,N)

G = np.arange(N)
Zij = np.arange(N)

Then the first sum, Sum_v(Av * Xi_v) can be computed with np.dot:

In [54]: X
Out[54]:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [55]: A
Out[55]: array([0, 1, 2, 3, 4])

In [56]: np.dot(X, A)
Out[56]: array([ 30,  80, 130, 180, 230])

Similarly, the second sum, Sum_v(Bv * Wj_v) can be computed as:

In [58]: np.dot(W,B)
Out[58]: array([ 30,  80, 130, 180, 230])

However, we want the first sum to result in a vector varying along the i-index, while we want the second sum to result in a vector varying along the j-index. To arrange that in numpy, use broadcasting:

In [59]: np.dot(X,A) + np.dot(W,B)[:,None]
Out[59]:
array([[ 60, 110, 160, 210, 260],
       [110, 160, 210, 260, 310],
       [160, 210, 260, 310, 360],
       [210, 260, 310, 360, 410],
       [260, 310, 360, 410, 460]])

The third sum is a simple dot product between two 1-dimensional arrays:

In [60]: np.dot(Zij, G)
Out[60]: 30

So putting it all together,

In [61]: M = np.dot(X,A) + np.dot(W,B)[:,None] + np.dot(Zij, G)

In [62]: M
Out[62]:
array([[ 90, 140, 190, 240, 290],
       [140, 190, 240, 290, 340],
       [190, 240, 290, 340, 390],
       [240, 290, 340, 390, 440],
       [290, 340, 390, 440, 490]])


Note I might have misunderstood the meaning of Zij. Although you say it is a 1-dimensional array, perhaps you meant that for each i,j it is a 1-dimensional array. Then Z would be 3-dimensional.

For the sake of concreteness, let's say the first two axes of Z represent the i and j-indices, and the last axis of Z is the one you wish to sum over.

In this case, you'd want the last term to be np.dot(Z, G):

In [13]: Z = np.arange(N**3).reshape(N,N,-1)

In [14]: np.dot(X,A) + np.dot(W,B)[:,None] + np.dot(Z, G)
Out[14]:
array([[  90,  190,  290,  390,  490],
       [ 390,  490,  590,  690,  790],
       [ 690,  790,  890,  990, 1090],
       [ 990, 1090, 1190, 1290, 1390],
       [1290, 1390, 1490, 1590, 1690]])




About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK