0

I would like a faster implementation of the functions shown below. Ideally the code should work when number_points variable is set to 400-500. Is there any way I can improve the function definitions to increase speed (see sample run)?

Here is a sample run showing a slow execution

Here is my code:

import numpy as np
import time

def initialize_plane_points(Domain = 100,number_points=200,Plane_Offset=0.0):
    '''Domain has implied coordinates of mm and the number of 
    points represents the number of samples within that space.  '''
    X = np.linspace(-Domain,Domain,number_points)
    #print(X)
    Y = np.linspace(-Domain,Domain,number_points)
    #print(Y)
    ZZ = np.array([])
    XX,YY = np.meshgrid(X,Y)
    for x in XX:
        for y in YY:
            ZZ = np.append(ZZ,[Plane_Offset])
    ZZ = np.reshape(ZZ, (len(XX),len(YY)))
    
    Shape = np.array([])
    for i in range(len(XX)):
        for j in range(len(YY)):
            Shape = np.append(Shape,[XX[i,j],YY[i,j],ZZ[i,j]])
    a = int(len(Shape) / 3)
    SHAPE = np.reshape(Shape,(a,3))
    return SHAPE



T0 = time.perf_counter()
Points = initialize_plane_points(number_points=100)
T1 = time.perf_counter()
    
    print("100 initialize time: ",T1-T0)

Juan Carlos Ramirez
  • 2,054
  • 1
  • 7
  • 22
john
  • 57
  • 1
  • 7

2 Answers2

2

As a general rule, if you want efficient code with numpy you want as few loop iterations as possible.

np.append as also relatively slow. Instead, try to build your arrays with vectorial algebra. For instance, ZZ = np.ones((len(XX),len(YY)) * Plane_Offset will be a lot faster than the two nested loops you have.

asimoneau
  • 695
  • 7
  • 18
0

New Results for array generation The function was rewritten avoiding any explicit for loops. The difference in time is amazing. I would love to know how these functions are so efficient.

def initialize_plane_points_2(Domain = 100,number_points=200,Plane_Offset=0.0):
    X = np.linspace(-Domain,Domain,number_points)
    Y = np.linspace(-Domain,Domain,number_points)
    
    XX,YY = np.meshgrid(X,Y)
    ZZ = np.ones((len(XX),len(YY)))*Plane_Offset
    #print(ZZ.shape, XX.shape,YY.shape)
    
    Shape = np.dstack((XX,YY,ZZ)).reshape(-1,3)
    return Shape
john
  • 57
  • 1
  • 7
  • These functions are efficient because they are implemented in [a backend written in C](https://docs.scipy.org/doc/numpy-1.13.0/reference/internals.html), and Python just executes that. The backend uses [SIMD operations](https://stackoverflow.com/questions/44944367/are-numpys-basic-operations-vectorized-i-e-do-they-use-simd-operations) to perform the same operation on multiple data instead of iteratively loading each data to operate on. – Pranav Hosangadi Jul 21 '20 at 18:19