def forecast(data_dir, Nt, Nf, ic, s, b, r, ts, scale, offset): X = lorenz.Lsteps(ic, lorenz.F, s, b, r, ts, Nf + 1) f = open(join(data_dir, 'LaserForecast'), 'w') for t in range(Nf): x0 = float(X[t + 1, 0]) print(t + Nt, Y[Nt + t], (x0 * x0 * scale + offset), file=f) f.close()
def StepNt(P, Nt): """ Simulate a sequence of Nt measurements by: (1) Calculate initial condidtions from radius and time. (2) Integrate Lorenz. (3) Square first component, scale, and add offset. P = [rad, Tr, r, s, b, ts, offset, scale, noise] """ params = ParamCalc(*(list(P[0:8]) + [0, 0])) # Stick 0, 0 on end of P ic = params[0:3] r, s, b, ts, offset, scale = params[3:9] X = lorenz.Lsteps(ic, lorenz.F, s, b, r, ts, Nt) ys = X[:, 0] * X[:, 0] * scale + offset return ys
def TanGen0( DevEta=0.001, # Dynamical noise DevEpsilon=0.004, # Measurement noise s=10.0, r=28.0, b=8.0 / 3, # Lorenz parameters ts=0.15, # Sample interval Nt=300, # Number of samples trelax=1.0 # Time to relax to attractor ): """ Simulate the evolution of the whole system for Nt time steps. Record and return the sequence of states (X), observations (Y), derivatives of state maps (F) and derivatives of observation maps (G). TanGen0() is like TanGen(), but observation is X_0 instead of X_0**2 """ import lorenz, numpy as np, random assert trelax < 2.0, "Integrator doesn't work with big times" RG = random.gauss # Storage for initial conditions ic = np.ones(3) # Relax to the attractor: Nrelax = 30 temp = lorenz.Lsteps(ic, lorenz.F, s, b, r, trelax, Nrelax) ic = temp[-1] # reset ICs X = [] Y = [] F = [] G = [] for t in range(Nt): X.append(ic) Y.append(np.array([ic[0] + RG(0.0, DevEpsilon)])) G.append(np.array([[1.0, 0, 0]])) # Call to integrator. ic is overwritten with result ic, tan = lorenz.Ltan_one(ic, s, b, r, ts) ic = ic + np.array([RG(0.0, DevEta), RG(0.0, DevEta), RG(0.0, DevEta)]) F.append(tan) return (X, Y, F, G)
def ParamCalc(rad, Tr, r, s, b, ts, offset, scale, dev_epsilon, dev_eta): """ Translates specification of initial condition (rad,Tr) with radius rad from one of the unstable complex fixed points and relaxation time Tr to (ic[0],ic[1],ic[2]) thus creating a parameter vector suitable for EKF.LogLike(). """ root = math.sqrt(b * (r - 1)) # A frequently used intermediate term f = numpy.array([root, root, (r - 1)]) # One of three fixed points DF = numpy.array([[-s, s, 0], [1, -1, -root], [root, root, -b]]) # DF is the derivative of F at the fixed point f [val, vec] = LA.eig(DF) v = vec.T[1].real u = vec.T[1].imag w = (u - (u[2] / v[2]) * v) x0 = f - rad * (f[0] / w[0]) * w # x0 is in the plane of unstable complex pair of eigenvectors at # radius rad from f ic = lorenz.Lsteps(x0, lorenz.F, s, b, r, Tr, 2)[-1, :] # Now ic is result of trajectory starting at x0 after relaxation # time Tr. The idea is avoid funny looking transients. return ([ ic[0], ic[1], ic[2], r, s, b, ts, offset, scale, dev_epsilon, dev_eta ])
DevEta = 1e-5 # Std dev of state noise DIC = 1.0 # Size of cube of initial condidtions Dqy = 1e-3 # Y Quantization size # The smaller values of Nt and Nr require 31.8 seconds on cathcart #Nt = 400 # Number of times #Nr = 100 # Number of runs # The larger values of Nt and Nr require 17:57 on cathcart Nt = 1000 # Number of times Nr = 1000 # Number of runs ts = 0.15 # Time step tr = 10.0 # Relax time Rt = numpy.empty((Nt,Nr,3)) RAt = numpy.empty((Nt,Nr,3)) ic = [0.0, 0.1, 20.0] result = lorenz.Lsteps(ic, lorenz.F, s,b,r,tr,2) Aug = DevEta/Dqy # Augmentation of expansion by noise for j in range(Nr): # Loop over runs # Random initial condition in DIC cube ic = result[-1] + numpy.array([RR()*DIC,RR()*DIC,RR()*DIC]) Q = numpy.mat(numpy.eye(3)) # Basis in tangent space for t in range(Nt): # Loop over time steps ic,Tan = lorenz.Ltan_one(ic,s,b,r,ts) # Add state noise at each time step ic = ic + numpy.array([RG(0.0,DevEta),RG(0.0,DevEta),RG(0.0,DevEta)]) TQ = numpy.mat(Tan)*Q Q,R = LA.qr(TQ) # QR decomposition for i in range(3): rii = R[i,i] if rii > 0: Rt[t,j,i] = math.log(rii)