将具有多个输入的函数向量化以形成唯一的函数

问题描述 投票:0回答:2

我有一个采用这种形式的函数:

def signal_prototype(t, A, f, p):
    return A*np.sin(2*np.pi*f*t+p)

我想对其进行矢量化,以便我可以按如下方式使用该函数。

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)

谢谢!

我尝试使用

np.vectorize
并阅读文档。似乎没有任何方法可以将静态参数发送到矢量化。

但是,矢量化可能不是最好的工具。

我有一组复杂的微分方程,这些信号是它们的输入。所以,我需要 f(t,x) 形式的函数。

随着模型条件的变化动态创建新的信号函数。因此,创建每个方程的静态版本并不是一个好的选择。

python numpy vectorization
2个回答
0
投票

np.sin()
已经矢量化,因为它将在数组上工作

>>> np.sin(np.array([1,2,3]))
array([0.84147098, 0.90929743, 0.14112001])

您可以直接调用您的函数

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)

如果您想为每个函数创建一个函数,您可以按照建议使用

lambda
functools.partial

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)

或者自己返回部分函数(实际上与

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)

如果你想传递默认值

t
或使其成为可选的,你可以扩展它,尽管我不建议这样做,只是用它来说明它有多么强大,因为永远不建议返回不同类型的东西(例如作为一个具有可变数量参数的函数)

不要这样做

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])

0
投票

上面的答案确实帮助我弄清楚了我需要做什么。

X1 = partial(signal_prototype, A=1e-3, f=1e3, p=0)
X2 = partial(signal_prototype, A=1e-3, f=1e3, p=np.pi/4)
X3 = partial(signal_prototype, A=1e-3, f=1e3, p=np.pi/2)
X4 = partial(signal_prototype, A=1e-3, f=1e3, p=3*np.pi/4)

现在我有了可以像这样调用的函数。

X1(t)
X2(t)
etc...
© www.soinside.com 2019 - 2024. All rights reserved.