给定它们的协方差矩阵(它们的功率谱密度(PSD)和交叉功率谱密度(CSD)),我很难生成一组固定的彩色时间序列。
我知道,给定两个时间序列和,我可以使用许多广泛使用的例程来估算其功率谱密度(PSD)和交叉谱密度(CSD)。和Matlab等中的功能。PSD和CSD组成协方差矩阵:
psd()
csd()
如果我想做相反的事情怎么办? 给定协方差矩阵,如何生成和y_ {J}(t)的实现?
请包括任何背景理论,或指出执行此操作的任何现有工具(Python中的任何工具都很好)。
我的尝试
以下是我尝试过的内容以及我注意到的问题的描述。本书读了很长一段时间,如果其中包含误用的术语,则抱歉。如果可以指出错误的地方,那将非常有帮助。但是我的问题是上面的粗体字。
- PSD和CSD可以写为时间序列傅立叶变换的乘积的期望值(或整体平均值)。因此,协方差矩阵可以表示为:
其中
- 协方差矩阵是Hermitian矩阵,其实特征值可以为零或为正。因此,可以将其分解为
其中是一个对角矩阵,其非零元素是特征值的平方根;是矩阵,其列是的正交特征向量;是单位矩阵。
- 单位矩阵写为
其中
和是不相关且复杂的频率序列,均值和单位方差为零。
- 通过在2中使用3.,然后与1比较。时间序列的傅立叶变换为:
- 然后可以通过使用诸如快速傅立叶逆变换之类的例程来获得时间序列。
我已经用Python编写了一个例程来做到这一点:
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
我已将此例程应用于PSD和CSD,其解析表达式是从我正在使用的某些检测器的建模中获得的。重要的是,它们在所有频率上都构成一个协方差矩阵(至少它们if
在例程中传递了所有这些语句)。协方差矩阵为3x3。这三个时间序列已生成约9000次,下面将所有这些实现的平均PSD和CSD估计值与分析性实现一起绘制。虽然总体形状一致,但在CSD中的某些频率上存在明显的噪声特征(图2)。在PSD的峰附近进行了特写(图3)之后,我注意到PSD的确被低估了,并且CSD中的噪声特征出现的频率与PSD中的峰值几乎相同。我不认为这是一个巧合,而是电源从PSD泄漏到CSD中。通过数据的如此众多的实现,我本来可以期望这些曲线相互重叠。