Tôi gặp khó khăn khi tạo ra một chuỗi các chuỗi thời gian có màu cố định, do ma trận hiệp phương sai của chúng (mật độ phổ công suất (PSD) và mật độ phổ công suất chéo (CSD)).
Tôi biết rằng, với hai chuỗi thời gian và , tôi có thể ước tính mật độ phổ công suất (PSD) và mật độ quang phổ chéo (CSD) bằng nhiều thói quen có sẵn rộng rãi, chẳng hạn như psd()
và các csd()
chức năng trong Matlab , v.v ... Các PSD và CSD tạo nên ma trận hiệp phương sai:
Điều gì xảy ra nếu tôi muốn làm ngược lại? Với ma trận hiệp phương sai, làm thế nào để tôi nhận ra và ?
Vui lòng bao gồm bất kỳ lý thuyết nền tảng nào, hoặc chỉ ra bất kỳ công cụ hiện có nào thực hiện điều này (mọi thứ trong Python đều tuyệt vời).
Nỗ lực của tôi
Dưới đây là một mô tả về những gì tôi đã cố gắng, và các vấn đề tôi đã nhận thấy. Đó là một chút của một đọc dài, và xin lỗi nếu nó có chứa các điều khoản đã bị sử dụng sai. Nếu những gì sai lầm có thể được chỉ ra, điều đó sẽ rất hữu ích. Nhưng câu hỏi của tôi là một trong những in đậm ở trên.
- Các PSD và CSD có thể được viết dưới dạng giá trị kỳ vọng (hoặc trung bình cộng) của các sản phẩm của các biến đổi Fourier của chuỗi thời gian. Vì vậy, ma trận hiệp phương sai có thể được viết là:
Nơi
- Ma trận hiệp phương sai là ma trận Hermiti, có giá trị riêng thực tế bằng 0 hoặc dương. Vì vậy, nó có thể được phân tách ra thành
trong đólà một ma trận đường chéo có các phần tử khác không là căn bậc hai củacác giá trị riêngcủa; là ma trận có các cột là các hàm riêng trực giao của; là ma trận danh tính.
- Ma trận sắc được viết như
trong đóVà là không tương quan và phức tạp tần số-series với zero đúng nghĩa và đơn vị.
- Bằng cách sử dụng 3. trong 2., và sau đó so sánh với 1. Fourier biến đổi của chuỗi thời gian là:
- Chuỗi thời gian sau đó có thể thu được bằng cách sử dụng các thường trình như biến đổi Fourier nhanh nghịch đảo.
Tôi đã viết một thói quen trong Python để làm điều này:
def get_noise_freq_domain_CovarMatrix( comatrix , df , inittime , parityN , seed='none' , N_previous_draws=0 ) :
"""
returns the noise time-series given their covariance matrix
INPUT:
comatrix --- covariance matrix, Nts x Nts x Nf numpy array
( Nts = number of time-series. Nf number of positive and non-Nyquist frequencies )
df --- frequency resolution
inittime --- initial time of the noise time-series
parityN --- is the length of the time-series 'Odd' or 'Even'
seed --- seed for the random number generator
N_previous_draws --- number of random number draws to discard first
OUPUT:
t --- time [s]
n --- noise time-series, Nts x N numpy array
"""
if len( comatrix.shape ) != 3 :
raise InputError , 'Input Covariance matrices must be a 3-D numpy array!'
if comatrix.shape[0] != comatrix.shape[1] :
raise InputError , 'Covariance matrix must be square at each frequency!'
Nts , Nf = comatrix.shape[0] , comatrix.shape[2]
if parityN == 'Odd' :
N = 2 * Nf + 1
elif parityN == 'Even' :
N = 2 * ( Nf + 1 )
else :
raise InputError , "parityN must be either 'Odd' or 'Even'!"
stime = 1 / ( N*df )
t = inittime + stime * np.arange( N )
if seed == 'none' :
print 'Not setting the seed for np.random.standard_normal()'
pass
elif seed == 'random' :
np.random.seed( None )
else :
np.random.seed( int( seed ) )
print N_previous_draws
np.random.standard_normal( N_previous_draws ) ;
zs = np.array( [ ( np.random.standard_normal((Nf,)) + 1j * np.random.standard_normal((Nf,)) ) / np.sqrt(2)
for i in range( Nts ) ] )
ntilde_p = np.zeros( ( Nts , Nf ) , dtype=complex )
for k in range( Nf ) :
C = comatrix[ :,:,k ]
if not np.allclose( C , np.conj( np.transpose( C ) ) ) :
print "Covariance matrix NOT Hermitian! Unphysical."
w , V = sp_linalg.eigh( C )
for m in range( w.shape[0] ) :
w[m] = np.real( w[m] )
if np.abs(w[m]) / np.max(w) < 1e-10 :
w[m] = 0
if w[m] < 0 :
print 'Negative eigenvalue! Simulating unpysical signal...'
ntilde_p[ :,k ] = np.conj( np.sqrt( N / (2*stime) ) * np.dot( V , np.dot( np.sqrt( np.diag( w ) ) , zs[ :,k ] ) ) )
zerofill = np.zeros( ( Nts , 1 ) )
if N % 2 == 0 :
ntilde = np.concatenate( ( zerofill , ntilde_p , zerofill , np.conj(np.fliplr(ntilde_p)) ) , axis = 1 )
else :
ntilde = np.concatenate( ( zerofill , ntilde_p , np.conj(np.fliplr(ntilde_p)) ) , axis = 1 )
n = np.real( sp.ifft( ntilde , axis = 1 ) )
return t , n
Tôi đã áp dụng thói quen này cho các PSD và CSD, các biểu thức phân tích được lấy từ mô hình của một số máy dò mà tôi đang làm việc. Điều quan trọng là ở tất cả các tần số, chúng tạo thành một ma trận hiệp phương sai (ít nhất là chúng vượt qua tất cả các if
câu lệnh trong thói quen). Ma trận hiệp phương sai là 3x3. Chuỗi 3 thời gian đã được tạo ra khoảng 9000 lần và các PSD và CSD ước tính, tính trung bình trên tất cả các nhận thức này được vẽ dưới đây với các phân tích. Mặc dù các hình dạng tổng thể đồng ý, có các tính năng nhiễu đáng chú ý ở các tần số nhất định trong CSDs (Hình 2). Sau khi chụp cận cảnh xung quanh các đỉnh trong PSD (Hình 3), tôi nhận thấy rằng các PSD thực sự bị đánh giá thấpvà các tính năng gây nhiễu trong CSD xảy ra ở cùng tần số với các đỉnh trong PSD. Tôi không nghĩ rằng đây là một sự trùng hợp ngẫu nhiên và bằng cách nào đó sức mạnh đang rò rỉ từ các PSD vào CSD. Tôi đã mong đợi các đường cong nằm trên nhau, với nhiều nhận thức về dữ liệu này.