I am writing a custom function that I want to have behaving as if it where a numpy-function, having the ability to take in an array, and perform the same operation on every element of the input list, and returning a list of same shape with all the results.
Luckily, there is a solution for this: numpy.vectorize()
So I used that: I have a function that creates a model in the form of a sine wave, and it takes in two variables: one numpy list X containing some input values for the sine function, and one numpy list param that contains the four possible parameters that a sine curve can have.
import numpy as np
def sine(X, param):
#Unpacking param
A = param[0]
P = param[1]
Phi = param[2]
B = param[3]
#translating variables
#Phi = t0/P
f = X/P
Y = A*np.sin(2*np.pi*(f + Phi)) + B
return Y
Because only the input values X need the broadcasting while the all the parameters are necessary all the time, so, according to the documentation, the way to vecorise the function is as follows:
np_sine = np.vectorize(sine, excluded=['param']) #makes sine() behave like a numpy function
...so that param is properly excluded from vectorisation.
This method is useful, since I will be fitting this model to a dataset, which requires occasionally tweaking the parameters, meanwhile, with this method the code where I need it is only one line long:
CHIsqrt = np.sum(((ydata - np_sine(xdata, param))/yerr)**2)
where ydata, xdata and yerr are equally long lists of datapoints and where param is the list of four parameters.
Yet, the result was a broadcasting error:
File "C:\Users\Anonymous\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\lib\function_base.py", line 2831, in _vectorize_call outputs = ufunc(*inputs)
ValueError: operands could not be broadcast together with shapes (500,) (4,)
Since the list param is 4 elements long, I get that the function ignored my commands to exclude it from vectorisation. That is a problem.
I tried specifying that the end result should be a ndArray, which did not change the error.
np_sine = np.vectorize(sine, excluded=['param'], otypes=[np.ndarray])
What would be the correct way to use this function?