import numpy as np import matplotlib.pyplot as plt m_z=12345 # Zufallsinitialisierung (seed) m_w=34645 # Zufallsinitialisierung (seed) def rndNum(): # Eigener Pseudozufallsgenerator global m_z, m_w m_z = 36969 * (m_z & 65535) + (m_z >> 16) m_w = 18000 * (m_w & 65535) + (m_w >> 16) return (((int)(m_z << 16) + m_w)%100000)/100000 def mackey_glass(tau=17, n=10, beta=0.2, gamma=0.1, t_max=3000, dt=1): # Generiere Mackey-Glass-Zeitreihen mit Euler t = np.arange(0, t_max+dt, dt) x = np.zeros(len(t)) x[0:tau] = 0.5 # Anfangsbedingung for i in range(tau, len(t)): x[i] = x[i-1] + dt * (beta*x[i-tau]/(1 + x[i-tau]**n) - gamma*x[i-1]) return x # Daten generieren trainLen, testLen, initLen = 1500, 1500, 100 data = mackey_glass(tau=17, t_max=trainLen+testLen) # ESN-Reservoir generieren res_size = 300 W_in = np.zeros((res_size,2)) # Eingangsgewichte W = np.zeros((res_size,res_size)) # Reservoirgewichte for i in range(res_size): W_in[i][0] = rndNum()-0.5 W_in[i][1] = rndNum()-0.5 for j in range(res_size): if rndNum()<0.05: # 5% Verbindungen W[i][j] = rndNum()-0.5 # Gewichtsmatrix auf Spektralradius von 1.2 skalieren W *= 1.2 / max(abs(np.linalg.eig(W)[0])) X = np.zeros((1+res_size,trainLen-initLen)) # Reservoir-Werte Yt = data[initLen+1:trainLen+1] # Target-Werte # ESN trainieren x = np.zeros(res_size) for t in range(trainLen): u = data[t] x = np.tanh(np.dot(W_in, [1,u])+np.dot(W, x)) if t >= initLen: X[:,t-initLen] = np.concatenate(([1],x)) reg = 1e-7 # Regularisierungskoeffizient W_out = np.linalg.solve(np.dot(X,X.T) + reg*np.eye(1+res_size), np.dot(X,Yt)).T # Mackey-Glass-Attraktor vorhersagen Y = np.zeros(testLen) u = data[trainLen] for t in range(testLen): x = np.tanh(np.dot(W_in, [1,u])+np.dot(W, x)) y = np.dot( W_out, np.concatenate(([1],x)) ) Y[t] = y u = y mse = np.mean((data[trainLen+1:trainLen+501]-Y[:500])**2) print('MSE = ' + str( mse )) # Attraktoren plotten plt.figure(figsize=(12,6)) plt.title("Mackey-Glass-Attraktor") plt.xlabel('t') plt.ylabel('y(t)') plt.plot(data[trainLen+1:trainLen+1001], 'g', label="Originale Daten") plt.plot(Y[:1000], '--r', label="Generierte Daten") plt.legend(loc='upper right') plt.show()