Skip to content

Commit 079c5cf

Browse files
authored
Merge pull request #1054 from pariterre/codex/biorbd-1-12-compat
Retrigger 2PR from mickaelbegon's codex
2 parents 0b7b5af + e8723c9 commit 079c5cf

10 files changed

Lines changed: 38 additions & 46 deletions

File tree

.github/workflows/run_tests_linux.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ jobs:
3636
conda list
3737
3838
- name: Install extra dependencies
39-
run: |
40-
conda install pip pytest-cov black pytest pytest-cov codecov packaging pytest-mpl -cconda-forge
39+
run: |
40+
conda install "numpy>=2.4,<3" pip pytest-cov black pytest pytest-cov codecov packaging pytest-mpl -cconda-forge
4141
sudo apt install -y librhash-dev
4242
4343
- name: Install ACADOS on Linux

.github/workflows/run_tests_osx_win.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
conda list
5151
5252
- name: Install extra dependencies
53-
run: conda install pip pytest-cov black pytest pytest-cov codecov packaging -cconda-forge
53+
run: conda install "numpy>=2.4,<3" pip pytest-cov black pytest pytest-cov codecov packaging -cconda-forge
5454

5555
- name: Install ACADOS on Mac
5656
run: |

bioptim/gui/graph.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99

1010
class GraphAbstract:
11-
_return_line: ""
12-
_squared: ""
11+
_return_line = ""
12+
_squared = ""
1313
"""
1414
Methods
1515
-------
@@ -61,6 +61,10 @@ def _vector_layout_structure(self, vector: FloatIterableorNpArray, decimal: Int)
6161
"""
6262
condensed_vector = ""
6363
for i, var in enumerate(vector):
64+
if isinstance(var, np.ndarray):
65+
if var.size > 1:
66+
raise ValueError("The vector layout structure needs to be applied on scalar only")
67+
var = var[0]
6468
condensed_vector += f"{round(float(var), decimal):.{decimal}f} "
6569
if i % 7 == 0 and i != 0:
6670
condensed_vector += f"... {self._return_line}... "

bioptim/gui/plot.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -695,10 +695,15 @@ def _add_bounds_to_plot(
695695
self, i: Int, nlp: NonLinearProgram, variable: Str, ctr: Int, ax: plt.Axes, mapping_to_first_index: IntList
696696
) -> None:
697697
"""Add bounds to a specific plot"""
698-
if nlp.plot[variable].bounds.type == InterpolationType.EACH_FRAME:
698+
if nlp.plot[variable].bounds.type in [InterpolationType.EACH_FRAME, InterpolationType.ALL_POINTS]:
699699
ns = nlp.plot[variable].bounds.min.shape[1] - 1
700700
else:
701701
ns = nlp.ns
702+
t = (
703+
[np.linspace(0, ns, ns + 1) for i in range(len(self.t))]
704+
if nlp.plot[variable].bounds.type == InterpolationType.ALL_POINTS
705+
else self.t
706+
)
702707

703708
# TODO: introduce repeat for the COLLOCATIONS min/max_bounds only for states graphs.
704709
# For now the plots in COLLOCATIONS with LINEAR are not giving the right values
@@ -712,8 +717,8 @@ def _add_bounds_to_plot(
712717
bounds_min = np.concatenate((bounds_min, [bounds_min[-1]]))
713718
bounds_max = np.concatenate((bounds_max, [bounds_max[-1]]))
714719

715-
self.plots_bounds.append([ax.step(self.t[i], bounds_min, where="post", **self.plot_options["bounds"]), i])
716-
self.plots_bounds.append([ax.step(self.t[i], bounds_max, where="post", **self.plot_options["bounds"]), i])
720+
self.plots_bounds.append([ax.step(t[i], bounds_min, where="post", **self.plot_options["bounds"]), i])
721+
self.plots_bounds.append([ax.step(t[i], bounds_max, where="post", **self.plot_options["bounds"]), i])
717722

718723
def _add_new_axis(self, variable: Str, nb: Int, n_rows: Int, n_cols: Int) -> np.ndarray[plt.Axes]:
719724
"""

bioptim/misc/mapping.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,12 @@ def __init__(
408408
dependency_matrix: list = [None for _ in range(len(first))]
409409
oppose = []
410410
for i in range(len(first)):
411-
if first[i] != 0 and first[i] > 0:
412-
dependency_matrix[i] = int(first[i] - 1)
413-
if first[i] < 0:
411+
value = first[i, 0]
412+
if value != 0 and value > 0:
413+
dependency_matrix[i] = int(value - 1)
414+
if value < 0:
414415
oppose.append(i)
415-
dependency_matrix[i] = int(abs(first[i]) - 1)
416+
dependency_matrix[i] = int(abs(value) - 1)
416417

417418
def _build_to_second(dependency_matrix: AnyList, independent_indices: AnyTuple):
418419
"""

bioptim/optimization/receding_horizon_optimization.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,8 @@ def solve(
775775
)
776776

777777
if self.parameters.shape != 0 and get_all_iterations:
778-
final_solution_parameters_dict = [{key: None} for key in solution[0].parameters.keys()][0]
779-
for key in solution[0].parameters.keys():
778+
final_solution_parameters_dict = [{key: None} for key in solution[1][0].parameters.keys()][0]
779+
for key in solution[1][0].parameters.keys():
780780
key_val = []
781781
for sol in solution[1]:
782782
key_val.append(sol.parameters[key])

bioptim/optimization/solution/solution.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,11 @@ def from_initial_guess(cls, ocp: "OptimalControlProgram", sol: AnyList):
277277

278278
dt, sol_states, sol_controls, sol_params, sol_algebraic_states = sol
279279

280-
vector = np.ndarray((0, 1))
281-
282280
# For time
283281
if len(dt.shape) == 1:
284282
dt = dt[:, np.newaxis]
285-
vector = np.concatenate((vector, dt))
283+
284+
state_vector = [dt]
286285

287286
# For states
288287
for p, ss in enumerate(sol_states):
@@ -299,9 +298,8 @@ def from_initial_guess(cls, ocp: "OptimalControlProgram", sol: AnyList):
299298

300299
for i in range(all_ns[p] * nb_intermediate_frames + 1):
301300
for key in ss.keys():
302-
vector = np.concatenate(
303-
(vector, ss[key].init.evaluate_at(i, nb_intermediate_frames)[:, np.newaxis])
304-
)
301+
state_vector.append(ss[key].init.evaluate_at(i, nb_intermediate_frames)[:, None])
302+
vector = np.vstack(state_vector)
305303

306304
# For controls
307305
for p, ss in enumerate(sol_controls):

environment.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ channels:
44
- conda-forge
55
dependencies:
66
- python >=3.10
7-
- biorbd >=1.12.0
7+
- biorbd >=1.12,<1.13
88
- matplotlib
99
- pyqt
1010
- pyqtgraph
1111
- python-graphviz
12-
- numpy <2.4
12+
- numpy >=2.4,<3

tests/shard1/test_global_fatigue.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ def test_fatigable_effort_torque_split(phase_dynamics):
629629
sol = ocp.solve()
630630

631631
# Check objective function value
632-
if platform.system() != "Linux":
632+
if platform.system() != "Windows":
633633
TestUtils.assert_objective_value(sol=sol, expected_value=124.09811263203727)
634634

635635
# Check constraints

tests/shard6/test_param_obj_and_scaling.py

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,18 @@
1111
from ..utils import TestUtils
1212

1313

14-
@pytest.mark.parametrize(
15-
"phase_dynamics",
16-
[
17-
PhaseDynamics.SHARED_DURING_THE_PHASE,
18-
PhaseDynamics.ONE_PER_NODE,
19-
],
20-
)
21-
@pytest.mark.parametrize(
22-
"use_sx",
23-
[
24-
True,
25-
False,
26-
],
27-
)
14+
@pytest.mark.parametrize("phase_dynamics", [PhaseDynamics.SHARED_DURING_THE_PHASE, PhaseDynamics.ONE_PER_NODE])
15+
@pytest.mark.parametrize("use_sx", [True, False])
2816
def test_example_param_obj_and_param_scaling(
2917
phase_dynamics,
3018
use_sx,
3119
):
32-
33-
if platform == "darwin" or platform == "win32":
34-
pytest.skip("This test is not working on MacOS or Windows")
35-
3620
from bioptim.examples.toy_examples.feature_examples import example_parameter_scaling as ocp_module
3721

3822
bioptim_folder = TestUtils.bioptim_folder()
3923

4024
final_time = 1
41-
n_shooting = 10
25+
n_shooting = 20
4226

4327
ocp_to_track = ocp_module.generate_dat_to_track(
4428
biorbd_model_path=bioptim_folder + "/examples/models/pendulum_wrong_gravity.bioMod",
@@ -67,7 +51,7 @@ def test_example_param_obj_and_param_scaling(
6751
sol = ocp.solve(Solver.IPOPT(show_online_optim=False))
6852

6953
# Test the objective values
70-
TestUtils.assert_objective_value(sol=sol, expected_value=35328792.2512389, decimal=4)
54+
TestUtils.assert_objective_value(sol=sol, expected_value=35479.23885709513, decimal=4)
7155

7256
g = np.array(sol.constraints)
7357
npt.assert_equal(g.shape, (0, 1))
@@ -81,11 +65,11 @@ def test_example_param_obj_and_param_scaling(
8165
npt.assert_almost_equal(qdot[:, -1], np.array([0.0, 0.0]), decimal=5)
8266

8367
npt.assert_almost_equal(q[:, 0], np.array([0.0, 0.0]), decimal=5)
84-
npt.assert_almost_equal(q[:, 5], np.array([-0.26673, 2.53154]), decimal=5)
68+
npt.assert_almost_equal(q[:, 5], np.array([-0.27469, 0.24421]), decimal=5)
8569
npt.assert_almost_equal(q[:, -1], np.array([0.0, 3.14]), decimal=5)
8670

8771
param_not_scaled = sol.decision_parameters(scaled=False)
8872
param_scaled = sol.decision_parameters(scaled=True)
8973

90-
npt.assert_almost_equal(param_not_scaled["gravity_xyz"], np.array([0.0, 3.89005766, -14.71310026]), decimal=5)
91-
npt.assert_almost_equal(param_scaled["gravity_xyz"], np.array([0.0, 3.89005766, -1.47131003]), decimal=5)
74+
npt.assert_almost_equal(param_not_scaled["gravity_xyz"], np.array([0.0, 0.01281, -5]), decimal=5)
75+
npt.assert_almost_equal(param_scaled["gravity_xyz"], np.array([0.0, 0.01281, -0.5]), decimal=5)

0 commit comments

Comments
 (0)