Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 75 additions & 4 deletions bioptim/gui/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

from ..limits.constraints import Constraint
from ..limits.objective_functions import ObjectiveFcn, ObjectiveList, Objective
from ..limits.path_conditions import PathCondition
from ..limits.path_conditions import PathCondition, Bounds
from ..optimization.parameters import Parameter
from ..misc.enums import Node
from bioptim import InterpolationType


class GraphAbstract:
Expand Down Expand Up @@ -308,15 +309,30 @@ class OcpToConsole(GraphAbstract):
-------
print(self)
Print ocp structure in the console
print_bounds(self, phase_idx: int, bounds: Bounds, col_name: list[str])
Print ocp bounds in the console
print_bounds_table(bounds: Bounds, col_name: list[str], title: list[str]):
Print bounds row

"""

def print(self):
"""
Print ocp structure in the console
"""

for phase_idx in range(self.ocp.n_phases):
print(f"PHASE {phase_idx}")
print(f"PHASE: {phase_idx}")
print(f"**********")
print(f"BOUNDS:")
print(f"STATES: InterpolationType.{self.ocp.nlp[phase_idx].x_bounds.type.name}")
self.print_bounds(phase_idx, self.ocp.nlp[phase_idx].x_bounds,
[self.ocp.nlp[phase_idx].states.cx[i].name()
for i in range(self.ocp.nlp[phase_idx].states.cx.shape[0])])
print(f"**********")
print(f"CONTROLS: InterpolationType.{self.ocp.nlp[phase_idx].u_bounds.type.name}")
self.print_bounds(phase_idx, self.ocp.nlp[phase_idx].u_bounds,
[self.ocp.nlp[phase_idx].controls.cx[i].name()
for i in range(self.ocp.nlp[phase_idx].controls.cx.shape[0])])
print(f"**********")
print(f"PARAMETERS: ")
print("")
Expand Down Expand Up @@ -369,9 +385,64 @@ def print(self):
print(f"*** Implicit Constraint: {constraint.name}")
print("")

def print_bounds(self, phase_idx: int, bounds: Bounds, col_name: list[str]):
"""
Print ocp bounds in the console

class OcpToGraph(GraphAbstract):
Parameters
----------
phase_idx: int
The phase index
bounds: Bounds
The controls or states bounds
col_name: list[str]
The list of controls or states name
"""
nlp = self.ocp.nlp[phase_idx]

if bounds.type == InterpolationType.CONSTANT_WITH_FIRST_AND_LAST_DIFFERENT:
title = ["", "Beginning", "Middle", "End"]
elif bounds.type == InterpolationType.CONSTANT:
title = ["", "Bounds"]
elif bounds.type == InterpolationType.LINEAR:
title = ["", "Beginning", "End"]
self.print_bounds_table(bounds, col_name, title)

@staticmethod
def print_bounds_table(bounds: Bounds, col_name: list[str], title: list[str]):
"""
Print bounds table

Parameters
----------
bounds: Bounds
The controls or states bounds
col_name: list[str]
The list of states names
title: list[str]
The list of column's title
"""
gap = 20 # length of a column printed in the console

max_bounds = np.round(np.array(bounds.max.tolist()), 3)
min_bounds = np.round(np.array(bounds.min.tolist()), 3)

first_col_length = len(max(col_name, key=len))

title_row = f"{title[0]}" + (first_col_length - len(title[0]) + 2) * " "
for n in range(len(title) - 1):
title_row += f"{title[n + 1]}" + (gap - len(title[n + 1])) * " "
print(title_row)
for h in range(bounds.shape[0]):
table_row = col_name[h] + (first_col_length - len(col_name[h]) + 2) * " "
for j in range(len(min_bounds[h])):
row_element = f"[{min_bounds[h][j]}, {max_bounds[h][j]}]"
row_element += (gap - row_element.__len__()) * " "
table_row += row_element
print(table_row)


class OcpToGraph(GraphAbstract):
_return_line = "<br/>"
_squared = "<sup>2</sup>"
"""
Expand Down