2015-09-04 37 views
3

每當我寫for循環時,我都會問自己是否沒有更實用的方法來編寫它。我沒有爲這個循環提供一些東西,用sin/cos填充矩陣的列。使用正弦/餘弦填充矩陣的列而不存在for循環

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循環可能沒有任何好處,因爲它非常簡單,但是有沒有辦法將這個替換爲循環?

+0

在Python中你可以使用一些函數式編程範式。但它主要不是一種功能性編程語言。以功能性方式重寫numpy代碼很少有意義。 – cel

回答

0

您可以使用平鋪並使用您在循環中使用的值構建出A。然後,你可以使用矩陣,並嘗試做COS和罪惡計算一次全部:

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

一則是這樣的:

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) 

但是,你仍然必須把它放回原始矩陣。你甚至可以把步伐作爲一個面具,並用cos填充A。然後以奇怪的步伐作爲面具並填充罪惡。

不知道這是否有幫助(或如果正確),只是另一種思路而不使用循環。

3

您可以利用與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)