Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
dynamicslab
GitHub Repository: dynamicslab/databook_python
Path: blob/master/CH07/CH07_SEC03_SINDY_Lorenz.ipynb
597 views
Kernel: Python 3
import numpy as np import matplotlib.pyplot as plt from matplotlib import rcParams from mpl_toolkits.mplot3d import Axes3D from scipy import integrate rcParams.update({'font.size': 18}) plt.rcParams['figure.figsize'] = [12, 12]
## Simulate the Lorenz System dt = 0.01 T = 50 t = np.arange(dt,T+dt,dt) beta = 8/3 sigma = 10 rho = 28 n = 3 def lorenz_deriv(x_y_z, t0, sigma=sigma, beta=beta, rho=rho): x, y, z = x_y_z return [sigma * (y - x), x * (rho - z) - y, x * y - beta * z] np.random.seed(123) x0 = (-8,8,27) x = integrate.odeint(lorenz_deriv, x0, t,rtol=10**(-12),atol=10**(-12)*np.ones_like(x0))
## Compute Derivative dx = np.zeros_like(x) for j in range(len(t)): dx[j,:] = lorenz_deriv(x[j,:],0,sigma,beta,rho)
## SINDy Function Definitions def poolData(yin,nVars,polyorder): n = yin.shape[0] yout = np.zeros((n,1)) # poly order 0 yout[:,0] = np.ones(n) # poly order 1 for i in range(nVars): yout = np.append(yout,yin[:,i].reshape((yin.shape[0],1)),axis=1) # poly order 2 if polyorder >= 2: for i in range(nVars): for j in range(i,nVars): yout = np.append(yout,(yin[:,i]*yin[:,j]).reshape((yin.shape[0],1)),axis=1) # poly order 3 if polyorder >= 3: for i in range(nVars): for j in range(i,nVars): for k in range(j,nVars): yout = np.append(yout,(yin[:,i]*yin[:,j]*yin[:,k]).reshape((yin.shape[0],1)),axis=1) return yout def sparsifyDynamics(Theta,dXdt,lamb,n): Xi = np.linalg.lstsq(Theta,dXdt,rcond=None)[0] # Initial guess: Least-squares for k in range(10): smallinds = np.abs(Xi) < lamb # Find small coefficients Xi[smallinds] = 0 # and threshold for ind in range(n): # n is state dimension biginds = smallinds[:,ind] == 0 # Regress dynamics onto remaining terms to find sparse Xi Xi[biginds,ind] = np.linalg.lstsq(Theta[:,biginds],dXdt[:,ind],rcond=None)[0] return Xi
Theta = poolData(x,n,3) # Up to third order polynomials lamb = 0.025 # sparsification knob lambda Xi = sparsifyDynamics(Theta,dx,lamb,n) print(Xi)
[[ 0. 0. 0. ] [-10. 28. 0. ] [ 10. -1. 0. ] [ 0. 0. -2.66666667] [ 0. 0. 0. ] [ 0. 0. 1. ] [ 0. -1. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ] [ 0. 0. 0. ]]