Python (Numpy) Non-Elementwise Array Operations

In summary: Suppose that s is a vector with 5 elements (N = 5), and that x is a vector with 7 elements (M = 7). Here's a possible s vector: s = <1, 2, 3, 4, 5>. And here's a possible x vector: x = <2, 4, 6, 8, 10, 12, 14>.How do you see f1(x)... f5(x)?
  • #1
thegreenlaser
525
16
Python (numpy) question:

I have two 2D numpy arrays, A[i,j] and B[k,l], but the indexes are unrelated to each other (A and B won't even have the same dimensions in general). I want to be able to add/multiply these two together to get a 4D matrix: C[i,j,k,l] = A[i,j] + B[k,l] or C[i,j,k,l] = A[i,j]*B[k,l].

Obviously I can do this by looping through all four indices and running the statement "C[i,j,k,l] = A[i,j] + B[k,l]" or "C[i,j,k,l] = A[i,j]*B[k,l]" at each iteration of the loop, but is there an elegant way of doing this using a numpy function rather than loops? Some sort of addition function that adds an N-dimensional array to an M-dimensional array to give an (N+M)-dimensional array of all possible pairwise additions of elements? My loops are taking a while to run, and I'm hoping that using a "proper" numpy array manipulation function rather than loops would speed things up (and clean up my code a bit).
 
Technology news on Phys.org
  • #2
  • #3
AlephZero said:
See http://docs.scipy.org/doc/numpy/reference/generated/numpy.kron.html for the "multiply" operation.

I don't think the "add" corresponds to any standard mathematical operation on matrices or tensors, so it's unlikely there is a function to do it. (The "Kronecker sum" of two matrices is something different).

Thanks. It's kind of too bad there's no such operation...

However, I've at least realized that rather than looping through all four indices i, j, k and l, I can just loop through two (e.g. i and j) and then run the statement "C[i,j,:,:] = A[i,j] + B" or "C[i,j,:,:] = A[i,j]*B" each time. That at least cuts out a decent chunk of the loop iterations. In fact, in my case I was able to cut out almost all of the loop iterations since k and l have much larger ranges than i and j.
 
  • #4
Is there some reason you need to add matrices in the way you described? The reason that there isn't a function like what you're asking for is that the usual matrix operations of addition and multiplication are very limited in how they operate. Two matrices can be added only if they are both the same size - same number of rows and columns. Two matrices A and B can be multiplied only if the number of columns of A is the same as the number of rows of B.

Are you doing this just to do it, or do you have some reason to combine matrices in the way you described?
 
  • #5
Mark44 said:
Is there some reason you need to add matrices in the way you described? The reason that there isn't a function like what you're asking for is that the usual matrix operations of addition and multiplication are very limited in how they operate. Two matrices can be added only if they are both the same size - same number of rows and columns. Two matrices A and B can be multiplied only if the number of columns of A is the same as the number of rows of B.

Are you doing this just to do it, or do you have some reason to combine matrices in the way you described?

Here's a really simple example with 1D matrices of why I would want to do this. Say I have N different sources, and I'm trying to calculate a function corresponding to each source: fn(x) where

[tex] f_n(x) = x - s_n [/tex]

Now, in a program, the variable "x" would actually be a 1xM matrix of values, so fn(x) would actually be an NxM matrix with values f[n,m] = x[m] - s[n].

My situation is more complicated, but it's the same sort of thing. The indices i and j correspond to x and y positions and the indices k and l correspond to different sources and I'm calculating the field created by each source.
 
  • #6
thegreenlaser said:
Here's a really simple example with 1D matrices of why I would want to do this. Say I have N different sources, and I'm trying to calculate a function corresponding to each source: fn(x) where

[tex] f_n(x) = x - s_n [/tex]


Now, in a program, the variable "x" would actually be a 1xM matrix of values, so fn(x) would actually be an NxM matrix with values f[n,m] = x[m] - s[n].
The notation isn't helping any that I can see. An example of what you're trying to do might be more helpful.

Suppose that s is a vector with 5 elements (N = 5), and that x is a vector with 7 elements (M = 7).
Here's a possible s vector: s = <1, 2, 3, 4, 5>. And here's a possible x vector: x = <2, 4, 6, 8, 10, 12, 14>.

How do you see f1(x) being calculated? The subtraction you show doesn't make sense to me, because x and s are of different sizes.
thegreenlaser said:
My situation is more complicated, but it's the same sort of thing. The indices i and j correspond to x and y positions and the indices k and l correspond to different sources and I'm calculating the field created by each source.
 
  • #7
Mark44 said:
The notation isn't helping any that I can see. An example of what you're trying to do might be more helpful.

Suppose that s is a vector with 5 elements (N = 5), and that x is a vector with 7 elements (M = 7).
Here's a possible s vector: s = <1, 2, 3, 4, 5>. And here's a possible x vector: x = <2, 4, 6, 8, 10, 12, 14>.

How do you see f1(x) being calculated? The subtraction you show doesn't make sense to me, because x and s are of different sizes.

f1(x) = <1,3,5,7,9,11,13>

I don't think you're really understanding what I'm asking, so let me try a more concrete example. Say I have three charged particles located on the x-axis at s1 = -3, s2 = 0, and s3 = 5.

The electric field due to charge n at some position x will depend on the distance away from that source, which is given by x - sn, right? So En(x) would depend on the quantity (x - sn).

Now, I'm writing a program, and I want to find each En(x) at a bunch of points between x = -10 and x = +10 so that I can plot the electric field for each charge. So, in the program, I create an array of 5 points x = [-10, -5, 0, 5, 10] that I want to calculate each En field at.

In the end, I'll have a 3x5 array "E" of points, where E[n,m] is the field due to the nth source at position x[m]. To calculate that value, I need to calculate x[m] - s[n]. I'm subtracting the number s[n] (the position of the nth source) from the number x[m] (the position I'm calculating En at), and I'm doing that for each combination of n and m.

Maybe it'll be more clear: so E[n,:] is an array which corresponds to En(x) calculated at a bunch of different x values (since you can't use a continuous variable in programming, you have to pick an array of values to calculate the function at).

Hopefully that makes sense? If I'm solving this problem with pen and paper, there's no point where I'm adding/subtracting an N or M dimensional vectors. I think the term "array" is probably more helpful than the word "vector" in this context.
 
  • #8
This thread is kind of getting off track though... without worrying about why I need to do it, can we just trust that I do need to perform such a calculation? To get back on track... I'm looking for a numpy function that accomplishes the same thing as the following piece of code:

Code:
#A, B, and C are numpy arrays
#A is Ni by Nj
#B is Nk by Nl
#C is Ni by Nj by Nk by Nl

for i in range(Ni):
    for j in range(Nj):
        for k in range(Nk):
            for l in range(Nl):
                C[i,j,k,l] = A[i,j] + B[k,l]
 
  • #9
thegreenlaser said:
f1(x) = <1,3,5,7,9,11,13>
Based on this, what you're doing is picking one component of s and subtracting it from each component of x.

Here is some C code that would do this operation.
Code:
for (j = 0; j < M; j++)
{
   f(1) = x(j) - s(1);
}

Here is some code that would calculate all of the values in the f array.
Edit: Changed the code below to address a bug reported in post #12.
Code:
for (i = 0; i < N; i ++)
{
   for (j = 0; j < M; j++)
   {
      f(i, j) = x(j) - s(i);
   }
}

When the code above is done, you'll have a vector of function values <f1, f2, ..., fN>, where each component is calculated in the way that you calculated f1(x).
thegreenlaser said:
I don't think you're really understanding what I'm asking, so let me try a more concrete example.
Let's stay with the simpler example until I get a better understanding of what you're trying to do. Does the above do what you're trying to do?
thegreenlaser said:
Say I have three charged particles located on the x-axis at s1 = -3, s2 = 0, and s3 = 5.

The electric field due to charge n at some position x will depend on the distance away from that source, which is given by x - sn, right? So En(x) would depend on the quantity (x - sn).

Now, I'm writing a program, and I want to find each En(x) at a bunch of points between x = -10 and x = +10 so that I can plot the electric field for each charge. So, in the program, I create an array of 5 points x = [-10, -5, 0, 5, 10] that I want to calculate each En field at.

In the end, I'll have a 3x5 array "E" of points, where E[n,m] is the field due to the nth source at position x[m]. To calculate that value, I need to calculate x[m] - s[n]. I'm subtracting the number s[n] (the position of the nth source) from the number x[m] (the position I'm calculating En at), and I'm doing that for each combination of n and m.

Maybe it'll be more clear: so E[n,:] is an array which corresponds to En(x) calculated at a bunch of different x values (since you can't use a continuous variable in programming, you have to pick an array of values to calculate the function at).

Hopefully that makes sense? If I'm solving this problem with pen and paper, there's no point where I'm adding/subtracting an N or M dimensional vectors. I think the term "array" is probably more helpful than the word "vector" in this context.
"Vector" and "array" are pretty much synonomous when the array is one-dimensional.
 
Last edited:
  • #10
Mark44 said:
Here is some code that would calculate all of the values in the f array.
Edit: Changed the code below to address a bug reported in post #12.
Code:
for (i = 0; i < N; i ++)
{
   for (j = 0; j < M; j++)
   {
      f(i, j) = x(j) - s(i);
   }
}

Yes, exactly, this is basically what I have currently. See my last post; the python code in that post does exactly what I want it to do, it's just that numpy functions tend to run a lot faster than loops, which is why I'm looking for a numpy function to accomplish the same thing as that loop.
 
Last edited by a moderator:
  • #11
As AlephZero said early on in this thread, there's not much demand for what you're trying to do, so there's not likely to be a special function to do it.

If you want the code to run faster, write your code in a compiled language such as C or C++. My understanding is that python is interpreted, and interpreted languages inherently run much more slowly than compiled languages.
 
  • #12
Mark44 said:
Here is some code that would calculate all of the values in the f array.
Code:
for (i = 0; i < N; i ++)
   for (j = 0; j < M; j++)
   {
      f(i) = x(j) - s(i);
   }
}
There must be some misunderstanding, or a typo, there.
Do you really mean something like
Code:
      f(i) += x(j) - s(i);
or
Code:
      f(i,j) = x(j) - s(i);
Either way, the bottom line is you are calculating i*j values, so the only optimization you can make is to reduce the overhead of stepping through the loops, in an interpreted language.

You could change the first option to something like
Code:
f(i) = sum(x(:)) - N*s(i)
(assuming there is a built in math function called sum)
or change the second option to use array slices instead of the inner loop, something like
Code:
      f(i,:) = x(:) - s(i);
(note, I'm not a Python programmer so my syntax is probably wrong in those examples!)
 
  • #13
AlephZero, you're right. What I intended was this:
Code:
f(i,j) = x(j) - s(i);
When I made the transition from calculating f1(x) to calculating all of the f values, I failed to take that into account.

Here's the corrected version:
Code:
for (i = 0; i < N; i ++)
{
   for (j = 0; j < M; j++)
   {
      f(i, j) = x(j) - s(i);
   }
}
 
  • #14
Mark44 said:
If you want the code to run faster, write your code in a compiled language such as C or C++. My understanding is that python is interpreted, and interpreted languages inherently run much more slowly than compiled languages.

Yes, I'm aware of this. This is why I want to use a built-in numpy function rather than looping through the array. As I understand it, the built-in functions are pre-compiled rather than interpreted, which is why they tend to run much faster than the interpreted loops.

I guess the answer is just that there is no such function. I'll try to find another way to make my code run faster... I think it's possible using a package to write part of a python script in C so that it runs fast. I'll look into that.

Thanks for the help.
 
  • #15
Hi, just stumbled upon this. This can be implemented using outer product and reshaping commands in numpy:

Python:
import numpy as np
s, x = [1,2,3,4,5], [2,4,6,8,10,12,14]
N, M = len(s), len(x)
fp = np.repeat(x,N) -np.outer(np.ones([M,1]),s).flatten()
f = fp.reshape([N,M],order='F')
 

Related to Python (Numpy) Non-Elementwise Array Operations

What is the purpose of Non-Elementwise Array Operations in Python (Numpy)?

Non-Elementwise Array Operations in Python (Numpy) allow for efficient and fast computation on arrays without having to loop through each element individually. This is especially useful for large datasets and complex mathematical operations.

What are some common Non-Elementwise Array Operations available in Python (Numpy)?

Some common Non-Elementwise Array Operations in Python (Numpy) include array manipulation functions such as reshape, transpose, and concatenate, as well as mathematical functions like dot product, matrix multiplication, and trigonometric functions.

Can Non-Elementwise Array Operations be performed on arrays of different dimensions?

Yes, Non-Elementwise Array Operations can be performed on arrays of different dimensions by using broadcasting. Broadcasting allows for arrays of different sizes to be used in operations by replicating the smaller array to match the size of the larger array.

How do Non-Elementwise Array Operations differ from Elementwise Array Operations?

Non-Elementwise Array Operations perform operations on the entire array at once, while Elementwise Array Operations perform operations on each element individually. Non-Elementwise Operations are typically more efficient for complex mathematical operations on large datasets, while Elementwise Operations are useful for simple mathematical operations on small arrays.

Are there any drawbacks to using Non-Elementwise Array Operations in Python (Numpy)?

The main drawback of Non-Elementwise Array Operations is that they can lead to unexpected results if the arrays being operated on have different shapes. It is important to understand broadcasting rules and the dimensions of the arrays being used to avoid errors and incorrect results.

Similar threads

  • Programming and Computer Science
Replies
14
Views
767
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
1
Views
977
Replies
1
Views
1K
  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
Replies
8
Views
2K
  • Programming and Computer Science
Replies
15
Views
3K
  • Programming and Computer Science
Replies
34
Views
2K
  • Programming and Computer Science
Replies
4
Views
690
  • Programming and Computer Science
Replies
25
Views
2K
Back
Top