openscvx 0.5.3.dev33__tar.gz → 0.5.3.dev35__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openscvx-0.5.3.dev33/openscvx.egg-info → openscvx-0.5.3.dev35}/PKG-INFO +1 -1
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/_version.py +3 -3
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/optimization_results.py +18 -2
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/problem.py +90 -16
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35/openscvx.egg-info}/PKG-INFO +1 -1
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/SOURCES.txt +2 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/scm_file_list.json +2 -0
- openscvx-0.5.3.dev35/openscvx.egg-info/scm_version.json +8 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_optimization_results.py +27 -0
- openscvx-0.5.3.dev35/tests/test_post_process_batched_tau_clamp.py +104 -0
- openscvx-0.5.3.dev35/tests/test_results_parameters.py +93 -0
- openscvx-0.5.3.dev33/openscvx.egg-info/scm_version.json +0 -8
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/assets/logo.svg +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/release-drafter.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/_docs.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/branch-name.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/docs.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/lint.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/nightly.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/release-drafter.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/release.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/tests-integration.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/tests-unit.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.gitignore +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.gitmodules +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/CONTRIBUTING.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/LICENSE +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/README.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/constraint_reformulation.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/control_parameterization.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/discretization.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/ocp.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/scvx.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/time_dilation.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/batching_jit_grad.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/custom_algorithms_autotuners.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/lowering_architecture.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/00_introduction.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/05_visualization.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/06_logic.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/07_lie.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/08_mpcc.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/09_mjx_dynamics.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/favicon.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/ct-scvx_dark.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/ct-scvx_light.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/ctcs_dark.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/ctcs_light.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/problem_class_dark.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/problem_class_light.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/logo.svg +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/openscvx_logo_square.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/viser-client/index.html +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/viser-recordings/drone_racing.viser +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/viser-recordings/franka_fr3v2_pick_place.viser +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/citation.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/examples.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/index.md +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/javascripts/mathjax.js +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/versions.json +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/_viser_embed_export.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/brachistochrone.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/brachistochrone_batched.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/flappy_bird.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/hypersensitive.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/impulsive.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/stl_integer_variable.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/stl_or.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/aircraft/dynamic_soaring.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/aircraft/supersonic_time_to_climb.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/7_dof_arm.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/_camera.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/_render.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/_sensor_view.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/dr_vp_polytope.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/franka_fr3v2_pick_place.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/logo.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/3_dof_arm.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/7_dof_arm.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/7_dof_arm_collision.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/7_dof_arm_vp.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/franka_fr3v2_pick_place.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/franka_fr3v2_viewplanning.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/franka_fr3v2_viewplanning_nodal.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_disjoint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_obstacle_conditional.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_obstacle_stl.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_stl_or.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_waypoint_stl.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/double_integrator/_plotting.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/double_integrator/moving_safe_zones.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/2d_obstacle_avoidance_batched_ic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/cinema_vp.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/cinema_vp_nodal.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/dr_double_integrator.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/dr_vp.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/dr_vp_nodal.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/dr_vp_polytope.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/drone_racing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/drone_racing_batched_gates.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo_utils/acl_logo.svg +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo_utils/openscvx_logo_single.svg +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo_utils/quadrotor_mesh.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo_utils/svg_path_utils.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/multi_agent_circle_swap.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/obstacle_avoidance.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/obstacle_avoidance_nodal.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/obstacle_avoidance_vmap_2d.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/openscvx_logo.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/frax/panda_frax.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/frax/panda_frax_pick_place.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/frax/panda_frax_viewplanning.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/frax/panda_frax_waypoint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/double_cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/skydio_x2_mjx.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/triple_cartpole_3d_mjx.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/triple_cartpole_game.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/triple_cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/double_integrator_discrete.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/double_integrator_drone_racing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/dubins_car_circle_analytical.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/dubins_car_circle_discrete.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/plotting.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/plotting_viser.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/3DoF_pdg_realtime.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/6DoF_pdg_realtime.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/3DoF_pdg_realtime_base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/6DoF_pdg_realtime_base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/dubins_car_realtime_base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/cinema_vp_realtime.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/drone_racing_realtime.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/dubins_car_realtime.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/rocket/3DoF_pdg.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/rocket/6DoF_pdg.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/rocket/6DoF_pdg_batched_ic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/rocket/ascent_launch_vehicle.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/halo_orbit.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/hohmann_transfer.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/let_transfer.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/proxops_cw.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/relative_loitering.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/ctlos_cine.gif +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/ctlos_dr.gif +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/dtlos_cine.gif +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/dtlos_dr.gif +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/openscvx_logo.svg +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/openscvx_logo_square.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/oscvx_structure_full_dark.svg +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/video_preview.png +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/assets/stylesheets/custom.css +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/assets/stylesheets/home-dropin.css +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/assets/stylesheets/home-hero.css +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/assets/stylesheets/home-viser.css +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/home.html +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/main.html +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-diagram.html +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-dropin-banner.html +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-hero.html +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-pipeline.html +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-viser-strip.html +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/mkdocs.yml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/__main__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/acceptance_ratio.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/adaptive_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/augmented_lagrangian.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/constant_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/ramp_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/history.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/hyperparams.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/loop.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/penalty.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/scvx/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/scvx/iteration.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/scvx/penalized_trust_region.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/state.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/weights.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/config.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/discretize_linearize.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/linearize_discretize.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/linearize_discretize_sparse.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/sparse_utils/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/sparse_utils/bcoo_helpers.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/sparse_utils/sparse_jacobian.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/expert/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/expert/byof.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/expert/lowering.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/expert/validation.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/init/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/init/interpolation.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/init/inverse_kinematics.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/_utils.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/frax.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/menagerie.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/mjx.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrators/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrators/diffrax.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrators/runge_kutta.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/loader.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/cvxpy_constraints.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/cvxpy_variables.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/dynamics.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/jax_constraints.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/parameters.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/problem.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/unified.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/plotting.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/publication.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/scp_iteration.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/animated.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/coordinates.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/orbits.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/plotly_integration.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/primitives.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/scp.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/server.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/propagation/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/propagation/post_processing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/propagation/propagation.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/base.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/cones.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/cvxpy_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/moreau_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/ptr_solver.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/qpax_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/affine.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/augmentation.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/builder.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/canonicalize.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/constraint_set.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/arithmetic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/array.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/constraint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/control.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/expr.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/lie/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/lie/se3.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/lie/so3.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/linalg.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/logic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/math.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/parameter.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/spatial.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/state.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/stl.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/stljax.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/time.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/variable.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/vmap.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/hashing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lower.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/array.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/control.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/math.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/state.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/_registry.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/array.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/constraint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/lie.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/linalg.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/logic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/math.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/parser.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/spatial.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/stl.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/stljax.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/tokenizer.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/preprocessing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/problem.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/sparsity.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/unified.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/cache.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/caching.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/printing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/profiling.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/utils.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/dependency_links.txt +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/entry_points.txt +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/requires.txt +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/top_level.txt +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/pyproject.toml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/scripts/gen_example_pages.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/scripts/gen_ref_pages.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/scripts/mkdocs_copy_viser_client_hook.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/setup.cfg +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/_marks.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/_iteration_helpers.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/autotuner/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/autotuner/test_defaults_agreement.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/autotuner/test_hyper_overrides.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/autotuner/test_update_weights_jit.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/test_algorithm_state_pytree.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/test_iteration_fn_jit.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/test_iteration_fn_parity.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/test_make_solve_loop.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/brachistochrone_analytical.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/conftest.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/expr/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/expr/test_gmsr.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/fixtures/brachistochrone.json +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/fixtures/brachistochrone.yaml +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/hohmann_analytical.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/integrations/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/integrations/test_mjx.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/integrations/test_mjx_dynamics.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/_iteration_callback_helpers.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_cvxpy_callback_jit_spike.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_iteration_callback_cvxpy.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_iteration_callback_moreau.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_iteration_callback_qpax.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_iteration_callback_vmap.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_moreau_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_qpax_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_subproblem_pytree.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_arithmetic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_array.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_constraint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_expr.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_lie.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_linalg.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_logic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_math.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_node_reference.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_parameters.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_scaling.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_spatial.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_stl.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_variable.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_vmap.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/__init__.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_array.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_constraint.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_lie.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_linalg.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_load.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_logic.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_math.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_parser.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_spatial.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_stl.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_tokenizer.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_vmap.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_augmentation.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_hashing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_lower_cvxpy.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_lower_jax.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_preprocessing.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_sparsity.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_unified.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_autotuning.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_cvxpygen_optional.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_discretization.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_examples.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_expert.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_impulsive.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_init.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_integrators.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_loader.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_multishot_propagation.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_plotting.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_propagation.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_batched_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_batched_cvxpy_export_errors.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_batched_export_roundtrip.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_batched_inference.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_jax_bare_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_jax_jit_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_jax_vmap_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_jax_vmap_converged_no_drift.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openscvx
|
|
3
|
-
Version: 0.5.3.
|
|
3
|
+
Version: 0.5.3.dev35
|
|
4
4
|
Summary: A general Python-based successive convexification implementation which uses a JAX backend.
|
|
5
5
|
Author-email: Chris Hayner and Griffin Norris <haynec@uw.edu>
|
|
6
6
|
License: Apache Software License
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.5.3.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 5, 3, '
|
|
21
|
+
__version__ = version = '0.5.3.dev35'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 5, 3, 'dev35')
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g43f7b7f31'
|
|
@@ -50,6 +50,14 @@ class OptimizationResults:
|
|
|
50
50
|
Added by propagate_trajectory_results.
|
|
51
51
|
ctcs_violation (Optional[np.ndarray]): Continuous-time constraint violations.
|
|
52
52
|
Added by propagate_trajectory_results.
|
|
53
|
+
parameters (dict[str, np.ndarray]): Parameter values the solve used, recorded
|
|
54
|
+
by :meth:`~openscvx.problem.Problem.solve` and
|
|
55
|
+
:meth:`~openscvx.problem.Problem.solve_batched` (batched solves store every
|
|
56
|
+
value with a leading ``(B,)`` axis, shared values replicated). Results
|
|
57
|
+
record what happened: post-processing propagates with these values, and
|
|
58
|
+
the Problem's parameter dict only seeds the next solve. Empty when no
|
|
59
|
+
snapshot was recorded (e.g. ``solve_jax``, whose callers manage
|
|
60
|
+
parameters themselves).
|
|
53
61
|
plotting_data (dict[str, Any]): Flexible storage for plotting and application data.
|
|
54
62
|
|
|
55
63
|
!!! note "JAX pytree registration"
|
|
@@ -59,8 +67,9 @@ class OptimizationResults:
|
|
|
59
67
|
``converged``, ``t_final``, ``nodes``, ``trajectory``, ``X``, ``U``,
|
|
60
68
|
and every ``*_history`` field — the data the user actually consumes.
|
|
61
69
|
Post-process fields (``t_full``, ``x_full``, ``u_full``, ``cost``,
|
|
62
|
-
``ctcs_violation``), ``plotting_data``, and the
|
|
63
|
-
``_controls`` metadata are stashed in the
|
|
70
|
+
``ctcs_violation``), ``parameters``, ``plotting_data``, and the
|
|
71
|
+
internal ``_states`` / ``_controls`` metadata are stashed in the
|
|
72
|
+
treedef's *aux* instead, so
|
|
64
73
|
a batched ``solve_jax`` doesn't force callers to handle ``None``
|
|
65
74
|
leaves and ``post_process()`` outputs stay outside the vmap surface
|
|
66
75
|
(post-process per element after the batched solve).
|
|
@@ -217,6 +226,10 @@ class OptimizationResults:
|
|
|
217
226
|
cost: Optional[float] = field(default=None, metadata={"npz": "optional_scalar"})
|
|
218
227
|
ctcs_violation: Optional[np.ndarray] = field(default=None, metadata={"npz": "optional_array"})
|
|
219
228
|
|
|
229
|
+
# Parameter values the solve used (recorded by Problem.solve() /
|
|
230
|
+
# Problem.solve_batched(); empty when nothing was recorded)
|
|
231
|
+
parameters: dict[str, np.ndarray] = field(default_factory=dict, metadata={"npz": "dict"})
|
|
232
|
+
|
|
220
233
|
# Additional plotting/application data (added by user)
|
|
221
234
|
plotting_data: dict[str, Any] = field(default_factory=dict, metadata={"npz": "dict"})
|
|
222
235
|
|
|
@@ -245,6 +258,7 @@ class OptimizationResults:
|
|
|
245
258
|
self.u_full,
|
|
246
259
|
self.cost,
|
|
247
260
|
self.ctcs_violation,
|
|
261
|
+
self.parameters,
|
|
248
262
|
self.plotting_data,
|
|
249
263
|
)
|
|
250
264
|
return children, aux
|
|
@@ -260,6 +274,7 @@ class OptimizationResults:
|
|
|
260
274
|
u_full,
|
|
261
275
|
cost,
|
|
262
276
|
ctcs_violation,
|
|
277
|
+
parameters,
|
|
263
278
|
plotting_data,
|
|
264
279
|
) = aux
|
|
265
280
|
return cls(
|
|
@@ -271,6 +286,7 @@ class OptimizationResults:
|
|
|
271
286
|
u_full=u_full,
|
|
272
287
|
cost=cost,
|
|
273
288
|
ctcs_violation=ctcs_violation,
|
|
289
|
+
parameters=parameters,
|
|
274
290
|
plotting_data=plotting_data,
|
|
275
291
|
)
|
|
276
292
|
|
|
@@ -23,6 +23,7 @@ import os
|
|
|
23
23
|
import queue
|
|
24
24
|
import threading
|
|
25
25
|
import time
|
|
26
|
+
import warnings
|
|
26
27
|
from dataclasses import fields as dc_fields
|
|
27
28
|
from dataclasses import replace as dc_replace
|
|
28
29
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
@@ -62,7 +63,11 @@ from openscvx.lowered.jax_constraints import (
|
|
|
62
63
|
LoweredJaxConstraints,
|
|
63
64
|
LoweredNodalConstraint,
|
|
64
65
|
)
|
|
65
|
-
from openscvx.propagation import
|
|
66
|
+
from openscvx.propagation import (
|
|
67
|
+
get_propagation_solver,
|
|
68
|
+
propagate_trajectory_results,
|
|
69
|
+
s_to_t,
|
|
70
|
+
)
|
|
66
71
|
from openscvx.solvers import ConvexSolver, resolve_solver_config
|
|
67
72
|
from openscvx.symbolic.builder import preprocess_symbolic_problem
|
|
68
73
|
from openscvx.symbolic.expr import CTCS, Constraint
|
|
@@ -672,6 +677,7 @@ class Problem:
|
|
|
672
677
|
# Final solution state (saved after successful solve)
|
|
673
678
|
self._solution: Optional[AlgorithmState] = None
|
|
674
679
|
self._solution_history: Optional[AlgorithmHistory] = None
|
|
680
|
+
self._solution_parameters: Optional[Dict[str, np.ndarray]] = None
|
|
675
681
|
|
|
676
682
|
# SCP algorithm (resolved from `algorithm` parameter above)
|
|
677
683
|
|
|
@@ -1287,6 +1293,7 @@ class Problem:
|
|
|
1287
1293
|
# Reset solution
|
|
1288
1294
|
self._solution = None
|
|
1289
1295
|
self._solution_history = None
|
|
1296
|
+
self._solution_parameters = None
|
|
1290
1297
|
|
|
1291
1298
|
# Reset timing
|
|
1292
1299
|
self.timing_solve = None
|
|
@@ -1355,7 +1362,10 @@ class Problem:
|
|
|
1355
1362
|
|
|
1356
1363
|
Returns:
|
|
1357
1364
|
OptimizationResults with trajectory and convergence info
|
|
1358
|
-
(call post_process() for full propagation)
|
|
1365
|
+
(call post_process() for full propagation). The parameter
|
|
1366
|
+
values used for the solve are recorded on
|
|
1367
|
+
``results.parameters``; :meth:`post_process` propagates
|
|
1368
|
+
with them.
|
|
1359
1369
|
"""
|
|
1360
1370
|
# Sync parameters, boundary conditions, and SCP constants before solving
|
|
1361
1371
|
self._sync_parameters()
|
|
@@ -1408,16 +1418,22 @@ class Problem:
|
|
|
1408
1418
|
|
|
1409
1419
|
profiling.profiling_end(pr, "solve")
|
|
1410
1420
|
|
|
1411
|
-
# Snapshot state
|
|
1421
|
+
# Snapshot state, history, and parameters for post_process() / plotting
|
|
1422
|
+
# reuse.
|
|
1412
1423
|
self._solution = self._state
|
|
1413
1424
|
self._solution_history = copy.deepcopy(self._history)
|
|
1425
|
+
self._solution_parameters = {
|
|
1426
|
+
name: np.array(value) for name, value in self._parameters.items()
|
|
1427
|
+
}
|
|
1414
1428
|
|
|
1415
1429
|
timed_out = t_max is not None and self.timing_solve >= t_max
|
|
1416
|
-
|
|
1430
|
+
result = self._format_result(
|
|
1417
1431
|
self._state,
|
|
1418
1432
|
self._history,
|
|
1419
1433
|
int(self._state.k) <= k_max and not timed_out,
|
|
1420
1434
|
)
|
|
1435
|
+
result.parameters = self._solution_parameters
|
|
1436
|
+
return result
|
|
1421
1437
|
|
|
1422
1438
|
def _default_state(self) -> AlgorithmState:
|
|
1423
1439
|
"""Fresh :class:`AlgorithmState` from settings and the algorithm's SCP constants.
|
|
@@ -1665,6 +1681,11 @@ class Problem:
|
|
|
1665
1681
|
parameters: Problem parameters dict for the current solve. Use
|
|
1666
1682
|
this rather than mutating ``self.parameters`` if the
|
|
1667
1683
|
parameters are traced. ``None`` reuses ``self._parameters``.
|
|
1684
|
+
Unlike :meth:`solve` / :meth:`solve_batched`, the merged
|
|
1685
|
+
values are *not* recorded on the returned results — under a
|
|
1686
|
+
caller's ``jit`` / ``vmap`` they are tracers, which must not
|
|
1687
|
+
leak into the pytree's aux — so callers that post-process
|
|
1688
|
+
manage parameter bookkeeping themselves.
|
|
1668
1689
|
x_guess: Initial state trajectory guess, shape ``(N, n_states)``.
|
|
1669
1690
|
Replaces ``state.x``; ``None`` uses the default from
|
|
1670
1691
|
settings (``State.guess`` at ``initialize()``).
|
|
@@ -1846,7 +1867,12 @@ class Problem:
|
|
|
1846
1867
|
|
|
1847
1868
|
Returns:
|
|
1848
1869
|
:class:`OptimizationResults` pytree with a leading ``B`` axis on
|
|
1849
|
-
every leaf and empty per-iteration histories.
|
|
1870
|
+
every leaf and empty per-iteration histories. The merged
|
|
1871
|
+
parameter values used for the solve are recorded on
|
|
1872
|
+
``results.parameters``, post-broadcast — every value carries the
|
|
1873
|
+
leading ``(B,)`` axis, shared values replicated — and
|
|
1874
|
+
:meth:`post_process_batched` propagates each element with its
|
|
1875
|
+
own values.
|
|
1850
1876
|
"""
|
|
1851
1877
|
if self._iteration_fn_jit_inner is None:
|
|
1852
1878
|
raise ValueError(
|
|
@@ -1953,7 +1979,16 @@ class Problem:
|
|
|
1953
1979
|
final_states = batched_solve(states, params_for_solve)
|
|
1954
1980
|
jax.block_until_ready(final_states)
|
|
1955
1981
|
self.timing_solve = time.time() - t_0_solve
|
|
1956
|
-
|
|
1982
|
+
results = OptimizationResults.from_final_state(final_states, problem=self)
|
|
1983
|
+
# Record the as-used parameter values with a leading (B,) axis on
|
|
1984
|
+
# every leaf, so post_process_batched() can index element b directly.
|
|
1985
|
+
results.parameters = {
|
|
1986
|
+
name: np.array(np.moveaxis(np.asarray(value), param_axes[name], 0))
|
|
1987
|
+
if param_axes[name] is not None
|
|
1988
|
+
else np.broadcast_to(np.asarray(value), (B,) + np.shape(value)).copy()
|
|
1989
|
+
for name, value in params_for_solve.items()
|
|
1990
|
+
}
|
|
1991
|
+
return results
|
|
1957
1992
|
|
|
1958
1993
|
def post_process(self) -> OptimizationResults:
|
|
1959
1994
|
"""Propagate solution through full nonlinear dynamics for high-fidelity trajectory.
|
|
@@ -1961,6 +1996,10 @@ class Problem:
|
|
|
1961
1996
|
Integrates the converged SCP solution through the nonlinear dynamics to
|
|
1962
1997
|
produce x_full, u_full, and t_full. Call after solve() for final results.
|
|
1963
1998
|
|
|
1999
|
+
Propagation uses the parameter values recorded at solve time
|
|
2000
|
+
(``results.parameters``), so mutating ``self.parameters`` between
|
|
2001
|
+
:meth:`solve` and here only seeds the next solve.
|
|
2002
|
+
|
|
1964
2003
|
Returns:
|
|
1965
2004
|
OptimizationResults with propagated trajectory fields
|
|
1966
2005
|
|
|
@@ -1980,9 +2019,11 @@ class Problem:
|
|
|
1980
2019
|
int(self._solution.k) <= self._algorithm.k_max,
|
|
1981
2020
|
)
|
|
1982
2021
|
|
|
2022
|
+
result.parameters = self._solution_parameters
|
|
2023
|
+
|
|
1983
2024
|
t_0_post = time.time()
|
|
1984
2025
|
result = propagate_trajectory_results(
|
|
1985
|
-
self.
|
|
2026
|
+
self._solution_parameters,
|
|
1986
2027
|
self.settings,
|
|
1987
2028
|
result,
|
|
1988
2029
|
self._propagation_solver,
|
|
@@ -2022,9 +2063,11 @@ class Problem:
|
|
|
2022
2063
|
- ``results.cost`` — ``(B,)``
|
|
2023
2064
|
- ``results.ctcs_violation`` — ``(B, ...)`` or ``None``
|
|
2024
2065
|
|
|
2025
|
-
Propagation runs sequentially over the batch in a Python loop;
|
|
2026
|
-
|
|
2027
|
-
|
|
2066
|
+
Propagation runs sequentially over the batch in a Python loop; each
|
|
2067
|
+
element propagates with its own parameter values from the snapshot
|
|
2068
|
+
:meth:`solve_batched` recorded on ``results.parameters``. Results
|
|
2069
|
+
without a snapshot (e.g. loaded from an older save) fall back to
|
|
2070
|
+
``self.parameters`` with a warning.
|
|
2028
2071
|
|
|
2029
2072
|
Args:
|
|
2030
2073
|
results: Batched :class:`~openscvx.algorithms.OptimizationResults`
|
|
@@ -2035,7 +2078,12 @@ class Problem:
|
|
|
2035
2078
|
``ceil(T_max / settings.prp.dt) + 1`` where ``T_max`` is the
|
|
2036
2079
|
longest terminal time across the batch. All ``B`` elements are
|
|
2037
2080
|
interpolated to the **same** ``n_times`` so the output arrays
|
|
2038
|
-
have uniform shape.
|
|
2081
|
+
have uniform shape. The requested (or default) value is capped
|
|
2082
|
+
so no single segment of any element receives more dense samples
|
|
2083
|
+
than the propagation solver's compiled per-segment capacity
|
|
2084
|
+
(``settings.prp.max_tau_len``); the cap binds on the largest
|
|
2085
|
+
segment-duration fraction across the batch, so trajectories with
|
|
2086
|
+
near-uniform segments are left untouched.
|
|
2039
2087
|
|
|
2040
2088
|
Returns:
|
|
2041
2089
|
The same ``results`` object with ``t_full``, ``x_full``, ``u_full``,
|
|
@@ -2056,10 +2104,24 @@ class Problem:
|
|
|
2056
2104
|
n_times = max(int(np.ceil(T_max / self.settings.prp.dt)) + 1, 2)
|
|
2057
2105
|
|
|
2058
2106
|
# The propagation solver is compiled with a per-segment tau capacity of
|
|
2059
|
-
# ``max_tau_len
|
|
2060
|
-
# ``
|
|
2061
|
-
#
|
|
2062
|
-
|
|
2107
|
+
# ``max_tau_len`` — the *per-segment* buffer width, not a total-point
|
|
2108
|
+
# budget. A uniform ``linspace`` grid over an element's real time span
|
|
2109
|
+
# drops about ``(n_times - 1) * seg_dur / span`` points into each
|
|
2110
|
+
# segment, so the binding quantity is the largest segment-duration
|
|
2111
|
+
# fraction across the batch, not the total point count. Bound
|
|
2112
|
+
# ``n_times`` so the busiest segment of any element — plus the endpoint
|
|
2113
|
+
# sample ``simulate_nonlinear_time`` appends — stays within
|
|
2114
|
+
# ``max_tau_len``:
|
|
2115
|
+
# (n_times - 1) * frac_max + 2 <= max_tau_len.
|
|
2116
|
+
u_batch = np.asarray(results.U[-1]) # (B, N, n_u)
|
|
2117
|
+
frac_max = 0.0
|
|
2118
|
+
for b in range(B):
|
|
2119
|
+
t_b = np.asarray(
|
|
2120
|
+
s_to_t(x_batch[b], u_batch[b], self.settings, self._discretizer)
|
|
2121
|
+
).reshape(-1)
|
|
2122
|
+
frac_max = max(frac_max, float(np.diff(t_b).max() / (t_b[-1] - t_b[0])))
|
|
2123
|
+
per_segment_bound = max(int((self.settings.prp.max_tau_len - 2) / frac_max) + 1, 2)
|
|
2124
|
+
n_times = min(n_times, per_segment_bound)
|
|
2063
2125
|
|
|
2064
2126
|
t_fulls: List[np.ndarray] = []
|
|
2065
2127
|
x_fulls: List[np.ndarray] = []
|
|
@@ -2068,11 +2130,23 @@ class Problem:
|
|
|
2068
2130
|
costs: List[float] = []
|
|
2069
2131
|
ctcs_violations = []
|
|
2070
2132
|
|
|
2133
|
+
# Empty for results saved before the snapshot existed — those fall
|
|
2134
|
+
# back to the Problem's current values, the pre-snapshot behaviour.
|
|
2135
|
+
snapshot = getattr(results, "parameters", None) or {}
|
|
2136
|
+
if not snapshot and self._parameters:
|
|
2137
|
+
warnings.warn(
|
|
2138
|
+
"results carry no record of the parameter values they were solved "
|
|
2139
|
+
"with; propagating every element with the Problem's current "
|
|
2140
|
+
"parameters, which may differ from the solved values.",
|
|
2141
|
+
UserWarning,
|
|
2142
|
+
stacklevel=2,
|
|
2143
|
+
)
|
|
2144
|
+
|
|
2071
2145
|
t_0_post = time.time()
|
|
2072
2146
|
for b in range(B):
|
|
2073
2147
|
single = _make_single_result(results, b)
|
|
2074
2148
|
prop = propagate_trajectory_results(
|
|
2075
|
-
self._parameters,
|
|
2149
|
+
dict(self._parameters, **{k: np.asarray(v)[b] for k, v in snapshot.items()}),
|
|
2076
2150
|
self.settings,
|
|
2077
2151
|
single,
|
|
2078
2152
|
self._propagation_solver,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openscvx
|
|
3
|
-
Version: 0.5.3.
|
|
3
|
+
Version: 0.5.3.dev35
|
|
4
4
|
Summary: A general Python-based successive convexification implementation which uses a JAX backend.
|
|
5
5
|
Author-email: Chris Hayner and Griffin Norris <haynec@uw.edu>
|
|
6
6
|
License: Apache Software License
|
|
@@ -354,7 +354,9 @@ tests/test_loader.py
|
|
|
354
354
|
tests/test_multishot_propagation.py
|
|
355
355
|
tests/test_optimization_results.py
|
|
356
356
|
tests/test_plotting.py
|
|
357
|
+
tests/test_post_process_batched_tau_clamp.py
|
|
357
358
|
tests/test_propagation.py
|
|
359
|
+
tests/test_results_parameters.py
|
|
358
360
|
tests/test_solve_batched_brachistochrone.py
|
|
359
361
|
tests/test_solve_batched_cvxpy_export_errors.py
|
|
360
362
|
tests/test_solve_batched_export_roundtrip.py
|
|
@@ -220,6 +220,8 @@
|
|
|
220
220
|
"tests/test_propagation.py",
|
|
221
221
|
"tests/hohmann_analytical.py",
|
|
222
222
|
"tests/test_expert.py",
|
|
223
|
+
"tests/test_results_parameters.py",
|
|
224
|
+
"tests/test_post_process_batched_tau_clamp.py",
|
|
223
225
|
"tests/test_solve_batched_inference.py",
|
|
224
226
|
"tests/test_solve_jax_bare_brachistochrone.py",
|
|
225
227
|
"tests/test_cvxpygen_optional.py",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Tests for OptimizationResults save/load round-trip."""
|
|
2
2
|
|
|
3
|
+
import jax
|
|
3
4
|
import numpy as np
|
|
4
5
|
import pytest
|
|
5
6
|
|
|
@@ -184,3 +185,29 @@ def test_plotting_data_skips_non_array(tmp_path):
|
|
|
184
185
|
loaded = OptimizationResults.load(path)
|
|
185
186
|
np.testing.assert_array_equal(loaded.plotting_data["good"], np.array([1, 2, 3]))
|
|
186
187
|
assert "bad_func" not in loaded.plotting_data
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def test_save_load_roundtrip_parameters(tmp_path):
|
|
191
|
+
"""The recorded parameter snapshot survives a save/load round-trip."""
|
|
192
|
+
original = _make_result()
|
|
193
|
+
original.parameters = {"gain": np.array([2.0]), "center": np.array([1.0, 2.0, 3.0])}
|
|
194
|
+
path = tmp_path / "with_parameters.npz"
|
|
195
|
+
original.save(path)
|
|
196
|
+
|
|
197
|
+
loaded = OptimizationResults.load(path)
|
|
198
|
+
assert set(loaded.parameters) == set(original.parameters)
|
|
199
|
+
for key, value in original.parameters.items():
|
|
200
|
+
np.testing.assert_array_equal(loaded.parameters[key], value)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def test_parameters_snapshot_is_pytree_aux_not_child():
|
|
204
|
+
"""The parameter snapshot rides the treedef's aux, leaving the children unchanged."""
|
|
205
|
+
result = _make_result()
|
|
206
|
+
n_leaves = len(jax.tree_util.tree_leaves(result))
|
|
207
|
+
|
|
208
|
+
result.parameters = {"gain": np.array([2.0])}
|
|
209
|
+
leaves, treedef = jax.tree_util.tree_flatten(result)
|
|
210
|
+
assert len(leaves) == n_leaves # no new pytree children
|
|
211
|
+
|
|
212
|
+
restored = jax.tree_util.tree_unflatten(treedef, leaves)
|
|
213
|
+
np.testing.assert_array_equal(restored.parameters["gain"], np.array([2.0]))
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""``post_process_batched`` sizes its dense grid per-segment, not per-total.
|
|
2
|
+
|
|
3
|
+
The propagation solver is compiled with a *per-segment* tau buffer of width
|
|
4
|
+
``settings.prp.max_tau_len``. ``post_process_batched`` used to clamp the
|
|
5
|
+
*total* number of dense output points to that per-segment width, collapsing
|
|
6
|
+
trajectories that would otherwise carry hundreds of samples down to a handful.
|
|
7
|
+
These tests pin the fixed behaviour: the dense grid may far exceed
|
|
8
|
+
``max_tau_len`` in total, yet no single segment of any batch element ever
|
|
9
|
+
overfills the per-segment buffer.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import jax.numpy as jnp
|
|
13
|
+
import numpy as np
|
|
14
|
+
import pytest
|
|
15
|
+
|
|
16
|
+
from openscvx.propagation import s_to_t
|
|
17
|
+
from tests.solvers._iteration_callback_helpers import build_brachistochrone
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _x_initial_stack(prob, shifts=(0.0, 0.3, -0.3)):
|
|
21
|
+
"""Stack a few initial pins by shifting the starting x-coordinate."""
|
|
22
|
+
default_pin = prob.state.x_init_pin
|
|
23
|
+
return jnp.stack([default_pin.at[0].set(default_pin[0] + s) for s in shifts])
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _worst_segment_occupancy(prob, results):
|
|
27
|
+
"""Largest per-segment dense-sample count across the batch.
|
|
28
|
+
|
|
29
|
+
Mirrors the binning ``simulate_nonlinear_time`` performs: each dense time
|
|
30
|
+
falls into the node-time segment ``[t_nodal[k], t_nodal[k + 1])``. Returns
|
|
31
|
+
the maximum count over all segments and all batch elements.
|
|
32
|
+
"""
|
|
33
|
+
x_batch = np.asarray(results.X[-1])
|
|
34
|
+
u_batch = np.asarray(results.U[-1])
|
|
35
|
+
worst = 0
|
|
36
|
+
for b in range(x_batch.shape[0]):
|
|
37
|
+
t_nodal = np.asarray(
|
|
38
|
+
s_to_t(x_batch[b], u_batch[b], prob.settings, prob._discretizer)
|
|
39
|
+
).reshape(-1)
|
|
40
|
+
seg = np.clip(
|
|
41
|
+
np.searchsorted(t_nodal, results.t_full[b], side="right") - 1,
|
|
42
|
+
0,
|
|
43
|
+
len(t_nodal) - 2,
|
|
44
|
+
)
|
|
45
|
+
counts = np.bincount(seg, minlength=len(t_nodal) - 1)
|
|
46
|
+
worst = max(worst, int(counts.max()))
|
|
47
|
+
return worst
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# === Dense grid is sized by the total, capped only per-segment ===
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_batched_dense_grid_exceeds_per_segment_capacity():
|
|
54
|
+
"""The default grid carries far more total points than one segment holds.
|
|
55
|
+
|
|
56
|
+
``ceil(T_max / prp.dt) + 1`` comfortably exceeds ``max_tau_len`` here, and
|
|
57
|
+
with near-uniform segments each segment stays well within the per-segment
|
|
58
|
+
buffer — so the total-count clamp was pure loss. Before the fix the dense
|
|
59
|
+
grid came out at exactly ``max_tau_len`` samples.
|
|
60
|
+
"""
|
|
61
|
+
pytest.importorskip("qpax")
|
|
62
|
+
|
|
63
|
+
prob = build_brachistochrone("qpax", n=8, k_max=20)
|
|
64
|
+
prob.initialize()
|
|
65
|
+
max_tau_len = prob.settings.prp.max_tau_len
|
|
66
|
+
|
|
67
|
+
batched = prob.solve_batched(x_initial=_x_initial_stack(prob))
|
|
68
|
+
results = prob.post_process_batched(batched)
|
|
69
|
+
|
|
70
|
+
# The dense grid dwarfs the per-segment buffer — the old clamp would have
|
|
71
|
+
# pinned it to exactly ``max_tau_len``.
|
|
72
|
+
assert results.t_full.shape[-1] > max_tau_len
|
|
73
|
+
# ...and the per-segment safety still holds: nothing overfills the buffer.
|
|
74
|
+
assert _worst_segment_occupancy(prob, results) + 1 <= max_tau_len
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# === Per-segment capacity is still enforced ===
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_batched_large_n_times_request_is_clamped_to_per_segment_capacity():
|
|
81
|
+
"""An absurd explicit ``n_times`` is capped, and no segment overfills.
|
|
82
|
+
|
|
83
|
+
Requesting far more points than the per-segment buffer could ever absorb
|
|
84
|
+
forces the bound to bind. A naive ``linspace`` of this size would drop
|
|
85
|
+
thousands of samples into each segment and blow past ``max_tau_len`` — the
|
|
86
|
+
propagation solver would crash on the negative pad. The per-segment-aware
|
|
87
|
+
bound reduces ``n_times`` just enough that every segment fits, so the call
|
|
88
|
+
both returns a smaller grid and completes without error.
|
|
89
|
+
"""
|
|
90
|
+
pytest.importorskip("qpax")
|
|
91
|
+
|
|
92
|
+
prob = build_brachistochrone("qpax", n=8, k_max=20)
|
|
93
|
+
prob.initialize()
|
|
94
|
+
max_tau_len = prob.settings.prp.max_tau_len
|
|
95
|
+
|
|
96
|
+
batched = prob.solve_batched(x_initial=_x_initial_stack(prob))
|
|
97
|
+
huge = 100_000
|
|
98
|
+
results = prob.post_process_batched(batched, n_times=huge)
|
|
99
|
+
|
|
100
|
+
# The request was clamped well below what was asked for...
|
|
101
|
+
assert results.t_full.shape[-1] < huge
|
|
102
|
+
# ...precisely so that the busiest segment plus its endpoint sample stays
|
|
103
|
+
# within the compiled per-segment buffer.
|
|
104
|
+
assert _worst_segment_occupancy(prob, results) + 1 <= max_tau_len
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Solved parameter values are recorded on results and drive post-processing.
|
|
2
|
+
|
|
3
|
+
``Problem.solve`` and ``Problem.solve_batched`` snapshot the merged, as-used
|
|
4
|
+
parameter values onto ``results.parameters``; ``post_process`` /
|
|
5
|
+
``post_process_batched`` propagate with the recorded values, so mutating
|
|
6
|
+
``problem.parameters`` between solve and post-process — or batching a
|
|
7
|
+
parameter that enters the dynamics — can no longer corrupt the dense
|
|
8
|
+
trajectory. The fixture's ``gain`` parameter scales the position kinematics,
|
|
9
|
+
which makes a wrong propagation parameter directly visible: gain 0 freezes
|
|
10
|
+
the dense positions, gain 1 moves them.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import jax
|
|
14
|
+
import jax.numpy as jnp
|
|
15
|
+
import numpy as np
|
|
16
|
+
import pytest
|
|
17
|
+
|
|
18
|
+
from tests.test_solve_batched_brachistochrone import _build_brachistochrone_with_params
|
|
19
|
+
|
|
20
|
+
# === solve() -> post_process() ===
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_post_process_propagates_with_solved_parameters():
|
|
24
|
+
prob = _build_brachistochrone_with_params("cvxpy", n=8, k_max=20)
|
|
25
|
+
prob.initialize()
|
|
26
|
+
result = prob.solve()
|
|
27
|
+
|
|
28
|
+
# The solve records the as-used values as plain numpy.
|
|
29
|
+
np.testing.assert_array_equal(result.parameters["gain"], np.array([1.0]))
|
|
30
|
+
|
|
31
|
+
# Mutating the Problem's parameters afterwards only seeds the next solve;
|
|
32
|
+
# post-processing propagates with the recorded gain of 1.0. Under gain 0
|
|
33
|
+
# the position kinematics would be identically zero.
|
|
34
|
+
prob.parameters["gain"] = np.array([0.0])
|
|
35
|
+
result = prob.post_process()
|
|
36
|
+
|
|
37
|
+
np.testing.assert_array_equal(result.parameters["gain"], np.array([1.0]))
|
|
38
|
+
position = np.asarray(result.trajectory["position"]) # (n_times, 2)
|
|
39
|
+
assert np.ptp(position[:, 0]) > 5.0 # moved from [0, 10] toward [10, 5]
|
|
40
|
+
|
|
41
|
+
jax.clear_caches()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# === solve_batched() -> post_process_batched() ===
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_post_process_batched_propagates_each_element_with_its_own_parameters():
|
|
48
|
+
pytest.importorskip("qpax")
|
|
49
|
+
|
|
50
|
+
prob = _build_brachistochrone_with_params("qpax", n=8, k_max=5)
|
|
51
|
+
prob.initialize()
|
|
52
|
+
|
|
53
|
+
gains = jnp.array([[0.0], [1.0]]) # (B, 1) vs declared (1,) -> batched
|
|
54
|
+
results = prob.solve_batched(parameters={"gain": gains})
|
|
55
|
+
|
|
56
|
+
# Post-broadcast snapshot: every value carries the leading (B,) axis,
|
|
57
|
+
# the shared gravity replicated.
|
|
58
|
+
np.testing.assert_allclose(np.asarray(results.parameters["gain"]), np.asarray(gains))
|
|
59
|
+
np.testing.assert_allclose(
|
|
60
|
+
np.asarray(results.parameters["gravity"]), np.broadcast_to([9.81], (2, 1))
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
results = prob.post_process_batched(results)
|
|
64
|
+
position = np.asarray(results.trajectory["position"]) # (B, n_times, 2)
|
|
65
|
+
|
|
66
|
+
# Element 0 solved with gain 0 and must propagate with gain 0: its
|
|
67
|
+
# position kinematics are identically zero, so the dense trajectory
|
|
68
|
+
# stays at the initial point. Element 1 (gain 1) moves.
|
|
69
|
+
assert np.abs(position[0] - position[0, 0]).max() < 1e-6
|
|
70
|
+
assert np.ptp(position[1, :, 0]) > 1.0
|
|
71
|
+
|
|
72
|
+
jax.clear_caches()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_post_process_batched_without_snapshot_falls_back_to_problem_parameters():
|
|
76
|
+
pytest.importorskip("qpax")
|
|
77
|
+
|
|
78
|
+
prob = _build_brachistochrone_with_params("qpax", n=8, k_max=5)
|
|
79
|
+
prob.initialize()
|
|
80
|
+
|
|
81
|
+
results = prob.solve_batched(parameters={"gain": jnp.array([[0.0], [1.0]])})
|
|
82
|
+
del results.parameters # a results object that predates the snapshot
|
|
83
|
+
|
|
84
|
+
with pytest.warns(UserWarning, match="no record of the parameter values"):
|
|
85
|
+
results = prob.post_process_batched(results)
|
|
86
|
+
position = np.asarray(results.trajectory["position"])
|
|
87
|
+
|
|
88
|
+
# Every element falls back to the Problem's own gain of 1.0: even the
|
|
89
|
+
# element solved with gain 0 moves during propagation.
|
|
90
|
+
for b in range(2):
|
|
91
|
+
assert np.ptp(position[b, :, 0]) > 0.5
|
|
92
|
+
|
|
93
|
+
jax.clear_caches()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/custom_algorithms_autotuners.md
RENAMED
|
File without changes
|
|
File without changes
|
{openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/vectorization_and_vmapping.md
RENAMED
|
File without changes
|
|
File without changes
|
{openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/01_hello_world_brachistochrone.md
RENAMED
|
File without changes
|