From 912b7ed91e7f619074727572515d0d0b8ce48ea3 Mon Sep 17 00:00:00 2001 From: tjstienstra Date: Wed, 14 Feb 2024 15:53:49 +0100 Subject: [PATCH 1/2] Improve constraint violation visualization --- opty/direct_collocation.py | 43 ++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/opty/direct_collocation.py b/opty/direct_collocation.py index e0624376..3d9cfeac 100644 --- a/opty/direct_collocation.py +++ b/opty/direct_collocation.py @@ -367,27 +367,30 @@ def plot_constraint_violations(self, vector): - r : number of unknown parameters """ - + N = self.collocator.num_collocation_nodes con_violations = self.con(vector) - con_nodes = range(self.collocator.num_states, - self.collocator.num_collocation_nodes + 1) - N = len(con_nodes) - fig, axes = plt.subplots(self.collocator.num_states + 1) - - for i, (ax, symbol) in enumerate(zip(axes[:-1], - self.collocator.state_symbols)): - ax.plot(con_nodes, con_violations[i * N:i * N + N]) - ax.set_ylabel(sm.latex(symbol, mode='inline')) - - axes[0].set_title('Constraint Violations') - axes[-2].set_xlabel('Node Number') - - left = range(len(con_violations[self.collocator.num_states * N:])) - axes[-1].bar(left, con_violations[self.collocator.num_states * N:], - tick_label=[sm.latex(s, mode='inline') - for s in self.collocator.instance_constraints]) - axes[-1].set_ylabel('Instance') - axes[-1].set_xticklabels(axes[-1].get_xticklabels(), rotation=-10) + state_violations = con_violations[ + :(N - 1) * len(self.collocator.state_symbols)] + instance_violations = con_violations[len(state_violations):] + state_violations = state_violations.reshape( + (len(self.collocator.state_symbols), N - 1)) + con_nodes = range(1, self.collocator.num_collocation_nodes) + + plot_inst_viols = self.collocator.instance_constraints is not None + fig, axes = plt.subplots(1 + plot_inst_viols) + + axes[0].plot(con_nodes, state_violations.T) + axes[0].set_title('Constraint violations') + axes[0].set_xlabel('Node Number') + axes[0].set_ylabel('EoM violation') + + if plot_inst_viols: + axes[-1].bar( + range(len(instance_violations)), instance_violations, + tick_label=[sm.latex(s, mode='inline') + for s in self.collocator.instance_constraints]) + axes[-1].set_ylabel('Instance') + axes[-1].set_xticklabels(axes[-1].get_xticklabels(), rotation=-10) return axes From 7861e9e53d0d0b904d7dddb6294e0aff0eecdd41 Mon Sep 17 00:00:00 2001 From: tjstienstra Date: Wed, 14 Feb 2024 16:38:30 +0100 Subject: [PATCH 2/2] Fix plot constraint violation when no instance constraints are passed --- opty/direct_collocation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opty/direct_collocation.py b/opty/direct_collocation.py index 3d9cfeac..a78f47b0 100644 --- a/opty/direct_collocation.py +++ b/opty/direct_collocation.py @@ -377,7 +377,8 @@ def plot_constraint_violations(self, vector): con_nodes = range(1, self.collocator.num_collocation_nodes) plot_inst_viols = self.collocator.instance_constraints is not None - fig, axes = plt.subplots(1 + plot_inst_viols) + fig, axes = plt.subplots(1 + plot_inst_viols, squeeze=False) + axes = axes.ravel() axes[0].plot(con_nodes, state_violations.T) axes[0].set_title('Constraint violations')