672 KiB
672 KiB
In [27]:
import numpy as np
import pandas as pd
from math import *
import matplotlib.pyplot as pltIn [28]:
DeltaT = 0.01
#set up arrays
tfinal = 20 # in seconds
n = ceil(tfinal/DeltaT)
# set up arrays for t, a, v, and x
t = np.zeros(n)
v = np.zeros(n)
x = np.zeros(n)
# Initial conditions as compact 2-dimensional arrays
x0 = 2
v0 = 0
x[0] = x0
v[0] = v0
# Start integrating using Euler's method
for i in range(n-1):
# Set up the acceleration
a = -x[i]
# update velocity, time and position using Euler's forward method
v[i+1] = v[i] + DeltaT*a
x[i+1] = x[i] + DeltaT*v[i+1]
t[i+1] = t[i] + DeltaT
m = 1
k = 1
K = 1/2*m*v**2
V = 1/2*k*x**2
E = K+V
# Plot position, velocity and total energy as function of time
fig, ax = plt.subplots(3,1)
fig.set_size_inches(15,10)
ax[0].set_title('Euler-Cromer')
ax[0].plot(t,x)
ax[1].plot(t,v)
ax[2].plot(t,E)
ax[2].set_ylim([0,20])
ax[2].set_xlabel('Time (s)')
ax[0].set_ylabel('Position (m)')
ax[1].set_ylabel('Velocity (m/s)')
ax[2].set_ylabel('Energy (J)')
fig.tight_layout()
plt.show()In [29]:
DeltaT = 0.01
#set up arrays
tfinal = 20
n = ceil(tfinal/DeltaT)
# set up arrays for t, a, v, and x
t = np.zeros(n)
v = np.zeros(n)
x = np.zeros(n)
# Initial conditions as compact 2-dimensional arrays
x0 = 2
v0 = 0
x[0] = x0
v[0] = v0
# Start integrating using the Velocity-Verlet method
for i in range(n-1):
# Set up the acceleration
a = -x[i]
# update velocity, time and position using the Velocity-Verlet method
x[i+1] = x[i] + DeltaT*v[i]+0.5*(DeltaT**2)*a
anew = -x[i+1]
v[i+1] = v[i] + 0.5*DeltaT*(a+anew)
t[i+1] = t[i] + DeltaT
m = 1
k = 1
K = 1/2*m*v**2
V = 1/2*k*x**2
E = K+V
# Plot position, velocity and total energy as function of time
fig, ax = plt.subplots(3,1)
fig.set_size_inches(15,10)
ax[0].set_title('Velocity-Verlet')
ax[0].plot(t,x)
ax[1].plot(t,v)
ax[2].plot(t,E)
ax[2].set_ylim([1.5,2.5])
ax[2].set_xlabel('Time (s)')
ax[0].set_ylabel('Position (m)')
ax[1].set_ylabel('Velocity (m/s)')
ax[2].set_ylabel('Energy (J)')
fig.tight_layout()
plt.show()In [30]:
DeltaT = 0.01
#set up arrays
tfinal = 20 # in seconds
n = ceil(tfinal/DeltaT)
# set up arrays for t, a, v, and x
t = np.zeros(n)
v = np.zeros(n)
x = np.zeros(n)
# Initial conditions as compact 2-dimensional arrays
x0 = 2
v0 = 2
x[0] = x0
v[0] = v0
gamma = 0.2
# Start integrating using Euler's method
for i in range(n-1):
# Set up the acceleration
a = -2*gamma*v[i]-x[i]
# update velocity, time and position using Euler's forward method
v[i+1] = v[i] + DeltaT*a
x[i+1] = x[i] + DeltaT*v[i+1]
t[i+1] = t[i] + DeltaT
m = 1
k = 1
# Plot position and velocity as function of time
fig, ax = plt.subplots(2,1)
fig.set_size_inches(8,10)
ax[0].set_title('Underdamping')
ax[0].plot(t,x)
ax[1].plot(t,v)
ax[1].set_xlabel('Time (s)')
ax[0].set_ylabel('Position (m)')
ax[1].set_ylabel('Velocity (m/s)')
fig.tight_layout()
plt.show()In [31]:
DeltaT = 0.01
#set up arrays
tfinal = 20 # in seconds
n = ceil(tfinal/DeltaT)
# set up arrays for t, a, v, and x
t = np.zeros(n)
v = np.zeros(n)
x = np.zeros(n)
# Initial conditions as compact 2-dimensional arrays
x0 = 2
v0 = 2
x[0] = x0
v[0] = v0
gamma = 1
# Start integrating using Euler's method
for i in range(n-1):
# Set up the acceleration
a = -2*gamma*v[i]-x[i]
# update velocity, time and position using Euler's forward method
v[i+1] = v[i] + DeltaT*a
x[i+1] = x[i] + DeltaT*v[i+1]
t[i+1] = t[i] + DeltaT
m = 1
k = 1
# Plot position and velocity as function of time
fig, ax = plt.subplots(2,1)
fig.set_size_inches(8,10)
ax[0].set_title('Critical Damping')
ax[0].plot(t,x)
ax[1].plot(t,v)
ax[1].set_xlabel('Time (s)')
ax[0].set_ylabel('Position (m)')
ax[1].set_ylabel('Velocity (m/s)')
fig.tight_layout()
plt.show()In [32]:
DeltaT = 0.01
#set up arrays
tfinal = 20 # in seconds
n = ceil(tfinal/DeltaT)
# set up arrays for t, a, v, and x
t = np.zeros(n)
v = np.zeros(n)
x = np.zeros(n)
# Initial conditions as compact 2-dimensional arrays
x0 = 2
v0 = 2
x[0] = x0
v[0] = v0
gamma = 2
# Start integrating using Euler's method
for i in range(n-1):
# Set up the acceleration
a = -2*gamma*v[i]-x[i]
# update velocity, time and position using Euler's forward method
v[i+1] = v[i] + DeltaT*a
x[i+1] = x[i] + DeltaT*v[i+1]
t[i+1] = t[i] + DeltaT
m = 1
k = 1
# Plot position and velocity as function of time
fig, ax = plt.subplots(2,1)
fig.set_size_inches(8,10)
ax[0].set_title('Overdamping')
ax[0].plot(t,x)
ax[1].plot(t,v)
ax[1].set_xlabel('Time (s)')
ax[0].set_ylabel('Position (m)')
ax[1].set_ylabel('Velocity (m/s)')
fig.tight_layout()
plt.show()In [33]:
DeltaT = 0.001
#set up arrays
tfinal = 20 # in dimensionless time
n = ceil(tfinal/DeltaT)
# set up arrays for t, v, and x
t = np.zeros(n)
v = np.zeros(n)
x = np.zeros(n)
# Initial conditions as one-dimensional arrays of time
x0 = 2
v0 = 2
x[0] = x0
v[0] = v0
gamma = 0.2
Omegatilde = 0.5
Ftilde = 1.0
# Start integrating using Euler-Cromer's method
for i in range(n-1):
# Set up the acceleration
a = -2*gamma*v[i]-x[i]+Ftilde*cos(t[i]*Omegatilde)
# update velocity, time and position
v[i+1] = v[i] + DeltaT*a
x[i+1] = x[i] + DeltaT*v[i+1]
t[i+1] = t[i] + DeltaT
# Plot position and velocity as function of time
fig, ax = plt.subplots(2,1)
fig.set_size_inches(8,10)
ax[0].set_title('Driving Force')
ax[0].plot(t,x)
ax[1].plot(t,v)
ax[1].set_xlabel('Time (s)')
ax[0].set_ylabel('Position (m)')
ax[1].set_ylabel('Velocity (m/s)')
fig.tight_layout()
plt.show()In [34]:
def SpringForce(v,x,t):
# note here that we have divided by mass and we return the acceleration
return -2*gamma*v-x+Ftilde*cos(t*Omegatilde)In [35]:
def RK4(v,x,t,n,Force):
for i in range(n-1):
# Setting up k1
k1x = DeltaT*v[i]
k1v = DeltaT*Force(v[i],x[i],t[i])
# Setting up k2
vv = v[i]+k1v*0.5
xx = x[i]+k1x*0.5
k2x = DeltaT*vv
k2v = DeltaT*Force(vv,xx,t[i]+DeltaT*0.5)
# Setting up k3
vv = v[i]+k2v*0.5
xx = x[i]+k2x*0.5
k3x = DeltaT*vv
k3v = DeltaT*Force(vv,xx,t[i]+DeltaT*0.5)
# Setting up k4
vv = v[i]+k3v
xx = x[i]+k3x
k4x = DeltaT*vv
k4v = DeltaT*Force(vv,xx,t[i]+DeltaT)
# Final result
x[i+1] = x[i]+(k1x+2*k2x+2*k3x+k4x)/6.
v[i+1] = v[i]+(k1v+2*k2v+2*k3v+k4v)/6.
t[i+1] = t[i] + DeltaTIn [36]:
DeltaT = 0.001
#set up arrays
tfinal = 20 # in dimensionless time
n = ceil(tfinal/DeltaT)
# set up arrays for t, v, and x
t = np.zeros(n)
v = np.zeros(n)
x = np.zeros(n)
# Initial conditions (can change to more than one dim)
x0 = 2
v0 = 2
x[0] = x0
v[0] = v0
gamma = 0.2
Omegatilde = 0.5
Ftilde = 1.0
# Start integrating using the RK4 method
# Note that we define the force function as a SpringForce
RK4(v,x,t,n,SpringForce)
# Plot position and velocity as function of time
fig, ax = plt.subplots(2,1)
fig.set_size_inches(8,10)
ax[0].set_title('Driving Force')
ax[0].plot(t,x)
ax[1].plot(t,v)
ax[1].set_xlabel('Time (s)')
ax[0].set_ylabel('Position (m)')
ax[1].set_ylabel('Velocity (m/s)')
fig.tight_layout()
plt.show()In [37]:
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dense, LSTM, Dropout
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.regularizers import l2
from tensorflow.keras.callbacks import EarlyStopping
from scipy.integrate import solve_ivp
import matplotlib.pyplot as pltIn [38]:
learning_rate = 0.001
epochs = 1000
hidden_layer_size = 64
l2_regularization = 1e-4
dropout_rate = 0.2In [39]:
model = Sequential([
LSTM(hidden_layer_size, activation='tanh', input_shape=(1, 3), kernel_regularizer=l2(l2_regularization)),
Dropout(dropout_rate),
Dense(hidden_layer_size, activation='relu', kernel_regularizer=l2(l2_regularization)),
Dropout(dropout_rate),
Dense(2)
])
optimizer = Adam(learning_rate=learning_rate)
model.compile(optimizer=optimizer, loss='mse')In [40]:
def SpringForce(t, y, gamma, Ftilde, Omegatilde):
x, v = y
a = -2*gamma*v-x+Ftilde*cos(t*Omegatilde)
return [v, a]In [41]:
gamma = 0.2
Ftilde = 1.0
Omegatilde = 0.5
t_span = (0, 20)
t_eval = np.linspace(*t_span, num=1000)
initial_conditions = [2, 2]
solution = solve_ivp(SpringForce, t_span, initial_conditions, args=(gamma, Ftilde, Omegatilde), t_eval=t_eval, method='RK45')
t_train = solution.t
y_train = solution.y.TIn [42]:
validation_split = 0.2
split_index = int((1 - validation_split) * len(t_train))
t_train, t_val = t_train[:split_index], t_train[split_index:]
y_train, y_val = y_train[:split_index], y_train[split_index:]In [43]:
input_train = np.column_stack((t_train, y_train))
input_train = input_train[:, np.newaxis, :]
input_val = np.column_stack((t_val, y_val))
input_val = input_val[:, np.newaxis, :]In [44]:
early_stopping = EarlyStopping(monitor='val_loss', patience=50, restore_best_weights=True)
model.fit(input_train, y_train, epochs=epochs, verbose=1, validation_data=(input_val, y_val), callbacks=[early_stopping])Out [44]:
Epoch 1/1000 25/25 [==============================] - 5s 27ms/step - loss: 0.9932 - val_loss: 0.9847 Epoch 2/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.6206 - val_loss: 1.1054 Epoch 3/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.2845 - val_loss: 0.6862 Epoch 4/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.1508 - val_loss: 0.5876 Epoch 5/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0904 - val_loss: 0.3317 Epoch 6/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0776 - val_loss: 0.2523 Epoch 7/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0681 - val_loss: 0.2011 Epoch 8/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0594 - val_loss: 0.1479 Epoch 9/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0564 - val_loss: 0.1409 Epoch 10/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0546 - val_loss: 0.1538 Epoch 11/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0551 - val_loss: 0.1175 Epoch 12/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0510 - val_loss: 0.1400 Epoch 13/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0509 - val_loss: 0.1371 Epoch 14/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0468 - val_loss: 0.1022 Epoch 15/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0436 - val_loss: 0.1038 Epoch 16/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0486 - val_loss: 0.0790 Epoch 17/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0416 - val_loss: 0.0797 Epoch 18/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0400 - val_loss: 0.0812 Epoch 19/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0432 - val_loss: 0.0821 Epoch 20/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0425 - val_loss: 0.0939 Epoch 21/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0411 - val_loss: 0.0838 Epoch 22/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0429 - val_loss: 0.0788 Epoch 23/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0409 - val_loss: 0.0886 Epoch 24/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0407 - val_loss: 0.0917 Epoch 25/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0407 - val_loss: 0.0651 Epoch 26/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0384 - val_loss: 0.0877 Epoch 27/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0372 - val_loss: 0.0887 Epoch 28/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0395 - val_loss: 0.0677 Epoch 29/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0368 - val_loss: 0.0617 Epoch 30/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0367 - val_loss: 0.0834 Epoch 31/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0368 - val_loss: 0.0486 Epoch 32/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0382 - val_loss: 0.0872 Epoch 33/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0366 - val_loss: 0.0880 Epoch 34/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0363 - val_loss: 0.0681 Epoch 35/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0359 - val_loss: 0.0598 Epoch 36/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0375 - val_loss: 0.0610 Epoch 37/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0354 - val_loss: 0.0645 Epoch 38/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0358 - val_loss: 0.0996 Epoch 39/1000 25/25 [==============================] - 0s 7ms/step - loss: 0.0389 - val_loss: 0.0878 Epoch 40/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0340 - val_loss: 0.0891 Epoch 41/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0320 - val_loss: 0.0818 Epoch 42/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0347 - val_loss: 0.0789 Epoch 43/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0326 - val_loss: 0.0638 Epoch 44/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0342 - val_loss: 0.0837 Epoch 45/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0333 - val_loss: 0.0889 Epoch 46/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0316 - val_loss: 0.0910 Epoch 47/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0352 - val_loss: 0.0653 Epoch 48/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0346 - val_loss: 0.0876 Epoch 49/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0316 - val_loss: 0.0684 Epoch 50/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0322 - val_loss: 0.0825 Epoch 51/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0320 - val_loss: 0.0637 Epoch 52/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0322 - val_loss: 0.0714 Epoch 53/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0343 - val_loss: 0.0830 Epoch 54/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0325 - val_loss: 0.0560 Epoch 55/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0312 - val_loss: 0.0751 Epoch 56/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0295 - val_loss: 0.0779 Epoch 57/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0312 - val_loss: 0.0893 Epoch 58/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0301 - val_loss: 0.0790 Epoch 59/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0325 - val_loss: 0.0802 Epoch 60/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0309 - val_loss: 0.0788 Epoch 61/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0309 - val_loss: 0.0808 Epoch 62/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0318 - val_loss: 0.0847 Epoch 63/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0309 - val_loss: 0.0853 Epoch 64/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0301 - val_loss: 0.0792 Epoch 65/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0323 - val_loss: 0.0772 Epoch 66/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0307 - val_loss: 0.1031 Epoch 67/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0321 - val_loss: 0.0724 Epoch 68/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0291 - val_loss: 0.0741 Epoch 69/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0292 - val_loss: 0.0715 Epoch 70/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0299 - val_loss: 0.0883 Epoch 71/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0326 - val_loss: 0.0799 Epoch 72/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0296 - val_loss: 0.0926 Epoch 73/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0296 - val_loss: 0.0984 Epoch 74/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0295 - val_loss: 0.0942 Epoch 75/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0297 - val_loss: 0.0896 Epoch 76/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0308 - val_loss: 0.0726 Epoch 77/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0306 - val_loss: 0.0913 Epoch 78/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0303 - val_loss: 0.0706 Epoch 79/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0303 - val_loss: 0.0832 Epoch 80/1000 25/25 [==============================] - 0s 5ms/step - loss: 0.0302 - val_loss: 0.0997 Epoch 81/1000 25/25 [==============================] - 0s 6ms/step - loss: 0.0316 - val_loss: 0.0758
<keras.callbacks.History at 0x2cd527b6ec0>
In [45]:
y_pred_train = model.predict(input_train)
y_pred_val = model.predict(input_val)
plt.figure(figsize=(18,10))
plt.subplot(1, 2, 1)
plt.plot(t_train, y_train[:, 0], label='True position (train)')
plt.plot(t_val, y_val[:, 0], label='True position (validation)')
plt.plot(t_train, y_pred_train[:, 0], label='Predicted position (train)')
plt.plot(t_val, y_pred_val[:, 0], label='Predicted position (validation)')
plt.xlabel('Time')
plt.ylabel('Position')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(t_train, y_train[:, 1], label='True velocity (train)')
plt.plot(t_val, y_val[:, 1], label='True velocity (validation)')
plt.plot(t_train, y_pred_train[:, 1], label='Predicted velocity (train)')
plt.plot(t_val, y_pred_val[:, 1], label='Predicted velocity (validation)')
plt.xlabel('Time')
plt.ylabel('Velocity')
plt.legend()
plt.show()25/25 [==============================] - 0s 2ms/step 7/7 [==============================] - 0s 3ms/step
In [46]:
gamma = 1
Ftilde = 0
Omegatilde = 1
t_span = (0, 20)
t_eval = np.linspace(*t_span, num=1000)
initial_conditions = [2, 2]
solution = solve_ivp(SpringForce, t_span, initial_conditions, args=(gamma, Ftilde, Omegatilde), t_eval=t_eval, method='RK45')
t_train = solution.t
y_train = solution.y.TIn [47]:
validation_split = 0.2
split_index = int((1 - validation_split) * len(t_train))
t_train, t_val = t_train[:split_index], t_train[split_index:]
y_train, y_val = y_train[:split_index], y_train[split_index:]In [48]:
input_train = np.column_stack((t_train, y_train))
input_train = input_train[:, np.newaxis, :]
input_val = np.column_stack((t_val, y_val))
input_val = input_val[:, np.newaxis, :]Warning:
Output truncated. This notebook contains too many cells to display efficiently.