如何计算添加白噪声的洛伦兹系统模拟的导数?

问题描述

我正在尝试计算添加白噪声的洛伦兹系统模拟的导数。例如,如果我想计算 x 数据 w.r.t. 的导数。时间 t。 我故意添加了一些噪音来检查导数计算器对实验数据的稳健性。所以,我不能使用诸如有限差分之类的数值导数技术。 我选择了具有更好条件多项式(例如切比雪夫多项式)的多项式回归来获得多项式方程,然后对其进行简单微分。 当然,对于这么复杂的曲线,我需要做多次局部多项式拟合,才能捕捉到曲线局部的剧烈变化。 但是,我从多项式回归中获得了非常高的导数值。请看一下 Python 代码。运行代码需要 5 分钟。

    import numpy as np   # matrix calc
import matplotlib.pyplot as plt
from methods import lorenz
from scipy.integrate import odeint  # scientific computation (ode solver)
import scipy.sparse as sparse

# %%  Initializing the chaotic Lorenz-system data
print('Initializing the chaotic Lorenz-system data')
sigma = 10
beta = 8/3
rho = 28
dt = 0.01
tspan = np.arange(0,50.01,dt,dtype=float)  # time span
x0 = np.array([-8,8,27])                 # initial conditions
x = odeint(lambda x,t: lorenz(x,t,sigma,beta,rho),x0,tspan,atol=1e-10,rtol=1e-10)
rows = np.shape(x)[0]
col = np.shape(x)[1]

# Visualizing the data
plt.figure(1)
plt.plot(tspan,x[:,0])

# %% True derivative using clean data
print('True derivative using clean data')
deriv = np.zeros((rows,col))
for i in range(1,rows):  # for each row
    deriv[i,:] = lorenz(x[i,:],rho)

# %% Tikhonov Differentiation (for clean data)
# returns argmin of (g) |Ag-f|_2^2 + Lambda*|Dg|_2^2
# d         nth derivative
# f         The data
# dx/dt    choose step length dx/ time step dt. For uniform grid only such as the rectangular grid
# Lambda   The hyperparameter or the trust over the regularization term


# Intializing paramters
print('Tikhonov Differentiation (for clean data)')
Lambda = 0.025  # threshold
# Addition and subtraction won't affect the derivative/slope but simplify the computation
f = np.array(x-x[0])
g = np.zeros((rows,col):  # for each columns
    A = np.zeros((rows,rows))
    for j in range(1,rows):
        A[j,j] = dt/2     # for diagonal elements
        A[j,0] = dt/2     # For first column only
        for k in range(1,j):
            A[j,k] = dt
            # Since k<=j,=> A is a lower triangular matrix

    e = np.ones(rows-1)
    D = sparse.diags([e,-e],[1,0],shape=(rows-1,rows)).todense()/dt
    # Invert to compute the derivative
    g[:,i] = np.linalg.lstsq(A.T.dot(A)+Lambda*D.T.dot(D),A.T.dot(x[:,i]),rcond=None)[0]

# %% polynomial differentiation at data
# u         The data near the point
# x         variable with respect to which the differentiation is to be done
# deg       degree of polynomial to use
# diff      maximum order of derivative we want
# width     number of data points neighbouring to the data point of interest
# Since the derivatives in dynamical systems are really complex in nature,therefore choosing the whole
# data for polynomial derivative might not capture the real derivative,therefore a series of 
# polynomial derivatives are taken with their 5 neighbouring data points 
# to capture the local gradient/ slope.
print('polynomial differentiation at data')
rows = np.shape(x)[0]
#index = int((rows-1)/2)  # where you want to compute your derivative
deg = 3
diff = 1
width = 100 # determined on the basis of true data
# fit to a Chebyshev polynomial as they are better conditioned than normal polynomials
# so small purturbation in the coefficients won't result in drastic change of the solution

# Making width array
width_array=np.arange(0,rows,width)
derivatives=np.zeros((rows,3))
# Here,width_array contains index of the input,such that index and index+1 accommodates exactly width number of data points
# inside the loop width_index is used to loop over each element of the width_array
# so 
#np.shape(width_array)[0]-1 otherwise upper_bound would exceed the array size
for width_index in range(0,np.shape(width_array)[0]-1):
    #lower_bound=x[width_array[width_index]][0]
    #upper_bound=x[width_array[width_index+1]][0]
    lower_bound=width_array[width_index]
    upper_bound=width_array[width_index+1]
    # here lower_bound and upper_bound gives the index of input data in between which width number of datapoint lies

    u = np.transpose(x[lower_bound:upper_bound,0])
    time= np.transpose(tspan[lower_bound:upper_bound])
    poly = np.polynomial.chebyshev.Chebyshev.fit(time,u,deg)

    # Take derivative
    derivatives_window = np.zeros((width))

    for l in range(0,width-1): # for each data point in the current window
        for d in range(1,diff+1):  # diff+1 is used so that d goes to diff
            derivatives_window[l] = (poly.deriv(m=d)(u[l])) # consecutive differentiation
    derivatives[lower_bound:upper_bound,0]=derivatives_window


# %% Plotting
print('Plotting')
plt.figure(2)
#for i in range(0,col):plt.plot(tspan,deriv[:,i])
plt.plot(tspan,"black",g[:,'blue',derivatives[:,"green")
plt.legend(['True','Tikhonov','polynomial'])

# Conclusion: Here we can't fit 1 curve as 1 curve can't capture the complex shape of the dynamics.

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...