向量化具有输入和输出历史依赖性的操作的最佳方法?

时间:2016-11-01 18:35:36

标签: python numpy vectorization

我的目标是在numpy中对以下操作进行矢量化,

y[n] = c1*x[n] + c2*x[n-1] + c3*y[n-1]

如果n是时间,我基本上需要输出取决于先前的输入以及先前的输出。我得到了x[-1]y[-1]的值。此外,这是我的实际问题的一般化版本c1 = 1.001c2 = -1c3 = 1

我可以找出添加前两个操作数的过程,只需添加c1*xc2*np.concatenate([x[-1], x[0:-1]),但我似乎无法找出处理{{1}的最佳方法。 }。

2 个答案:

答案 0 :(得分:2)

可以使用IIR过滤器来执行此操作。在这种情况下,scipy.signal.lfilter是正确的选择。

对于我的特定常量,以下代码片段可以 -

  from scipy import signal
  inital = signal.lfiltic([1.001,-1], [1, -1], [y_0], [x_0])
  output, _ = signal.lfilter([1.001,-1], [1, -1], input, zi=inital)

此处,signal.lfiltic用于指定初始条件。

答案 1 :(得分:0)

只需使用cumsum

首先是一个迭代生成表达式的小函数:

def foo1(x,C):
    x=x.copy()
    for i in range(1,x.shape[0]-1):
        x[i]=np.dot(x[i-1:i+2],C)
    return x[1:-1]

制作一个小型测试数组(我首先使用np.arange(10)

In [227]: y=np.arange(1,11); np.random.shuffle(y)
# array([ 4,  9,  7,  8,  2,  6,  1,  5, 10,  3])

In [229]: foo1(y,[1,2,1])
Out[229]: array([ 29,  51,  69,  79,  92,  99, 119, 142])
In [230]: y[0] + np.cumsum(2*y[1:-1] + 1*y[2:])
Out[230]: array([ 29,  51,  69,  79,  92,  99, 119, 142], dtype=int32)

并使用不同的C

In [231]: foo1(y,[1,3,2])
Out[231]: array([ 45,  82, 110, 128, 148, 161, 196, 232])
In [232]: y[0]+np.cumsum(3*y[1:-1]+2*y[2:])
Out[232]: array([ 45,  82, 110, 128, 148, 161, 196, 232], dtype=int32)

我第一次尝试:

In [238]: x=np.arange(10)
In [239]: foo1(x,[1,2,1])
Out[239]: array([  4,  11,  21,  34,  50,  69,  91, 116])
In [240]: np.cumsum(x[:-2]+2*x[1:-1]+x[2:])
Out[240]: array([  4,  12,  24,  40,  60,  84, 112, 144], dtype=int32)

然后意识到不需要x[:-2]这个词:

In [241]: np.cumsum(2*x[1:-1]+x[2:])
Out[241]: array([  4,  11,  21,  34,  50,  69,  91, 116], dtype=int32)

如果我回到学校,我可能会发现这种代数模式,而不是一个numpy trial-n-error。这可能不够普遍,但希望它是一个开始。