-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathduffing_single_model.m
More file actions
207 lines (162 loc) · 5.74 KB
/
Copy pathduffing_single_model.m
File metadata and controls
207 lines (162 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
clc; clear; close all;
%set default figure properties
set(0,'DefaultLineLineWidth',2)
set(0,'defaultfigurecolor',[1 1 1])
% fix random seed
seed = 1;
rng(seed);
% import functions
addpath dynamics dmd edmd training prediction
%% Problem setup
% for duffing, states = [x1, x2].
dynamics_fn = @dynamics_duffing; % point to pendulum dynamics
% operator approximation method
% set to EDMD_flag = false for DMD.
% set to EDMD_flag = true for EDMD.
EDMD_flag = true;
%% Load training trajectory data using full domain
data = load("training/duffing_training.csv");
%%%%%%%%%%%%% Visualize the training dataset %%%%%%%%%%%%%%%%%%%%
% complete code to plot phase portraits of training data
% Number of trajectories in the dataset
num_trajectories = 100;
% Sampling rate
sampling_rate = 0.1;
% Number of data points in each trajectory
num_points = 10;
% Time span for each trajectory
time_span = 1;
% Visualize a few sample trajectories by plotting a phase portrait (θ vs ẋ)
figure;
hold on;
data_new = [];
index = 1;
theta = data(index:num_points+1,1);
theta_dot = data(index:num_points+1,2);
plot(theta, theta_dot);
data_new = [theta; theta_dot];
for i = 2:num_trajectories % Plot up to 5 trajectories
hold on;
index = num_points*(i-1)+i;
% Extract theta and theta_dot for the current trajectory
theta = data(index:index+num_points,1);
theta_dot = data(index:index+num_points,2);
% Plot phase portrait (theta vs theta_dot)
plot(theta, theta_dot);
data_new = [data_new,[theta;theta_dot]];
end
% Set labels and title
xlabel('\theta');
ylabel('\theta-dot');
title('Phase Portrait of Duffing Training Data');
% Add legend
legend('Trajectory 1', 'Trajectory 2', 'Trajectory 3', 'Trajectory 4', 'Trajectory 5');
% Display grid
grid on;
hold off;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%% Generate time-shfited snapshots %%%%%%%%%%%%%%%%%%%%
% complete code to obtain snapshots X1 and X2 from dataset X
% STEP 0: data split
X1 = data_new(:,1:end-1);
X2 = data_new(:,2:end);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% get Koopman operator
if(EDMD_flag)
% get Koopman operator using EDMD
% define basis setup
basis.dim = 2; % system dimension
%%%%%%%%%%%%% Setup basis properties for EDMD %%%%%%%%%%%%
% complete code
% specify basis type as a string below ('monomials or rbf'
basis.type = 'rbf';
switch basis.type
case 'monomials'
% specifiy degree of monomial sbelow
% basis.deg = ??;
case 'rbf'
% specifiy kernel width of rbfs
basis.gamma = 50;
otherwise
disp('Please specify type of basis')
end
%%%%%%%%%% Obtain Koopman operator using EDMD %%%%%%%%%%%%
% complete code for function get_EDMD()
[A, C, D_sorted] = get_EDMD(X1, X2, basis);
operator.A = A;
operator.C = C;
D = D_sorted(abs(D_sorted) < 1);
D = D(D~=0);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
else
%%%%%%%%%% Obtain Koopman operator using DMD %%%%%%%%%%%%
basis = [];
% complete code for function get_DMD()
A = get_DMD(X1, X2);
operator.A = A;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
%% Plot eigenvalues of Koopman operator
%%%%%%%%% Plot eigenvlaues of A in a unit circle %%%%%%%%%%%%%%%%
% complete code to plot discrete time eigenvalues of A
% Plot the eigenvalues in the complex plane (unit circle)
figure;
hold on;
plot(real(D), imag(D), 'bo'); % Plot eigenvalues as blue circles
theta = linspace(0, 2*pi, 100);
plot(cos(theta), sin(theta), 'r--'); % Plot unit circle in red dashed line
xlabel('Real Part');
ylabel('Imaginary Part');
title('Eigenvalues of Koopman Operator (DMD)');
legend('Eigenvalues', 'Unit Circle');
axis equal;
grid on;
hold off;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% evaluate operator for n timesteps prediction
% Use the following parameters for validation
prediction.n_traj = 9; %traj for evaluations
prediction.n_steps = 20; % num timesteps to predict
prediction.dt = 0.1;
prediction.show_plot = true;
% load the validation dataset
X_eval = load('prediction/duffing_validation.csv');
% Number of data points in each trajectory
prediction.num_points = size(X_eval, 1)/prediction.n_traj;
% Visualize a few sample trajectories by plotting a phase portrait (θ vs ẋ)
figure;
hold on;
index = 1;
theta_eval = X_eval(index:prediction.num_points,1);
theta_dot_eval = X_eval(index:prediction.num_points,2);
plot(theta_eval, theta_dot_eval);
for i = 2:prediction.n_traj % Plot up to 5 trajectories
hold on;
index = prediction.num_points *(i-1)+1;
% Extract theta and theta_dot for the current trajectory
theta_eval = X_eval(index:index+prediction.num_points -1,1);
theta_dot_eval = X_eval(index:index+prediction.num_points -1,2);
% Plot phase portrait (theta vs theta_dot)
plot(theta_eval, theta_dot_eval);
end
% Set labels and title
xlabel('\theta_{Eval}');
ylabel('\theta-dot_{Eval}');
title('Phase Portrait of Pendulum Prediction Data');
% Add legend
legend('Trajectory 1', 'Trajectory 2', 'Trajectory 3', 'Trajectory 4', 'Trajectory 5', ...
'Trajectory 6', 'Trajectory 7', 'Trajectory 8', 'Trajectory 9');
% Display grid
grid on;
hold off;
% Generate evaluation data
data_eval_new = zeros(size(X1, 1), prediction.n_traj * 10);
data_eval_new(1:11,1) = X_eval(1:11,1);
data_eval_new(12:22,1) = X_eval(1:11,2);
%%%%%%%%%%%%% Get predictions using Koopman %%%%%%%%%%%%%%%%%%%%
% complete code for function eval_prediction()
X_pred = eval_prediction(X_eval,operaotr,basis,prediction);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% evaluate the avg rmse and % error across for prediction
X_true = X_eval(1:prediction.n_steps,:);
RMSE = rmse(X_pred, X_true, prediction);