Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Algebraic states are states #907

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e597291
feat: alternative partition recommendation
Ipuch Jan 23, 2025
9b8fef0
refactor: making partionned_forward_dynamics more flexible for colloc…
Ipuch Jan 24, 2025
2187a56
lint: holonomic model
Ipuch Jan 26, 2025
4da2bba
feat: making sure algebraic states are states. Rolling.
Ipuch Jan 26, 2025
3fbf174
fix test: restoring tf dependant dynamics tests
Ipuch Jan 27, 2025
cc50213
docs : stochastic
Ipuch Jan 27, 2025
2bdf6de
refactor: splitting ode_solver script
Ipuch Jan 30, 2025
bb2cedc
feat/ fix: I found all the places with inconsistent n_cols for algebr…
Ipuch Jan 30, 2025
6883210
feat: handling 2d dim with partitionned states
Ipuch Jan 30, 2025
42fe411
feat: algebraic states as proper entry of OCP
Ipuch Jan 30, 2025
c7f956e
Merge remote-tracking branch 'pyomeca/master' into algebraic
Ipuch Jan 31, 2025
52e57de
example: holonomic refactor plot
Ipuch Jan 31, 2025
cfa1ced
example: holonomic algebraic
Ipuch Jan 31, 2025
c2b8774
fix: integrator algebraic states offset idx
Ipuch Jan 31, 2025
2090518
refactor: standardizing the way variable size is written
Ipuch Jan 31, 2025
b146b05
refactor: giving the right size to OptimizationVariableList even if n…
Ipuch Jan 31, 2025
437c72c
fix: for tests to pass
Ipuch Jan 31, 2025
000d740
tests: fixed
Ipuch Jan 31, 2025
5aef666
fix: IRK case
Ipuch Jan 31, 2025
6f86c93
some comment to help me debug
Ipuch Jan 31, 2025
e9f4901
tests: fix the numerical time series utils to fit the one in the OCP …
Ipuch Jan 31, 2025
1dc116c
fix: integrated values
Ipuch Jan 31, 2025
7b19efb
todos
Ipuch Feb 3, 2025
a200e03
fix: on algebraic states
Ipuch Feb 4, 2025
5c87647
feat: allow for multiple ODE Solvers for multiphases problems.
Ipuch Feb 4, 2025
21e6030
hacky: disgusting solution, need to make sure i can skip any intermed…
Ipuch Feb 4, 2025
cf04062
cherry pick ode solver test
Ipuch Feb 7, 2025
f312c24
very poor success @restoring stochastic...
Ipuch Feb 7, 2025
fa080a2
refactor feat delete: astates stuff no longer neeeded
Ipuch Feb 7, 2025
f1665c9
Merge branch 'master' into algebraic
Ipuch Feb 19, 2025
d89ebf3
make sure n_cx = 3 is used
Ipuch Feb 19, 2025
3d92b82
tests: restore example
Ipuch Feb 19, 2025
21f3516
tests: algebraic holonomic pb
Ipuch Feb 19, 2025
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
Prev Previous commit
Next Next commit
feat: making sure algebraic states are states. Rolling.
Ipuch committed Jan 26, 2025
commit 4da2bbaf2b12cf513cbb5b49bfc1b124443d2f12
8 changes: 5 additions & 3 deletions bioptim/dynamics/configure_new_variable.py
Original file line number Diff line number Diff line change
@@ -443,7 +443,7 @@ def _declare_cx_and_plot(self):
for node_index in range(
self.nlp.n_states_nodes if self.nlp.phase_dynamics == PhaseDynamics.ONE_PER_NODE else 1
):
n_cx = 2
n_cx = self.nlp.ode_solver.n_required_cx + 2
cx_scaled = (
self.ocp.nlp[self.nlp.use_states_from_phase_idx].algebraic_states[node_index][self.name].original_cx
if self.copy_algebraic_states
@@ -463,14 +463,16 @@ def _declare_cx_and_plot(self):
node_index,
)
if not self.skip_plot:
all_variables_in_one_subplot = True if self.name in ["m", "cov", "k"] else False
all_variables_in_one_subplot = (
True if self.name in ["m", "cov", "k"] else False
) # To Eve: This should not be there.
self.nlp.plot[f"{self.name}_algebraic"] = CustomPlot(
lambda t0, phases_dt, node_idx, x, u, p, a, d: (
a[self.nlp.algebraic_states.key_index(self.name), :]
if a.any()
else np.ndarray((cx[0][0].shape[0], 1)) * np.nan
),
plot_type=PlotType.STEP,
plot_type=PlotType.INTEGRATED,
axes_idx=self.axes_idx,
legend=self.legend,
combine_to=self.combine_name,
14 changes: 11 additions & 3 deletions bioptim/dynamics/integrator.py
Original file line number Diff line number Diff line change
@@ -87,7 +87,7 @@ def __init__(self, ode: dict, ode_opt: dict):
self._x_sym_modified,
self.u_sym,
self.param_sym,
self.a_sym,
self._a_sym_modified,
self.numerical_timeseries_sym,
],
self.dxdt(
@@ -130,6 +130,10 @@ def _time_xall_from_dt_func(self) -> Function:
def _x_sym_modified(self):
return self.x_sym

@property
def _a_sym_modified(self):
return self.a_sym

@property
def _input_names(self):
return ["t_span", "x0", "u", "p", "a", "d"]
@@ -585,6 +589,10 @@ def _initialize(self, ode: dict, ode_opt: dict):
def _x_sym_modified(self):
return horzcat(*self.x_sym) if self.duplicate_starting_point else horzcat(*self.x_sym[1:])

@property
def _a_sym_modified(self):
return horzcat(*self.a_sym) if self.duplicate_starting_point else horzcat(*self.a_sym[1:])

@property
def _output_names(self):
return ["xf", "xall", "defects"]
@@ -664,7 +672,7 @@ def dxdt(
states[j + 1],
self.get_u(controls, self._integration_time[j]),
params,
algebraic_states,
algebraic_states[j],
numerical_timeseries,
)[:, self.ode_idx]
defects.append(xp_j - f_j * self.h)
@@ -676,7 +684,7 @@ def dxdt(
states[j + 1],
self.get_u(controls, self._integration_time[j]),
params,
algebraic_states,
algebraic_states[j],
numerical_timeseries,
xp_j / self.h,
)
9 changes: 8 additions & 1 deletion bioptim/dynamics/ode_solver.py
Original file line number Diff line number Diff line change
@@ -491,8 +491,15 @@ def x_ode(self, nlp):
def p_ode(self, nlp):
return nlp.controls.scaled.cx_start

# def a_ode(self, nlp):
# return nlp.algebraic_states.scaled.cx_start

def a_ode(self, nlp):
return nlp.algebraic_states.scaled.cx_start
out = [nlp.algebraic_states.scaled.cx_start]
if not self.duplicate_starting_point:
out += [nlp.algebraic_states.scaled.cx_start]
out += nlp.algebraic_states.scaled.cx_intermediates_list
return out

def d_ode(self, nlp):
return nlp.numerical_timeseries.cx_start
4 changes: 4 additions & 0 deletions bioptim/interfaces/interface_utils.py
Original file line number Diff line number Diff line change
@@ -332,6 +332,10 @@ def generic_get_all_penalties(interface, nlp: NonLinearProgram, penalties, scale
tp[: u_tp.shape[0], :] = u_tp
u_tp = tp
u = horzcat(u, u_tp)
if idx != 0 and a_tp.shape[0] != a.shape[0]:
tp = ocp.cx.nan(a.shape[0], 1)
tp[: a_tp.shape[0], :] = a_tp
a_tp = tp
a = horzcat(a, a_tp)
d = horzcat(d, d_tp) if d is not None else d_tp
weight = np.concatenate((weight, [[float(weight_tp)]]), axis=1)