Как вычислить спектральную плотность мощности векторного процесса, не отражая функцию автокорреляции?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как вычислить спектральную плотность мощности векторного процесса, не отражая функцию автокорреляции?

Сообщение Anonymous »

Я моделирую 2D-процесс Ornstein-Uhlenbeck (уравнение Langevin для скорости), и я заинтересован в вычислении спектральной плотности мощности (PSD) векторного процесса скорости. /> $$
r (\ tau) = \ frac {1} {t - \ tau} \ int_0^{t - \ tau} \ langle \ mathbf {v} (t) \ cdot \ mathbf {v} (t + \ tau) \ rangle, dt
$$ < /p>

Чтобы получить PSD. Однако, поскольку я только вычисляю VACF для положительных лагов $ \ tau \ geq 0 $, мне нужно отразить VACF вручную, чтобы сделать его симметричным, прежде чем применять np.fft.fft < /code>. < /P>
Этот шаг зеркального зеркала ощущается как обходной векторный процесс без необходимости явно клонировать VACF? Я рассчитываю VACF как средний точечный продукт с течением времени для всех траекторий, а затем отражает его для вычисления PSD через FFT. < /P>
1. Моделирование 2D траекторий Лангевина

Код: Выделить всё

import numpy as np
import matplotlib.pyplot as plt
import scipy.signal

np.random.seed(0)
n = 10_000      # Number of time steps
dt = .1         # Time step size (delta t)
dim = 2         # Dimension of the velocity vector (2D: x and y)
N = 10          # Ensemble size
gamma = 1       # Damping coefficient in Langevin equation
sigma = 1       # Noise intensity

dW = np.random.normal(scale=sigma * np.sqrt(dt), size=(n, dim, N)) # Gaussian noise
v = np.zeros((n, dim, N)) # Velocity - shape (time, dimension, trajectories)
r = np.zeros((n, dim, N)) # Position - shape (time, dimension, trajectories)

# Integrate the Langevin equation using the Euler-Maruyama method
for i in range(n - 1)
v[i + 1] = v[i] - gamma * v[i] * dt + dW[i]  # Update velocity: damping + noise
r[i + 1] = r[i] + v[i] * dt                  # Update position: Euler integration of velocity

< /code>
[b] 2. Вычисление VACF и PSD [/b] 
# Computes the VACF: ⟨v(t) · v(t + τ)⟩
def manual_vacf(v, lag):
vacf = []                           # VACF for the ensemble
for i in range(v.shape[-1]):        # Loop over trajectories
v_ = v[..., i]                  # Select trajectory i (shape: [time, dim])
vacf_ = np.empty(lag)           # VACF of current trajectory
for lag_ in range(1, lag + 1):  # Loop over lag values
v1, v2 = v_[:-lag_], v_[lag_:] # Vectors at t and t+lag
v1v2 = (v1 - v1.mean(axis=0)) * (v2 - v2.mean(axis=0)) # Remove mean and take element wise product
v1_dot_v2 = np.sum(v1v2, axis=1)      # Dot product v(t) · v(t + τ)
vacf_[lag_ - 1] = np.mean(v1_dot_v2)  # Time average
vacf.append(vacf_)
return np.mean(vacf, axis=0)  # Ensemble average

# Mirrors the VACF and computes the PSD using the Wiener–Khinchin theorem
def psd_wiener_khinchin(vacf, lag, dt):
vacf_mirror = np.hstack([np.flip(vacf), vacf])  # Extend VACF to negative lags
ft = np.fft.fft(vacf_mirror)[:lag]              # FFT and keep only non-negative frequencies
freq = np.fft.fftfreq(2 * lag, dt)[:lag]        # Frequency values
psd = np.abs(ft) * dt                           # PSD (magnitude × dt)
return psd, freq

# === vacf ===
lag_time = 4
lag = int(lag_time / dt)
tau = dt * np.arange(lag)
vacf_manual = manual_vacf(v, lag)
tau_theory = dt * np.arange(-lag, lag)
vacf_theory = theoretical_vacf(tau_theory, gamma, sigma)

# === psd ===
psd_manual, freq_manual = psd_wiener_khinchin(vacf_manual, lag, dt)
psd_theory = theoretical_psd(freq_manual, gamma, sigma)
< /code>
[b] 3. График [/b] 
fig, axs = plt.subplots(1, 3, figsize=(10, 2))

# first 3 simulated trajectories
for i in range(3):
axs[0].plot(*r[..., i].T)
axs[0].axis('equal')
axs[0].set_xlabel('x')
axs[0].set_ylabel('y')

# vacf
axs[1].plot(tau, vacf_manual)
axs[1].plot(tau_theory, vacf_theory)
axs[1].set_xlim(-lag_time, lag_time)
axs[1].set_xlabel('lag time')
axs[1].set_ylabel('VACF')

# psd
axs[2].plot(freq_manual, psd_manual, label='simulation')
axs[2].plot(freq_manual, psd_theory, label='theory')
axs[2].set_yscale('log')
axs[2].set_xscale('log')
axs[2].set_xlabel('frequency')
axs[2].set_ylabel('PSD')
axs[2].legend()

plt.show()


Подробнее здесь: https://stackoverflow.com/questions/796 ... ithout-mir
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»