Issue
I have a function that takes this form:
def signal_prototype(t, A, f, p):
return A*np.sin(2*np.pi*f*t+p)
I would like to vectorize this so that I can use the function as follows.
signal_A = SOME_VECTORIZE_FUNCTION(signal_prototype, t=t, A=1, f=10000, p=0)
signal_B = SOME_VECTORIZE_FUNCTION(signal_prototype, t=t, A=1, f=10000, p=np.pi/4)
signal_C = SOME_VECTORIZE_FUNCTION(signal_prototype, t=t, A=1, f=10000, p=np.pi/2)
signal_D = SOME_VECTORIZE_FUNCTION(signal_prototype, t=t, A=1, f=10000, p=3*np.pi/4)
t = np.linspace(0,1e-3,100000)
X1 = signal_A(t)
X2 = signal_B(t)
X3 = signal_C(t)
X4 = signal_D(t)
Thank you!
I tried using np.vectorize
and reading the documentation. There does not appear to be any way to send in static arguments to vectorize.
However, vectorize might not be the best tool for this.
I have a complicated set of differential equations that these signals are an input for. So, I need the functions in the form f(t,x).
The new signal functions are created dynamically as conditions in the model change. So, creating a static version of each equation is not a good option.
Solution
np.sin()
is already vectorized in that it will work on an array
>>> np.sin(np.array([1,2,3]))
array([0.84147098, 0.90929743, 0.14112001])
You can directly call your functions instead
def signal_prototype(t, A, f, p):
return A*np.sin(2*np.pi*f*t+p)
t = np.linspace(0,1e-3,100000)
X1 = signal_prototype(t=t, A=1, f=10000, p=0)
X2 = signal_prototype(t=t, A=1, f=10000, p=np.pi/4)
X3 = signal_prototype(t=t, A=1, f=10000, p=np.pi/2)
X4 = signal_prototype(t=t, A=1, f=10000, p=3*np.pi/4)
If you want to create a single function for each, you could use lambda
or functools.partial
as suggested
signal_A = lambda t: signal_prototype(t=t, A=1, f=10000, p=0)
signal_B = lambda t: signal_prototype(t=t, A=1, f=10000, p=np.pi/4)
signal_C = lambda t: signal_prototype(t=t, A=1, f=10000, p=np.pi/2)
signal_D = lambda t: signal_prototype(t=t, A=1, f=10000, p=3*np.pi/4)
X1 = signal_A(t)
X2 = signal_B(t)
X3 = signal_C(t)
X4 = signal_D(t)
Or just return the partial function yourself (effectively the same as lambda
)
def wrapper(func, **kwargs):
def wrapped(t):
return func(t, **kwargs)
return wrapped
signal_A = wrapper(signal_prototype, A=1, f=10000, p=0)
signal_B = wrapper(signal_prototype, A=1, f=10000, p=np.pi/4)
signal_C = wrapper(signal_prototype, A=1, f=10000, p=np.pi/2)
signal_D = wrapper(signal_prototype, A=1, f=10000, p=3*np.pi/4)
You can extend this if you want to pass a default t
or make it optinonal, though I can't advise doing so and just have it to illustrate how powerful this is as it's never advisable to return things with different types (such as imo a function with a variable number of arguments)
do not do this
def wrapper(func, t=None, **kwargs):
if t is not None:
def wrapped(t=t):
return func(t, **kwargs)
else:
def wrapped(t):
return func(t, **kwargs)
return wrapped
>>> wrapper(signal_prototype, A=1, f=10000, p=0)(t)
array([ 0.00000000e+00, 6.28324773e-04, 1.25664930e-03, ...,
-1.25664930e-03, -6.28324773e-04, -2.44929360e-15])
>>> wrapper(signal_prototype, t=t, A=1, f=10000, p=0)()
array([ 0.00000000e+00, 6.28324773e-04, 1.25664930e-03, ...,
-1.25664930e-03, -6.28324773e-04, -2.44929360e-15])
Answered By - ti7
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.