Newer
Older
import numpy as np
import json
from itertools import product
import matplotlib.pyplot as plt
# Load configuration from JSON file
def load_config(config_path):
with open(config_path, 'r') as f:
return json.load(f)
def simulation_configuration_setup():
config_path = "config.json"
config = load_config(config_path)
m_start = config["m_variants_start"]
m_end = config["m_variants_end"]
m_step = config["m_variants_step"]
k_start = config["k_variants_start"]
k_end = config["k_variants_end"]
k_step = config["k_variants_step"]
b_start = config["b_variants_start"]
b_end = config["b_variants_end"]
b_step = config["b_variants_step"]
# Generate model variants
ms = np.arange(m_start, m_end + m_step, m_step).tolist()
ks = np.arange(k_start, k_end + k_step, k_step).tolist()
bs = np.arange(b_start, b_end + b_step, b_step).tolist()
# Generate all possible combinations of m, k, and b
λs = [np.array(λ) for λ in product(ms, ks, bs)]
m = config['true_m']
k = config['true_k']
b = config['true_b']
dt = config["dt"]
H = np.array(config["H"])
Q = np.eye(H.shape[1]) * config["Q"]
R = np.eye(H.shape[0]) * config["R"]
x0 = np.array(config["initial_state"])
max_time = config['max_time']
max_steps = int(config['max_time'] / dt)
amplitude = config['amplitude']
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
return λs, m, k, b, dt, H, Q, R, x0, max_time, max_steps, amplitude
def plot_λ_hat(times, lambda_hats, true_λ):
# Convert the list of lambda_hats (which are vectors) to a numpy array for easy indexing
lambda_hats = np.array(lambda_hats)
fig, ax1 = plt.subplots()
# Plot estimated mass (m) on the primary y-axis
ax1.set_xlabel('Time (s)')
ax1.set_ylabel('Mass (m)', color='blue')
ax1.plot(times, lambda_hats[:, 0], label='Estimated mass (m)', color='blue', linestyle='-')
ax1.axhline(y=true_λ[0], color='blue', linestyle='--', label='True mass (m)')
ax1.tick_params(axis='y', labelcolor='blue')
# Create a secondary y-axis for spring constant (k)
ax2 = ax1.twinx()
ax2.set_ylabel('Spring constant (k)', color='green')
ax2.plot(times, lambda_hats[:, 1], label='Estimated spring constant (k)', color='green', linestyle='-')
ax2.axhline(y=true_λ[1], color='green', linestyle='--', label='True spring constant (k)')
ax2.tick_params(axis='y', labelcolor='green')
# Create another secondary y-axis for damping coefficient (b) (offset from the right)
ax3 = ax1.twinx()
ax3.spines['right'].set_position(('outward', 60)) # Offset third axis to the right
ax3.set_ylabel('Damping coefficient (b)', color='red')
ax3.plot(times, lambda_hats[:, 2], label='Estimated damping coefficient (b)', color='red', linestyle='-')
ax3.axhline(y=true_λ[2], color='red', linestyle='--', label='True damping coefficient (b)')
ax3.tick_params(axis='y', labelcolor='red')
# Add legends for each axis
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')
ax3.legend(loc='lower right')
plt.title('Parameter Estimates (m, k, b) vs Time')
fig.tight_layout() # To avoid overlap of labels

Tilboon Elberier
committed
plt.grid(True)
plt.show()
def plot_heatmap(models_summary, times, λs, title):
# Convert to string for label on plot
λs = [f"m: {round(λ[0], 2)}, k: {round(λ[1], 2)}, b: {round(λ[2], 2)}" for λ in λs]

Tilboon Elberier
committed
plt.figure(figsize=(10, 6))
plt.imshow(models_summary.T, aspect='auto', cmap='hot', origin='lower',
extent=[times[0], times[-1], λs[0], λs[-1]])
plt.colorbar(label='Model Likelihoods/Probabilities')
plt.xlabel('Time (s)')
plt.ylabel('Model Variants (λs)')
plt.title(title)
plt.show()
def mmae_simulator_simulation_and_plot(simulator, λs, true_λ, max_steps, dt):
# Lists to store time and λ_hat values
times = []
lambda_hats = []

Tilboon Elberier
committed
cumulative_posteriors_summary = []
pdvs_summary = []
# Main simulation loop
for step_counter in range(1, max_steps):

Tilboon Elberier
committed
λ_hat, cumulative_posteriors, pdvs = simulator.update(step_counter)
times.append(step_counter * dt)
lambda_hats.append(λ_hat)

Tilboon Elberier
committed
cumulative_posteriors_summary.append(cumulative_posteriors)
pdvs_summary.append(pdvs)
print(f"Step {step_counter}: λ_hat = {λ_hat}")
# Convert the list of lambda_hat values (vectors) to a numpy array
lambda_hats = np.array(lambda_hats)

Tilboon Elberier
committed
# Convert the list of model probabilities to a numpy array
cumulative_posteriors_summary = np.array(cumulative_posteriors_summary)
# Convert the list of model probabilities to a numpy array
pdvs_summary = np.array(pdvs_summary)
# np.savetxt("pdvs_summary.txt", pdvs_summary)
# np.savetxt("cumulative_posteriors_summary.txt", cumulative_posteriors_summary)
# Plot the estimated mass over time
plot_λ_hat(times, lambda_hats, true_λ)

Tilboon Elberier
committed
# Plot the heatmap for likelihoods (PDVs) over time
plot_heatmap(pdvs_summary, times, λs, title="Heatmap of Model Likelihood Over Time")
# Plot the heatmap for model cumulative posterior probabilities over time
plot_heatmap(cumulative_posteriors_summary, times, λs, title="Heatmap of Cumulative Posterior Probabilities Over Time")