def test_initial_guess_update(): # Load pendulum from bioptim.examples.optimal_time_ocp import pendulum_min_time_Mayer as ocp_module bioptim_folder = os.path.dirname(ocp_module.__file__) ocp = ocp_module.prepare_ocp( biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod", final_time=2, n_shooting=10, ) np.testing.assert_almost_equal(ocp.nlp[0].x_init.init, np.zeros((4, 1))) np.testing.assert_almost_equal(ocp.nlp[0].u_init.init, np.zeros((2, 1))) idx = ocp.v.parameters_in_list.index("time") np.testing.assert_almost_equal( ocp.v.parameters_in_list[idx].initial_guess.init[0, 0], 2) np.testing.assert_almost_equal( ocp.v.init.init, np.concatenate((np.zeros( (4 * 11 + 2 * 10, 1)), [[2]]))) wrong_new_x_init = InitialGuess([1] * 6) new_x_init = InitialGuess([1] * 4) wrong_new_u_init = InitialGuess([3] * 4) new_u_init = InitialGuess([3] * 2) new_time_init = InitialGuess([4]) # No name for the param with pytest.raises( ValueError, match="update_initial_guess must specify a name for the parameters" ): ocp.update_initial_guess(new_x_init, new_u_init, new_time_init) new_time_init.name = "dumb name" with pytest.raises( ValueError, match="update_initial_guess cannot declare new parameters"): ocp.update_initial_guess(new_x_init, new_u_init, new_time_init) new_time_init.name = "time" with pytest.raises(RuntimeError): ocp.update_initial_guess(new_x_init, wrong_new_u_init, new_time_init) with pytest.raises(RuntimeError): ocp.update_initial_guess(wrong_new_x_init, wrong_new_u_init, new_time_init) ocp.update_initial_guess(new_x_init, new_u_init, new_time_init) np.testing.assert_almost_equal(ocp.nlp[0].x_init.init, np.ones((4, 1))) np.testing.assert_almost_equal(ocp.nlp[0].u_init.init, np.ones((2, 1)) * 3) idx = ocp.v.parameters_in_list.index("time") np.testing.assert_almost_equal( ocp.v.parameters_in_list[idx].initial_guess.init[0, 0], 4) np.testing.assert_almost_equal( ocp.v.init.init, np.array([[1, 1, 1, 1] * 11 + [3, 3] * 10 + [4]]).T)
def test_monophase_time_constraint(ode_solver): # Load time_constraint from bioptim.examples.optimal_time_ocp import multiphase_time_constraint as ocp_module bioptim_folder = os.path.dirname(ocp_module.__file__) ocp = ocp_module.prepare_ocp( biorbd_model_path=bioptim_folder + "/models/cube.bioMod", final_time=(2, 5, 4), time_min=[1, 3, 0.1], time_max=[2, 4, 0.8], n_shooting=(20,), ode_solver=ode_solver(), ) sol = ocp.solve() # Check objective function value f = np.array(sol.cost) np.testing.assert_equal(f.shape, (1, 1)) np.testing.assert_almost_equal(f[0, 0], 10826.61745902614) # Check constraints g = np.array(sol.constraints) if ode_solver == OdeSolver.COLLOCATION: np.testing.assert_equal(g.shape, (120 * 5 + 7, 1)) np.testing.assert_almost_equal(g, np.concatenate((np.zeros((120 * 5, 1)), np.array([[0, 0, 0, 0, 0, 0, 1]]).T))) else: np.testing.assert_equal(g.shape, (127, 1)) np.testing.assert_almost_equal(g, np.concatenate((np.zeros((126, 1)), [[1]]))) # Check some of the results q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"] tf = sol.parameters["time"][0, 0] # initial and final position np.testing.assert_almost_equal(q[:, 0], np.array((1, 0, 0))) np.testing.assert_almost_equal(q[:, -1], np.array((2, 0, 0))) # initial and final velocities np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0, 0))) np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0, 0))) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((5.71428583, 9.81, 0))) np.testing.assert_almost_equal(tau[:, -2], np.array((-5.71428583, 9.81, 0))) # optimized time np.testing.assert_almost_equal(tf, 1.0) # save and load TestUtils.save_and_load(sol, ocp, True) # simulate TestUtils.simulate(sol)
def test_simulate_from_initial_single_shoot(): # Load pendulum from bioptim.examples.getting_started import example_save_and_load as ocp_module bioptim_folder = os.path.dirname(ocp_module.__file__) ocp = ocp_module.prepare_ocp( biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod", final_time=2, n_shooting=10, n_threads=4, ) X = InitialGuess([-1, -2, 0.1, 0.2]) U = InitialGuess(np.array([[-0.1, 0], [1, 2]]).T, interpolation=InterpolationType.LINEAR) sol = Solution(ocp, [X, U]) controls = sol.controls sol = sol.integrate(shooting_type=Shooting.SINGLE_CONTINUOUS, keep_intermediate_points=True) # Check some of the results states = sol.states q, qdot, tau = states["q"], states["qdot"], controls["tau"] # initial and final position np.testing.assert_almost_equal(q[:, 0], np.array((-1.0, -2.0))) np.testing.assert_almost_equal(q[:, -1], np.array( (-0.33208579, 0.06094747))) # initial and final velocities np.testing.assert_almost_equal(qdot[:, 0], np.array((0.1, 0.2))) np.testing.assert_almost_equal(qdot[:, -1], np.array((-4.43192682, 6.38146735))) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((-0.1, 0.0))) np.testing.assert_almost_equal(tau[:, -2], np.array((0.89, 1.8)))
def test_simulate_from_initial_multiple_shoot(): from bioptim.examples.getting_started import example_save_and_load as ocp_module bioptim_folder = os.path.dirname(ocp_module.__file__) ocp = ocp_module.prepare_ocp( biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod", final_time=2, n_shooting=10, n_threads=4, ) X = InitialGuess([-1, -2, 1, 0.5]) U = InitialGuess(np.array([[-0.1, 0], [1, 2]]).T, interpolation=InterpolationType.LINEAR) sol = Solution(ocp, [X, U]) controls = sol.controls sol = sol.integrate(shooting_type=Shooting.MULTIPLE, keep_intermediate_points=True) states = sol.states # Check some of the results q, qdot, tau = states["q"], states["qdot"], controls["tau"] # initial and final position np.testing.assert_almost_equal(q[:, 0], np.array((-1.0, -2.0))) np.testing.assert_almost_equal(q[:, -1], np.array( (-0.7553692, -1.6579819))) # initial and final velocities np.testing.assert_almost_equal(qdot[:, 0], np.array((1.0, 0.5))) np.testing.assert_almost_equal(qdot[:, -1], np.array( (1.05240919, 2.864199))) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((-0.1, 0.0))) np.testing.assert_almost_equal(tau[:, -2], np.array((0.89, 1.8)))
def test_multiphase_time_constraint(ode_solver): # Load time_constraint from bioptim.examples.optimal_time_ocp import multiphase_time_constraint as ocp_module bioptim_folder = os.path.dirname(ocp_module.__file__) ocp = ocp_module.prepare_ocp( biorbd_model_path=bioptim_folder + "/models/cube.bioMod", final_time=(2, 5, 4), time_min=[1, 3, 0.1], time_max=[2, 4, 0.8], n_shooting=(20, 30, 20), ode_solver=ode_solver(), ) sol = ocp.solve() # Check objective function value f = np.array(sol.cost) np.testing.assert_equal(f.shape, (1, 1)) np.testing.assert_almost_equal(f[0, 0], 55582.04125083612) # Check constraints g = np.array(sol.constraints) if ode_solver == OdeSolver.COLLOCATION: np.testing.assert_equal(g.shape, (421 * 5 + 22, 1)) np.testing.assert_almost_equal( g, np.concatenate((np.zeros((612, 1)), [[1]], np.zeros((909, 1)), [[3]], np.zeros((603, 1)), [[0.8]])) ) else: np.testing.assert_equal(g.shape, (447, 1)) np.testing.assert_almost_equal( g, np.concatenate((np.zeros((132, 1)), [[1]], np.zeros((189, 1)), [[3]], np.zeros((123, 1)), [[0.8]])) ) # Check some of the results sol_merged = sol.merge_phases() states, controls = sol_merged.states, sol_merged.controls q, qdot, tau = states["q"], states["qdot"], controls["tau"] tf_all = sol.parameters["time"] tf = sol_merged.phase_time[1] # initial and final position np.testing.assert_almost_equal(q[:, 0], np.array((1, 0, 0))) np.testing.assert_almost_equal(q[:, -1], np.array((2, 0, 1.57))) # initial and final velocities np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0, 0))) np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0, 0))) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((5.71428583, 9.81, 0))) np.testing.assert_almost_equal(tau[:, -2], np.array((-8.92857121, 9.81, -14.01785679))) # optimized time np.testing.assert_almost_equal(tf_all.T, [[1.0, 3, 0.8]]) np.testing.assert_almost_equal(tf, np.sum(tf_all)) # save and load TestUtils.save_and_load(sol, ocp, True) # simulate TestUtils.simulate(sol)
def test_time_constraint(ode_solver): # Load time_constraint from bioptim.examples.optimal_time_ocp import time_constraint as ocp_module bioptim_folder = os.path.dirname(ocp_module.__file__) if ode_solver == OdeSolver.IRK: ft = 2 ns = 35 elif ode_solver == OdeSolver.COLLOCATION: ft = 2 ns = 15 elif ode_solver == OdeSolver.RK4: ft = 2 ns = 42 else: raise ValueError("Test not implemented") ocp = ocp_module.prepare_ocp( biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod", final_time=ft, n_shooting=ns, time_min=0.2, time_max=1, ode_solver=ode_solver(), ) sol = ocp.solve() # Check constraints g = np.array(sol.constraints) if ode_solver == OdeSolver.COLLOCATION: np.testing.assert_equal(g.shape, (ns * 20 + 1, 1)) np.testing.assert_almost_equal(g, np.concatenate((np.zeros((ns * 20, 1)), [[1]]))) else: np.testing.assert_equal(g.shape, (ns * 4 + 1, 1)) np.testing.assert_almost_equal(g, np.concatenate((np.zeros((ns * 4, 1)), [[1]]))) # Check some of the results q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"] tf = sol.parameters["time"][0, 0] # initial and final position np.testing.assert_almost_equal(q[:, 0], np.array((0, 0))) np.testing.assert_almost_equal(q[:, -1], np.array((0, 3.14))) # initial and final velocities np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0))) np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0))) # optimized time np.testing.assert_almost_equal(tf, 1.0) if ode_solver == OdeSolver.IRK: # Check objective function value f = np.array(sol.cost) np.testing.assert_equal(f.shape, (1, 1)) np.testing.assert_almost_equal(f[0, 0], 57.84641870505798) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((5.33802896, 0))) np.testing.assert_almost_equal(tau[:, -2], np.array((-23.69200381, 0))) elif ode_solver == OdeSolver.COLLOCATION: # Check objective function value f = np.array(sol.cost) np.testing.assert_equal(f.shape, (1, 1)) np.testing.assert_almost_equal(f[0, 0], 90.22986699069487) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((8.48542163, 0))) np.testing.assert_almost_equal(tau[:, -2], np.array((-18.13750096, 0))) elif ode_solver == OdeSolver.RK4: # Check objective function value f = np.array(sol.cost) np.testing.assert_equal(f.shape, (1, 1)) np.testing.assert_almost_equal(f[0, 0], 39.593354247030085) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((6.28713595, 0))) np.testing.assert_almost_equal(tau[:, -2], np.array((-12.72892599, 0))) else: raise ValueError("Test not ready") # save and load TestUtils.save_and_load(sol, ocp, True) # simulate TestUtils.simulate(sol, decimal_value=6)
def test_pendulum_min_time_mayer(ode_solver): # Load pendulum_min_time_Mayer from bioptim.examples.optimal_time_ocp import pendulum_min_time_Mayer as ocp_module bioptim_folder = os.path.dirname(ocp_module.__file__) if ode_solver == OdeSolver.IRK: ft = 2 ns = 35 elif ode_solver == OdeSolver.COLLOCATION: ft = 2 ns = 10 elif ode_solver == OdeSolver.RK4: ft = 2 ns = 30 else: raise ValueError("Test not implemented") ocp = ocp_module.prepare_ocp( biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod", final_time=ft, n_shooting=ns, ode_solver=ode_solver(), ) sol = ocp.solve() # Check objective function value f = np.array(sol.cost) np.testing.assert_equal(f.shape, (1, 1)) # Check constraints g = np.array(sol.constraints) if ode_solver == OdeSolver.COLLOCATION: np.testing.assert_equal(g.shape, (ns * 20, 1)) np.testing.assert_almost_equal(g, np.zeros((ns * 20, 1)), decimal=6) else: np.testing.assert_equal(g.shape, (ns * 4, 1)) np.testing.assert_almost_equal(g, np.zeros((ns * 4, 1)), decimal=6) # Check some of the results q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"] tf = sol.parameters["time"][0, 0] # initial and final position np.testing.assert_almost_equal(q[:, 0], np.array((0, 0))) np.testing.assert_almost_equal(q[:, -1], np.array((0, 3.14))) # initial and final velocities np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0))) np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0))) if ode_solver == OdeSolver.IRK: np.testing.assert_almost_equal(f[0, 0], 0.2855606738489079) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((87.13363409, 0)), decimal=6) np.testing.assert_almost_equal(tau[:, -2], np.array((-99.99938226, 0)), decimal=6) # optimized time np.testing.assert_almost_equal(tf, 0.2855606738489079) elif ode_solver == OdeSolver.COLLOCATION: pass elif ode_solver == OdeSolver.RK4: np.testing.assert_almost_equal(f[0, 0], 0.2862324498580764) # initial and final controls np.testing.assert_almost_equal(tau[:, 0], np.array((70.46234418, 0))) np.testing.assert_almost_equal(tau[:, -2], np.array((-99.99964325, 0))) # optimized time np.testing.assert_almost_equal(tf, 0.2862324498580764) else: raise ValueError("Test not implemented") # save and load TestUtils.save_and_load(sol, ocp, True) # simulate TestUtils.simulate(sol, decimal_value=5)
def test_pendulum_min_time_mayer_constrained(ode_solver): # Load pendulum_min_time_Mayer from bioptim.examples.optimal_time_ocp import pendulum_min_time_Mayer as ocp_module bioptim_folder = os.path.dirname(ocp_module.__file__) if ode_solver == OdeSolver.IRK: ft = 2 ns = 35 min_ft = 0.5 elif ode_solver == OdeSolver.COLLOCATION: ft = 2 ns = 10 min_ft = 0.5 elif ode_solver == OdeSolver.RK4: ft = 2 ns = 30 min_ft = 0.5 else: raise ValueError("Test not implemented") ocp = ocp_module.prepare_ocp( biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod", final_time=ft, n_shooting=ns, ode_solver=ode_solver(), min_time=min_ft, ) sol = ocp.solve() # Check constraints g = np.array(sol.constraints) if ode_solver == OdeSolver.COLLOCATION: np.testing.assert_equal(g.shape, (ns * 20, 1)) np.testing.assert_almost_equal(g, np.zeros((ns * 20, 1)), decimal=6) else: np.testing.assert_equal(g.shape, (ns * 4, 1)) np.testing.assert_almost_equal(g, np.zeros((ns * 4, 1)), decimal=6) # Check some of the results q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"] tf = sol.parameters["time"][0, 0] # initial and final position np.testing.assert_almost_equal(q[:, 0], np.array((0, 0))) np.testing.assert_almost_equal(q[:, -1], np.array((0, 3.14))) # initial and final velocities np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0))) np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0))) # Check objective function value f = np.array(sol.cost) np.testing.assert_equal(f.shape, (1, 1)) if ode_solver == OdeSolver.COLLOCATION: np.testing.assert_almost_equal(f[0, 0], 1.1878186850775596) else: np.testing.assert_almost_equal(f[0, 0], min_ft) # optimized time if ode_solver == OdeSolver.COLLOCATION: np.testing.assert_almost_equal(tf, 1.1878186850775596) else: np.testing.assert_almost_equal(tf, min_ft) # save and load TestUtils.save_and_load(sol, ocp, True) # simulate TestUtils.simulate(sol, decimal_value=6)