我正在尝试找到以下随机过程的相关函数: 其中beta和D是常数,而xi(t)是高斯噪声项。
使用Euler方法模拟此过程后,我想找到此过程的自动相关函数。首先,我找到了相关函数的解析解决方案,并且已经使用相关函数的定义对其进行了仿真,并且两个结果非常接近(请参见照片,相应的代码在本文的结尾)。
(图1)
现在,我想使用Wiener-Khinchin定理(使用fft)通过实现的fft来找到相关函数,将其乘以其共轭,然后找到ifft来获得相关函数。但是显然我得到的结果与预期的相关函数相去甚远,所以我很确定代码中有些东西我被误解了,以获得错误的结果。
这是我用于解决随机过程的代码(尽管我的代码可能很草率,但我确信它是正确的),以及我尝试使用fft查找自相关的方法:
N = 1000000
dt=0.01
gamma = 1
D=1
v_data = []
v_factor = math.sqrt(2*D*dt)
v=1
for t in range(N):
F = random.gauss(0,1)
v = v - gamma*dt + v_factor*F
if v<0: ###boundary conditions.
v=-v
v_data.append(v)
def S(x,dt): ### power spectrum
N=len(x)
fft=np.fft.fft(x)
s=fft*np.conjugate(fft)
# n=N*np.ones(N)-np.arange(0,N) #divide res(m) by (N-m)
return s.real/(N)
c=np.fft.ifft(S(v_data,0.01)) ### correlation function
t=np.linspace(0,1000,len(c))
plt.plot(t,c.real,label='fft method')
plt.xlim(0,20)
plt.legend()
plt.show()
这是我使用定义的相关函数代码:
def c_theo(t,b,d): ##this was obtained by integrating the solution of the SDE
I1=((-t*d)+((d**2)/(b**2))-((1/4)*(b**2)*(t**2)))*special.erfc(b*t/(2*np.sqrt(d*t)))
I2=(((d/b)*(np.sqrt(d*t/np.pi)))+((1/2)*(b*t)*(np.sqrt(d*t/np.pi))))*np.exp(-((b**2)*t)/(4*d))
return I1+I2
## this is the correlation function that was plotted in the figure 1 using the definition of the autocorrelation.
Ntau = 500
sum2=np.zeros(Ntau)
c=np.zeros(Ntau)
v_mean=0
for i in range (0,N):
v_mean=v_mean+v_data[i]
v_mean=v_mean/N
for itau in range (0,Ntau):
for i in range (0,N-10*itau):
sum2[itau]=sum2[itau]+v_data[i]*v_data[itau*10+i]
sum2[itau]=sum2[itau]/(N-itau*10)
c[itau]=sum2[itau]-v_mean**2
t=np.arange(Ntau)*dt*10
plt.plot(t,c,label='numericaly')
plt.plot(t,c_theo(t,1,1),label='analyticaly')
plt.legend()
plt.show()
所以有人请指出我的代码中的错误在哪里,如何更好地模拟它以获得正确的相关函数?
答案 0 :(得分:1)
我看到的代码有两个问题。
与francis said in a comment一样,您需要从信号中减去平均值,以使自相关达到零。
您用错误的x轴值绘制了自相关函数。
v_data
定义为:
N = 1000000 % 1e6
dt = 0.01 % 1e-2
表示t
从0到1e4。但是:
t = np.linspace(0,1000,len(c))
表示您使用t
从0到1e3进行绘制。您可能应该使用{p>来定义t
t = np.arange(N) * dt
看看情节,我想说,将蓝线拉伸10倍会使它与红线很好地对齐。