用不带for循环的sin/cos填充矩阵的列



每当我编写for循环时,我都会问自己是否有更实用的方式来编写它。我没能想出一个for循环,用sin/cos填充矩阵的列。

k = 5 #this is any odd integer
t = np.arange(0,N)/fs #time array for the sin/cos
A = np.zeros((N,k))
A[:,0] = 1
for i in range(1, k, 2):
    A[:,i] = np.cos(2*np.pi*freq*t*(i+1)/2)
    A[:,i+1] = np.sin(2*np.pi*freq*t*(i+1)/2)

我使用numpy,因为这是用于更多的数学之后。我意识到替换for循环可能没有任何好处,因为它非常微不足道,但是有没有一种方法可以替换这个for循环?

您可以利用NumPy的向量化,而不是循环,使用索引数组,例如:

assert k & 1
odd = np.arange(1, k, 2)
even = odd + 1
A = np.zeros((N, k))
A[:, 0] = 1
A[:, odd] = np.cos(2 * np.pi * freq * t[:, None] * even / 2)
A[:, even] = np.sin(2 * np.pi * freq * t[:, None] * even / 2)

您可以使用tile并使用循环中使用的值构建A。然后你可以用这个矩阵试着同时做cos和sin的计算:

A = np.tile(np.arange(0, 5), (3,1))
A[:,0] = 1
A[:,1:] += 1

A是这样的:

array([[1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5]])

那么你也许可以对计算进行矢量化?

cos = np.cos(2*np.pi*freq*t*(A)/2)
sin = np.sin(2*np.pi*freq*t*(A)/2)

但是你仍然需要把它放回原来的矩阵中。你可以把even strides作为蒙版,用cos填充a。然后用奇怪的步伐作为面具,用罪恶填充。

不确定这是否有帮助(或者是否正确),只是另一种不使用循环的思考方式。

最新更新