Моделювання часових рядів заданих потужностей та перехресних спектральних густин


20

У мене виникають проблеми з генерацією набору стаціонарних кольорових часових рядів, враховуючи їх матрицю коваріації (їх спектральні щільності потужності (PSD) та спектральні щільності спектру потужності (CSD)).

Я знаю, що, враховуючи два часові ряди та , я можу оцінити їх спектральні щільності потужності (PSD) та перехресні спектральні щільності (CSD), використовуючи багато широко доступних підпрограм, таких як і функції в Matlab тощо. PSD і CSD складають матрицю коваріації: yI(t)yJ(t)psd()csd()

C(f)=(PII(f)PIJ(f)PJI(f)PJJ(f)),
що взагалі є функцією частоти . f

Що станеться, якщо я хочу зробити зворотний? З огляду на матрицю коваріації, як я можу генерувати реалізацію та ?yI(t)yJ(t)

Будь ласка, включіть будь-яку фонову теорію або вкажіть будь-які існуючі інструменти, які це роблять (все, що в Python було б чудово).

Моя спроба

Нижче описується те, що я спробував, і проблеми, які я помітив. Це трохи прочитане, і вибачте, якщо він містить терміни, які були неправильно використані. Якщо те, що є помилковим, можна вказати, це було б дуже корисно. Але моє питання - це жирним шрифтом вище

  1. PSD і CSD можуть бути записані як величина очікування (або середня кількість ансамблів) продуктів перетворень Фур'є часового ряду. Отже, матрицю коваріації можна записати у вигляді:
    C(f)=2τY(f)Y(f),
    де
    Y(f)=(y~I(f)y~J(f)).
  2. Коваріаційна матриця - це ермітова матриця, яка має реальні власні значення, що є або нульовими, або позитивними. Отже, його можна розкласти на де - діагональна матриця, ненульові елементи якої є квадратними коренями власних значень ; - матриця, стовпці якої є ортонормальними власними векторами ;
    C(f)=X(f)λ12(f)Iλ12(f)X(f),
    λ12(f)C(f)X(f)C(f)I - матриця ідентичності.
  3. Матриця ідентичності записується як де і - некорельовані та складні частотні ряди з нульовою середньою та одиничною дисперсією.
    I=z(f)z(f),
    z(f)=(zI(f)zJ(f)),
    {zi(f)}i=I,J
  4. Використовуючи 3. в 2., а потім порівняйте з 1. Перетвореннями Фур'є часового ряду є:
    Y(f)=τ2z(f)λ12(f)X(f).
  5. Тоді ряд може бути отриманий за допомогою таких процедур, як зворотне швидке перетворення Фур'є.

Я написав процедуру в 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твердження в рутину). Коваріаційна матриця дорівнює 3х3. Три часові серії були сформовані приблизно в 9000 разів, а розрахункові PSD та CSD, усереднені за всіма цими реалізаціями, наведені нижче з аналітичними. Незважаючи на те, що загальні форми узгоджуються, на певних частотах у CSD помітні шумні особливості (рис. 2). Після крупного плану навколо піків у PSD (рис.3) я помітив, що PSD насправді недооцінені, а також те, що шумні особливості в центральних дисках виникають приблизно на тих же частотах, що і піки в PSD. Я не думаю, що це збіг обставин, і що якимось чином витікає сила з PSD в ЦДД. Я б очікував, що криві лежать одна над одною, маючи це безліч реалізацій даних.

Малюнок 1: P11
Малюнок 2: P12 Малюнок 2: P11 (крупний план)


Ласкаво просимо на сайт. Я частково проголосував за це питання, щоб ви не мали змоги публікувати зображення. Якщо ні, просто опублікуйте посилання, і хтось із достатньою репутацією відредагує зображення, щоб вставити зображення.
кардинал

1
Ви спробували відфільтрувати високочастотний шум?
Карл

Відповіді:


1

Оскільки ваші сигнали стаціонарні, простим підходом буде використання білого шуму як основи та фільтрування його, щоб відповідати вашим PSD. Спосіб обчислення цих коефіцієнтів фільтра полягає у використанні лінійного прогнозування .

Здається, для цього є функція python, спробуйте:

from scikits.talkbox import lpc

Якщо ви хочете (я використовував лише еквівалент MATLAB). Це підхід, який використовується при обробці мови, де форманти оцінюються таким чином.


Ви не маєте на увазі застосувати фільтр до сигналу, а не до білого шуму?
Майкл Р. Черник

Ні, те, на що я прагну, - наблизити фільтр, де функція передачі нагадує PSD стаціонарного процесу. Якщо білий шум, який має однакову потужність у всіх діапазонах частот, фільтрується за допомогою них, вихід оптимальним чином нагадує вихідні сигнали за спектральною щільністю потужності.
Йонас Шварц

0

Трохи запізнююся на вечірку, як зазвичай, але я бачу деяку недавню активність, тож я буду свої дві єни.

По-перше, я не можу помилитися в спробі ОП - мені це здається правильним. Невідповідності можуть бути пов'язані з проблемами з кінцевими зразками, наприклад, позитивним зміщенням оцінки потужності сигналу.

Однак я думаю, що є більш прості способи генерування часових рядів з матриці перехресної спектральної щільності (CPSD, це те, що ОП називає коваріаційною матрицею).

Один параметричний підхід - використовувати CPSD для отримання авторегресивного опису, а потім використовувати його для створення часового ряду. У matlab ви можете це зробити за допомогою інструментів причинності Грейнджера (наприклад, Multivaraite Granger Causality Toolbox, Seth, Barnett ). Панель інструментів дуже проста у використанні. Оскільки існування CPSD гарантує автоматичний опис, такий підхід є точним. (для отримання додаткової інформації про CPSD та авторегресію див. "Вимірювання лінійної залежності та зворотного зв’язку між декількома часовими рядами" від Geweke, 1982, або багатьох документів Aneil Seth + Lionel Barnett, щоб отримати повне уявлення).

Потенційно простіше, зазначивши, що CPSD може бути сформований шляхом застосування fft до автоматичної коваріації (надання діагоналі CPSD, тобто потужності сигналів) та поперечної коваріації (надання відключених діагональних елементів, тобто поперечної потужності). Таким чином, застосовуючи зворотний fft до CPSD, ми можемо отримати автокореляцію та автоматичну коваріацію. Потім ми можемо використовувати їх для створення зразків наших даних.

Сподіваюсь, це допомагає. Будь ласка, залиште будь-які запити на інформацію у коментарях, і я спробую виступити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.