I have the following code
a1 = 0.5
b0 = 3
ui_delta = np.arange(100000)
for i in range(1, ui_delta.shape[0]):
ui_delta[i] = b0 * ui_delta[i] a1 * ui_delta[i-1]
Would it be possible to generate this code using nditer or other instruction from numpy? I am trying to accelerate the code, is quite slow with the number of values I am working with. Thanks
CodePudding user response:
How about you use numba instead of numpy to speet things up.
@nb.njit
def calc():
a1 = 0.5
b0 = 3
ui_delta = np.arange(n)
for i in range(1, ui_delta.shape[0]):
ui_delta[i] = b0 * ui_delta[i] a1 * ui_delta[i-1]
return ui_delta
calc()
This takes ~88.1 ms with the @nb.njit and ~393 ms without it. So it's a more than 4 times speed up.
CodePudding user response:
The fastest and more Numpy-like way would be using array views.
If you look at the procedure from a perspective of the whole array, what you are trying to do is take the array except the first item and add it to itself but without the last item. Basically you sum your array with itself but with a 1-element shift.
Numpy provides a very handy feature called views, that allow having a reference or a view to a part of an array. This means, that changing the elements in the view will also change the original array.
a1 = 0.5
b0 = 3
ui_delta = np.arange(100000)
ui_delta1 = ui_delta[1:] # choosing all but the first element
ui_delta2 = ui_delta[:-1] # all but the last element
ui_delta1[:] = b0 * ui_delta1 a1 * ui_delta2
Using whole array operations not only simplifies code, but it is dramatically faster than iteration. Numpy has very efficient internal array loops that run extremely fast, because they are written in С under the hood. The bigger the array - the more significant is the efficiency gain.
Your code executes in roughly ~1 s The code above executes in just ~0.4 ms