Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NumPy - Vectorizing loops involving range iterators

Is there any way to make this work without for loops?

import import numpy as np
import matplotlib.pyplot as plt    

L = 1
N = 255
dh = 2*L/N
dh2 = dh*dh

phi_0 = 1
c = int(N/2)
r_0 = L/2

arr = np.empty((N, N))

for i in range(N):

    for j in range(N):

            arr[i, j] = phi_0 if (i - c)**2 + (j - c)**2 < r_0**2/dh2 else 0


plt.imshow(arr)

I've tried calling function(x[None,:], y[:, None]), where:

function(i, j):

    return phi_0 if (i - c)**2 + (j - c)**2 < r_0**2/dh2 else 0

but it requires list .any or .all methods. I'm looking for specifically functionless method (without fromfunction and vectorization). Big thanks!

like image 319
Serge Konstantinov Avatar asked Oct 08 '18 14:10

Serge Konstantinov


People also ask

Is numpy vectorize faster than for loop?

Vectorized implementations (numpy) are much faster and more efficient as compared to for-loops. To really see HOW large the difference is, let's try some simple operations used in most machine learnign algorithms (especially deep learning).

What does vectorize do in numpy?

Define a vectorized function which takes a nested sequence of objects or numpy arrays as inputs and returns a single numpy array or a tuple of numpy arrays. The vectorized function evaluates pyfunc over successive tuples of the input arrays like the python map function, except it uses the broadcasting rules of numpy.

Why is numpy vectorize fast?

You will often come across this assertion in the data science, machine learning, and Python community that Numpy is much faster due to its vectorized implementation and due to the fact that many of its core routines are written in C (based on CPython framework).

Does numpy use for loops?

Numpy for loop is used for iterating through numpy arrays of different dimensions, which is created using the python numpy library and using the for loop, multiple operations can be done going through each element in the array by one.


Video Answer


2 Answers

Vectorized solution using open grids

We could use two open range/grid arrays for N simulating the same behavior as the iterators -

I = np.arange(N)
mask = (I[:,None] - c)**2 + (I - c)**2 < r_0**2/dh2
out = np.where(mask,phi_0,0)

For a generic range on the two loops

For the generic case where we would iterate through two loops that extend till say M and N respectively, we could make use of np.ogrid to create those open grids and then use on the same lines -

I,J = np.ogrid[:M,:N]
mask = (I - c)**2 + (J - c)**2 < r_0**2/dh2

For a generic number of loops

For a generic number of loops, simply create as many variables as the number of loops. Hence, for three loops :

for i in range(M):
    for j in range(N):
        for k in range(P):

, we would have :

I,J,K = np.ogrid[:M,:N,:P]

, then use I,J,K instead of i,j,k respectively for element-wise operations like we have here.


Alternative to replace last step for this specific case

Last step could also be implemented with elementwise multiplication by scaling to phi_0 with mask as the else part is setting to 0s -

out = mask*phi_0
like image 180
Divakar Avatar answered Oct 01 '22 09:10

Divakar


If you want to use numbers of row and column to calculation, a loop is necessary. You can use one loop. Numpy has ndenumerate attribute that iterate over your matrix.

def function(i, j):
    return phi_0 if (i - c)**2 + (j - c)**2 < r_0**2/dh2 else 0

for (i,j), value in np.ndenumerate(arr):
    arr[i, j] = function(i, j)

enter image description here

like image 24
CezarySzulc Avatar answered Oct 01 '22 09:10

CezarySzulc