openscvx 0.5.3.dev15__tar.gz → 0.5.3.dev17__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.dev15/openscvx.egg-info → openscvx-0.5.3.dev17}/PKG-INFO +1 -1
- openscvx-0.5.3.dev17/docs/UnderTheHood/batching_jit_grad.md +134 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UnderTheHood/lowering_architecture.md +23 -8
- openscvx-0.5.3.dev17/examples/abstract/brachistochrone_batched.py +126 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/mkdocs.yml +2 -1
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/_version.py +3 -3
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/base.py +39 -7
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/optimization_results.py +233 -1
- openscvx-0.5.3.dev17/openscvx/algorithms/scvx/iteration.py +386 -0
- openscvx-0.5.3.dev17/openscvx/algorithms/scvx/penalized_trust_region.py +330 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/problem.py +191 -96
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/solvers/cvxpy_ptr_solver.py +33 -2
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/solvers/moreau_ptr_solver.py +16 -3
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/solvers/qpax_ptr_solver.py +37 -26
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/utils/caching.py +25 -17
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17/openscvx.egg-info}/PKG-INFO +1 -1
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx.egg-info/SOURCES.txt +11 -0
- openscvx-0.5.3.dev17/tests/algorithms/_iteration_helpers.py +27 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/algorithms/autotuner/test_update_weights_jit.py +1 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/algorithms/test_algorithm_state_pytree.py +1 -0
- openscvx-0.5.3.dev17/tests/algorithms/test_iteration_fn_jit.py +47 -0
- openscvx-0.5.3.dev17/tests/algorithms/test_iteration_fn_parity.py +64 -0
- openscvx-0.5.3.dev17/tests/algorithms/test_make_solve_loop.py +41 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/_iteration_callback_helpers.py +86 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/test_iteration_callback_moreau.py +5 -4
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/test_iteration_callback_qpax.py +12 -11
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/test_iteration_callback_vmap.py +3 -2
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/test_moreau_ptr_solver.py +3 -1
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/test_qpax_ptr_solver.py +9 -3
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_autotuning.py +1 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_brachistochrone.py +11 -22
- openscvx-0.5.3.dev17/tests/test_solve_jax_bare_brachistochrone.py +70 -0
- openscvx-0.5.3.dev17/tests/test_solve_jax_jit_brachistochrone.py +36 -0
- openscvx-0.5.3.dev17/tests/test_solve_jax_vmap_brachistochrone.py +51 -0
- openscvx-0.5.3.dev17/tests/test_solve_jax_vmap_converged_no_drift.py +128 -0
- openscvx-0.5.3.dev15/openscvx/algorithms/scvx/penalized_trust_region.py +0 -794
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/assets/logo.svg +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/release-drafter.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/_docs.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/branch-name.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/docs.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/lint.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/nightly.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/release-drafter.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/release.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/tests-integration.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.github/workflows/tests-unit.yml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.gitignore +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/.gitmodules +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/CONTRIBUTING.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/LICENSE +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/README.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/Foundations/constraint_reformulation.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/Foundations/control_parameterization.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/Foundations/discretization.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/Foundations/ocp.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/Foundations/scvx.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/Foundations/time_dilation.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/00_introduction.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/05_visualization.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/06_logic.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/07_lie.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/08_mpcc.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/UsersGuide/09_mjx_dynamics.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/favicon.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/images/ct-scvx_dark.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/images/ct-scvx_light.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/images/ctcs_dark.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/images/ctcs_light.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/images/problem_class_dark.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/images/problem_class_light.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/logo.svg +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/openscvx_logo_square.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/viser-client/index.html +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/viser-recordings/drone_racing.viser +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/assets/viser-recordings/franka_fr3v2_pick_place.viser +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/citation.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/examples.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/index.md +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/javascripts/mathjax.js +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/docs/versions.json +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/_viser_embed_export.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/abstract/brachistochrone.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/abstract/hypersensitive.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/abstract/impulsive.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/abstract/stl_integer_variable.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/abstract/stl_or.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/animations/7_dof_arm.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/animations/_camera.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/animations/_render.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/animations/_sensor_view.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/animations/dr_vp_polytope.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/animations/franka_fr3v2_pick_place.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/animations/logo.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/animations/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/arm/3_dof_arm.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/arm/7_dof_arm.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/arm/7_dof_arm_collision.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/arm/7_dof_arm_vp.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/arm/franka_fr3v2_pick_place.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/arm/franka_fr3v2_viewplanning.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/car/dubins_car.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/car/dubins_car_disjoint.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/car/dubins_car_obstacle_conditional.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/car/dubins_car_obstacle_stl.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/car/dubins_car_stl_or.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/car/dubins_car_waypoint_stl.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/cinema_vp.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/dr_double_integrator.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/dr_vp.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/dr_vp_nodal.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/dr_vp_polytope.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/drone_racing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/logo.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/logo_utils/acl_logo.svg +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/logo_utils/svg_path_utils.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/obstacle_avoidance.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/obstacle_avoidance_nodal.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/drone/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mjx/cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mjx/double_cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mjx/skydio_x2_mjx.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mjx/triple_cartpole_3d_mjx.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mjx/triple_cartpole_game.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mjx/triple_cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mpc/double_integrator_discrete.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mpc/double_integrator_drone_racing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mpc/dubins_car_circle_analytical.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mpc/dubins_car_circle_discrete.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/plotting.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/plotting_viser.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/3DoF_pdg_realtime.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/6DoF_pdg_realtime.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/base_problems/3DoF_pdg_realtime_base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/base_problems/6DoF_pdg_realtime_base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/base_problems/dubins_car_realtime_base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/cinema_vp_realtime.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/drone_racing_realtime.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/dubins_car_realtime.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/rocket/3DoF_pdg.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/rocket/6DoF_pdg.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/spacecraft/halo_orbit.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/spacecraft/hohmann_transfer.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/spacecraft/let_transfer.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/spacecraft/proxops_cw.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/examples/spacecraft/relative_loitering.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/figures/ctlos_cine.gif +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/figures/ctlos_dr.gif +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/figures/dtlos_cine.gif +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/figures/dtlos_dr.gif +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/figures/openscvx_logo.svg +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/figures/openscvx_logo_square.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/figures/oscvx_structure_full_dark.svg +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/figures/video_preview.png +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/assets/stylesheets/custom.css +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/assets/stylesheets/home-dropin.css +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/assets/stylesheets/home-hero.css +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/assets/stylesheets/home-viser.css +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/home.html +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/main.html +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/partials/home-diagram.html +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/partials/home-dropin-banner.html +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/partials/home-hero.html +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/partials/home-pipeline.html +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/material/overrides/partials/home-viser-strip.html +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/__main__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/autotuner/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/autotuner/adaptive_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/autotuner/augmented_lagrangian.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/autotuner/constant_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/autotuner/ramp_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/scvx/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/algorithms/weights.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/config.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/discretization/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/discretization/base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/discretization/discretize_linearize.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/discretization/linearize_discretize.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/discretization/linearize_discretize_sparse.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/discretization/sparse_utils/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/discretization/sparse_utils/bcoo_helpers.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/discretization/sparse_utils/sparse_jacobian.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/expert/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/expert/byof.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/expert/lowering.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/expert/validation.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/init/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/init/interpolation.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/init/inverse_kinematics.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/integrations/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/integrations/base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/integrations/menagerie.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/integrations/mjx.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/integrators/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/integrators/diffrax.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/integrators/runge_kutta.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/loader.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/lowered/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/lowered/cvxpy_constraints.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/lowered/cvxpy_variables.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/lowered/dynamics.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/lowered/jax_constraints.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/lowered/parameters.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/lowered/problem.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/lowered/unified.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/plotting.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/scp_iteration.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/viser/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/viser/animated.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/viser/orbits.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/viser/plotly_integration.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/viser/primitives.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/viser/scp.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/plotting/viser/server.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/propagation/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/propagation/post_processing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/propagation/propagation.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/solvers/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/solvers/base.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/solvers/ptr_solver.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/augmentation.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/builder.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/constraint_set.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/arithmetic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/array.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/constraint.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/control.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/expr.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/lie/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/lie/se3.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/lie/so3.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/linalg.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/logic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/math.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/parameter.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/spatial.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/state.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/stl.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/stljax.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/time.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/variable.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/expr/vmap.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/hashing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lower.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/array.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/control.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/math.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/state.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/_registry.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/array.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/constraint.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/lie.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/linalg.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/logic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/math.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/parser.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/spatial.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/stl.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/stljax.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/parser/tokenizer.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/preprocessing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/problem.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/sparsity.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/symbolic/unified.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/utils/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/utils/cache.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/utils/printing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/utils/profiling.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx/utils/utils.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx.egg-info/dependency_links.txt +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx.egg-info/entry_points.txt +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx.egg-info/requires.txt +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/openscvx.egg-info/top_level.txt +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/pyproject.toml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/scripts/gen_example_pages.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/scripts/gen_ref_pages.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/scripts/mkdocs_copy_viser_client_hook.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/setup.cfg +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/_marks.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/algorithms/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/algorithms/autotuner/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/brachistochrone_analytical.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/conftest.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/expr/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/expr/test_gmsr.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/fixtures/brachistochrone.json +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/fixtures/brachistochrone.yaml +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/hohmann_analytical.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/integrations/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/integrations/test_mjx.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/integrations/test_mjx_dynamics.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/test_cvxpy_callback_jit_spike.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/test_iteration_callback_cvxpy.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/solvers/test_subproblem_pytree.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_arithmetic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_array.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_constraint.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_expr.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_lie.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_linalg.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_logic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_math.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_node_reference.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_parameters.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_scaling.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_spatial.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_stl.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_variable.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/expr/test_vmap.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/__init__.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_array.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_constraint.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_lie.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_linalg.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_load.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_logic.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_math.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_parser.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_spatial.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_stl.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_tokenizer.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/parser/test_vmap.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/test_augmentation.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/test_hashing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/test_lower_cvxpy.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/test_lower_jax.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/test_preprocessing.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/test_sparsity.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/symbolic/test_unified.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_cvxpygen_optional.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_discretization.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_examples.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_expert.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_impulsive.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_init.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_integrators.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_loader.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_optimization_results.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_plotting.py +0 -0
- {openscvx-0.5.3.dev15 → openscvx-0.5.3.dev17}/tests/test_propagation.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.dev17
|
|
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
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Batching, JIT, and Grad with `Problem.solve_jax()`
|
|
2
|
+
|
|
3
|
+
`Problem` exposes two solve entry points. `solve()` is the familiar
|
|
4
|
+
Python-loop driver — real-time prints, wall-clock `time_limit`, `continuous`
|
|
5
|
+
mode, populated per-iteration history. `solve_jax()` is its JAX-pure
|
|
6
|
+
sibling: it drives the same fused `iteration_fn` body inside a
|
|
7
|
+
`lax.while_loop` and returns an `OptimizationResults`
|
|
8
|
+
(`openscvx/algorithms/optimization_results.py`) pytree, so it composes with
|
|
9
|
+
`jax.vmap`, `jax.jit`, and `jax.grad`.
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
problem = ox.Problem(..., solver={"backend": "qpax"})
|
|
13
|
+
problem.initialize()
|
|
14
|
+
|
|
15
|
+
# Familiar interactive solve — unchanged: prints, history, time limit.
|
|
16
|
+
result = problem.solve()
|
|
17
|
+
|
|
18
|
+
# JAX-pure single solve — silent, no per-iteration history, batchable.
|
|
19
|
+
result = problem.solve_jax()
|
|
20
|
+
|
|
21
|
+
# Batched — standard jax.vmap, no library-specific API.
|
|
22
|
+
batched = jax.vmap(problem.solve_jax, in_axes=(0, 0, None))(
|
|
23
|
+
x_initial_stack, x_final_stack, params
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# JIT-compile once, solve forever (e.g. MPC inner loop).
|
|
27
|
+
fast_solve = jax.jit(problem.solve_jax)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
A worked example lives at `examples/abstract/brachistochrone_batched.py`
|
|
31
|
+
— four brachistochrone problems with shifted starting x-coordinates,
|
|
32
|
+
solved in parallel via `jax.vmap(problem.solve_jax)`.
|
|
33
|
+
|
|
34
|
+
## When to choose `solve()` vs. `solve_jax()`
|
|
35
|
+
|
|
36
|
+
| Use case | Entry point |
|
|
37
|
+
|---|---|
|
|
38
|
+
| Interactive use, real-time prints, plotting per iteration | `solve()` |
|
|
39
|
+
| Wall-clock `time_limit` or `continuous=True` | `solve()` |
|
|
40
|
+
| Per-iteration trajectories / weights / diagnostics | `solve()` |
|
|
41
|
+
| Batched solve over many initial conditions or parameters | `solve_jax()` |
|
|
42
|
+
| JIT-compile once, solve forever (MPC inner loop, scenario sweeps) | `solve_jax()` |
|
|
43
|
+
| `jax.grad` through the solver (best-effort, untested) | `solve_jax()` |
|
|
44
|
+
|
|
45
|
+
The split exists to make user intent explicit — a single dispatched
|
|
46
|
+
`solve()` would have to infer from arguments which path the caller wants,
|
|
47
|
+
and silent routing failures (like `continuous=True` quietly skipping the
|
|
48
|
+
Python loop) are exactly the failure class the two-method design exists to
|
|
49
|
+
prevent. See `plans/jax-pure-solve.md`'s Decision Log for the longer
|
|
50
|
+
discussion.
|
|
51
|
+
|
|
52
|
+
## What `solve_jax()` returns
|
|
53
|
+
|
|
54
|
+
`solve_jax()` returns the same `OptimizationResults` type as `solve()`,
|
|
55
|
+
but built via
|
|
56
|
+
`OptimizationResults.from_final_state(state, problem=...)` instead of
|
|
57
|
+
`from_history(history, final_state, ...)`. The differences:
|
|
58
|
+
|
|
59
|
+
* **Per-iteration history is empty.** `X = [state.x]` and `U = [state.u]`
|
|
60
|
+
are single-element lists so `result.x` / `result.u` continue to return
|
|
61
|
+
the final iterate; every `*_history` field is `[]`. List growth doesn't
|
|
62
|
+
fit inside `lax.while_loop`. If you need per-iteration trajectories, use
|
|
63
|
+
`solve()` or wrap `solve_jax()` in `lax.scan` manually.
|
|
64
|
+
* **Post-process fields stay `None`.** `t_full`, `x_full`, `u_full`,
|
|
65
|
+
`cost`, `ctcs_violation` are populated only by `post_process()`. They're
|
|
66
|
+
outside the JAX pytree's children surface, so a batched `solve_jax`
|
|
67
|
+
result doesn't force every consumer to handle `None` leaves. If you want
|
|
68
|
+
to post-process, call `post_process()` per batch element after the
|
|
69
|
+
batched solve.
|
|
70
|
+
* **`converged` is a `jnp.bool_`** under the JAX-pure path (a `(B,)` array
|
|
71
|
+
under vmap), not a Python `bool` like `solve()` returns. Most uses
|
|
72
|
+
(`if result.converged: ...`) work either way.
|
|
73
|
+
|
|
74
|
+
## `solve_jax()` arguments
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
problem.solve_jax(
|
|
78
|
+
x_initial=None, # boundary-condition pin (full unified state vector,
|
|
79
|
+
# ``jnp.nan`` at non-Fix entries — see
|
|
80
|
+
# ``AlgorithmState.from_settings``); falls back
|
|
81
|
+
# to the default from settings
|
|
82
|
+
x_final=None, # terminal pin, same conventions
|
|
83
|
+
parameters=None, # parameters dict for this solve; falls back to
|
|
84
|
+
# ``self._parameters``
|
|
85
|
+
*,
|
|
86
|
+
max_iters=None, # SCP iteration cap; non-default rebuilds the
|
|
87
|
+
# cached ``lax.while_loop`` closure (one extra
|
|
88
|
+
# trace; subsequent calls at the same cap hit
|
|
89
|
+
# the cache)
|
|
90
|
+
)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Positional kwargs (rather than a single `inputs` pytree) keep
|
|
94
|
+
`jax.vmap(problem.solve_jax, in_axes=(0, 0, None))` ergonomic;
|
|
95
|
+
multi-argument gradient uses `jax.grad(..., argnums=(0, 1))`.
|
|
96
|
+
|
|
97
|
+
## Caveats
|
|
98
|
+
|
|
99
|
+
### CVXPy under `vmap` is sequential
|
|
100
|
+
|
|
101
|
+
The CVXPy backend's `iteration_callback`
|
|
102
|
+
(`openscvx/solvers/cvxpy_ptr_solver.py`) host-calls CVXPy through
|
|
103
|
+
`jax.pure_callback` with `vmap_method="sequential"`. Host
|
|
104
|
+
CVXPy is not thread-safe, so a `jax.vmap(problem.solve_jax)` over the
|
|
105
|
+
CVXPy backend runs `B` sequential CVXPy solves. The QPAX and Moreau
|
|
106
|
+
backends are pure JAX end-to-end and run in parallel under vmap.
|
|
107
|
+
|
|
108
|
+
### Moreau warm-start is bypassed
|
|
109
|
+
|
|
110
|
+
The Moreau backend's `_warm_start` carry is host-side mutable state that
|
|
111
|
+
`lax.while_loop` doesn't thread. Both `solve()` and `solve_jax()` cold-start
|
|
112
|
+
the inner Moreau solve every SCP iteration (see the Moreau module
|
|
113
|
+
docstring and `plans/jax-pure-solve.md`'s Decision Log 2026-05-27).
|
|
114
|
+
Restoring warm-start to the SCP loop requires threading `(x, z, s)`
|
|
115
|
+
through an `AlgorithmState.moreau_carry` field — a Future Extension.
|
|
116
|
+
|
|
117
|
+
### `jax.grad` is best-effort, untested
|
|
118
|
+
|
|
119
|
+
The QPAX backend's `solve_qp` is not differentiable (its convergence flag
|
|
120
|
+
costs reverse-mode autodiff). The CVXPy backend's `pure_callback` is
|
|
121
|
+
non-differentiable by default. End-to-end gradient validation through
|
|
122
|
+
`solve_jax` is a follow-up — `jax.grad(loss_fn)(x0)` will run without
|
|
123
|
+
erroring under QPAX (`solve_qp_primal` would be `custom_vjp`, but the
|
|
124
|
+
backend currently uses `solve_qp`), but the gradient's correctness is not
|
|
125
|
+
yet pinned down by a test against finite differences.
|
|
126
|
+
|
|
127
|
+
### Convergence under `vmap` with mixed-rate elements
|
|
128
|
+
|
|
129
|
+
`lax.while_loop` continues while *any* batch element still needs
|
|
130
|
+
iterations — converged elements would otherwise keep receiving body calls
|
|
131
|
+
while their peers iterate. `make_solve_loop`'s body selects the unchanged
|
|
132
|
+
state for converged elements (`jax.tree.map(jnp.where, ...)`), so a
|
|
133
|
+
batched solve agrees with the single-problem `solve_jax` on each element.
|
|
134
|
+
The cost is per-iteration work × slowest-element iteration count.
|
|
@@ -168,18 +168,33 @@ of the abstract `PTRSolver` base. Three backends ship today:
|
|
|
168
168
|
| Backend | Class | Selector | Notes |
|
|
169
169
|
|---------|-------|----------|-------|
|
|
170
170
|
| CVXPy (default) | `CVXPyPTRSolver` | `solver={"backend": "cvxpy"}` (default) | DCP graph via CVXPy, dispatched to QOCO / CLARABEL / etc. Supports user `.convex()` constraints, cross-node constraints, CTCS, and impulsive controls. Optional cvxpygen code generation. |
|
|
171
|
-
| QPAX | `QPAXPTRSolver` | `solver={"backend": "qpax"}` | JAX-native QP via `qpax.solve_qp`. Flat `(Q, q, A, b, G, h)` assembly. Supports box / dynamics (continuous and impulsive) / CTCS / boundary-Fix; **rejects** user `.convex()` and cross-node at `initialize()` with a clear "use `CVXPyPTRSolver`" message.
|
|
171
|
+
| QPAX | `QPAXPTRSolver` | `solver={"backend": "qpax"}` | JAX-native QP via `qpax.solve_qp`. Flat `(Q, q, A, b, G, h)` assembly. Supports box / dynamics (continuous and impulsive) / CTCS / boundary-Fix; **rejects** user `.convex()` and cross-node at `initialize()` with a clear "use `CVXPyPTRSolver`" message. The `iteration_callback` uses `qpax.solve_qp`, whose convergence flag maps to a `status_code` so a diverged solve fails loudly (chosen over the differentiable `solve_qp_primal`, which exposes no such flag). |
|
|
172
172
|
| Moreau | `MoreauPTRSolver` | `solver={"backend": "moreau"}` | JAX-native conic solver (`moreau.jax.Solver`). Sparse CSR assembly; SOC epigraphs for the L1 / pos PTR penalties (fewer variables and rows than QPAX). Warm-starts between SCP iterations. Same supported subset as QPAX (continuous and impulsive dynamics). Paves the way for user `.convex()` SOC support in a follow-up. |
|
|
173
173
|
|
|
174
174
|
Each backend exposes two per-iteration entry points: the historical NumPy
|
|
175
|
-
`update_*` + `solve()` stages
|
|
175
|
+
`update_*` + `solve()` stages (kept for direct / interactive solver use), and a
|
|
176
176
|
JAX-pure `iteration_callback()` built once at `initialize()`. The callback
|
|
177
|
-
returns a `(state, SubproblemData) -> SubproblemSolution` callable; all
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
177
|
+
returns a `(state, SubproblemData) -> SubproblemSolution` callable; all three
|
|
178
|
+
backends emit the same input/output pytree shape (CVXPy host-calls via
|
|
179
|
+
`jax.pure_callback`).
|
|
180
|
+
|
|
181
|
+
`Problem.initialize()` fuses that callback with discretization, constraint
|
|
182
|
+
linearization, the SCP metrics, and the autotuner into one JAX function —
|
|
183
|
+
`iteration_fn`, built by `make_scp_iteration`
|
|
184
|
+
(`openscvx/algorithms/scvx/iteration.py`). A single JIT'd `iteration_fn` call
|
|
185
|
+
per iteration replaces the former per-step NumPy↔JAX stitching, and the Python
|
|
186
|
+
SCP loop now drives that one fused body. Forward propagation stays a separate
|
|
187
|
+
JAX export, used only by `post_process()` — so a compiled problem holds **one
|
|
188
|
+
`iteration_fn` plus one propagation export**, not three discretization /
|
|
189
|
+
propagation exports stitched together in Python. Because `iteration_fn` is a
|
|
190
|
+
registered pytree in and out, it also composes with `jax.jit`; `make_solve_loop`
|
|
191
|
+
wraps it in `lax.while_loop` to drive the **JAX-pure** `Problem.solve_jax()`
|
|
192
|
+
entry point, which composes with `jax.vmap`, `jax.jit`, and `jax.grad` (see
|
|
193
|
+
`docs/UnderTheHood/batching_jit_grad.md`). The familiar
|
|
194
|
+
`Problem.solve()` keeps its Python-loop shape — real-time prints, wall-clock
|
|
195
|
+
`time_limit`, populated per-iteration history — and is the right entry
|
|
196
|
+
point for interactive use. `solve_jax()` is the right entry point for
|
|
197
|
+
batched / JIT'd / differentiable workflows.
|
|
183
198
|
|
|
184
199
|
Picking a backend at construction time:
|
|
185
200
|
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Batched brachistochrone via ``jax.vmap(problem.solve_jax)``.
|
|
2
|
+
|
|
3
|
+
Solves four brachistochrone problems in parallel — each with a different
|
|
4
|
+
starting x-coordinate — using the JAX-pure
|
|
5
|
+
:meth:`~openscvx.problem.Problem.solve_jax` entry point. ``solve_jax``
|
|
6
|
+
returns an :class:`~openscvx.algorithms.optimization_results.OptimizationResults`
|
|
7
|
+
pytree, so ``jax.vmap`` over the boundary-condition pins is the standard JAX
|
|
8
|
+
composition pattern; no library-specific batching API is needed.
|
|
9
|
+
|
|
10
|
+
Run with ``python examples/abstract/brachistochrone_batched.py``.
|
|
11
|
+
|
|
12
|
+
Notes:
|
|
13
|
+
|
|
14
|
+
* Under the QPAX backend used here, vmap'd subproblem solves run in
|
|
15
|
+
parallel (no host callback). The CVXPy backend is single-threaded under
|
|
16
|
+
vmap because :func:`jax.pure_callback` uses ``vmap_method="sequential"``
|
|
17
|
+
for thread safety — see :meth:`solve_jax`'s docstring.
|
|
18
|
+
* The Moreau warm-start is bypassed on the JAX-pure path (its carry is
|
|
19
|
+
host-side state that ``lax.while_loop`` doesn't thread). Use QPAX or
|
|
20
|
+
CVXPy when you want batched solves.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import os
|
|
24
|
+
import sys
|
|
25
|
+
|
|
26
|
+
import jax
|
|
27
|
+
import jax.numpy as jnp
|
|
28
|
+
import numpy as np
|
|
29
|
+
|
|
30
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
31
|
+
grandparent_dir = os.path.dirname(os.path.dirname(current_dir))
|
|
32
|
+
sys.path.append(grandparent_dir)
|
|
33
|
+
|
|
34
|
+
import openscvx as ox
|
|
35
|
+
from openscvx import Problem
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def build_problem(n: int = 8):
|
|
39
|
+
g = 9.81
|
|
40
|
+
|
|
41
|
+
position = ox.State("position", shape=(2,))
|
|
42
|
+
position.max = np.array([10.0, 10.0])
|
|
43
|
+
position.min = np.array([0.0, 0.0])
|
|
44
|
+
position.initial = np.array([0.0, 10.0])
|
|
45
|
+
position.final = [10.0, 5.0]
|
|
46
|
+
|
|
47
|
+
velocity = ox.State("velocity", shape=(1,))
|
|
48
|
+
velocity.max = np.array([10.0])
|
|
49
|
+
velocity.min = np.array([0.0])
|
|
50
|
+
velocity.initial = np.array([0.0])
|
|
51
|
+
velocity.final = [("free", 10.0)]
|
|
52
|
+
|
|
53
|
+
theta = ox.Control("theta", shape=(1,))
|
|
54
|
+
theta.max = np.array([100.5 * jnp.pi / 180])
|
|
55
|
+
theta.min = np.array([0.0])
|
|
56
|
+
theta.guess = np.linspace(5 * jnp.pi / 180, 100.5 * jnp.pi / 180, n).reshape(-1, 1)
|
|
57
|
+
|
|
58
|
+
states = [position, velocity]
|
|
59
|
+
controls = [theta]
|
|
60
|
+
|
|
61
|
+
dynamics = {
|
|
62
|
+
"position": ox.Concat(
|
|
63
|
+
velocity[0] * ox.Sin(theta[0]),
|
|
64
|
+
-velocity[0] * ox.Cos(theta[0]),
|
|
65
|
+
),
|
|
66
|
+
"velocity": g * ox.Cos(theta[0]),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
constraint_exprs = []
|
|
70
|
+
for state in states:
|
|
71
|
+
constraint_exprs.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
|
|
72
|
+
|
|
73
|
+
time = ox.Time(
|
|
74
|
+
initial=0.0,
|
|
75
|
+
final=("minimize", 2.0),
|
|
76
|
+
min=0.0,
|
|
77
|
+
max=2.0,
|
|
78
|
+
uniform_time_grid=True,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return Problem(
|
|
82
|
+
dynamics=dynamics,
|
|
83
|
+
states=states,
|
|
84
|
+
controls=controls,
|
|
85
|
+
time=time,
|
|
86
|
+
constraints=constraint_exprs,
|
|
87
|
+
N=n,
|
|
88
|
+
float_dtype="float64",
|
|
89
|
+
algorithm={
|
|
90
|
+
"autotuner": "ConstantProximalWeight",
|
|
91
|
+
"lam_prox": 1e0,
|
|
92
|
+
"lam_cost": 6e-1,
|
|
93
|
+
"ep_tr": 1e-5,
|
|
94
|
+
"ep_vb": 1e-5,
|
|
95
|
+
"ep_vc": 1e-9,
|
|
96
|
+
"k_max": 30,
|
|
97
|
+
},
|
|
98
|
+
solver={"backend": "qpax"},
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
problem = build_problem()
|
|
104
|
+
problem.initialize()
|
|
105
|
+
|
|
106
|
+
# The default boundary-condition pin (the full unified state vector with
|
|
107
|
+
# ``jnp.nan`` at non-Fix entries — see
|
|
108
|
+
# :meth:`AlgorithmState.from_settings`).
|
|
109
|
+
default_pin = problem.state.x_init_pin
|
|
110
|
+
|
|
111
|
+
# Stack four ICs by varying the starting x-coordinate (component 0 of
|
|
112
|
+
# the unified state vector is the x-position).
|
|
113
|
+
shifts = jnp.array([0.0, 0.3, 0.6, 0.9])
|
|
114
|
+
x_initial_stack = jnp.stack([default_pin.at[0].set(default_pin[0] + s) for s in shifts])
|
|
115
|
+
|
|
116
|
+
# Bare ``jax.vmap`` — the library exposes no batching wrapper of its own.
|
|
117
|
+
batched_solve = jax.vmap(problem.solve_jax, in_axes=(0, None, None))
|
|
118
|
+
results = batched_solve(x_initial_stack, None, None)
|
|
119
|
+
|
|
120
|
+
# ``results`` is a batched ``OptimizationResults`` pytree — every child
|
|
121
|
+
# (``X``, ``U``, ``t_final``, ``converged``, ...) has a leading batch axis.
|
|
122
|
+
print(f"Batched solve over {x_initial_stack.shape[0]} initial conditions:")
|
|
123
|
+
print(f" result.x.shape: {results.x.shape}")
|
|
124
|
+
print(f" result.u.shape: {results.u.shape}")
|
|
125
|
+
print(f" result.t_final: {np.asarray(results.t_final).reshape(-1)}")
|
|
126
|
+
print(f" result.converged: {np.asarray(results.converged)}")
|
|
@@ -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.dev17'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 5, 3, 'dev17')
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'gb2143958f'
|
|
@@ -29,7 +29,6 @@ from openscvx.utils.printing import Column
|
|
|
29
29
|
if TYPE_CHECKING:
|
|
30
30
|
from openscvx.config import Config
|
|
31
31
|
from openscvx.lowered.jax_constraints import LoweredJaxConstraints
|
|
32
|
-
from openscvx.solvers import ConvexSolver
|
|
33
32
|
|
|
34
33
|
from .weights import Weights
|
|
35
34
|
|
|
@@ -373,6 +372,16 @@ class AlgorithmState:
|
|
|
373
372
|
actual_reduction: Actual reduction in ``J_nonlin`` for this iter.
|
|
374
373
|
acceptance_ratio: ``actual_reduction / predicted_reduction``.
|
|
375
374
|
adaptive_state_code: :class:`AdaptiveStateCode` value as ``int32``.
|
|
375
|
+
x_init_pin: Initial-state boundary condition, shape ``(n_states,)``.
|
|
376
|
+
``jnp.nan`` where the state is not pinned at t0 (``initial_type``
|
|
377
|
+
is not ``"Fix"``). Carried on the pytree — rather than read from
|
|
378
|
+
``settings`` — so the fused SCP iteration body assembles the
|
|
379
|
+
subproblem's initial boundary rows as a pure function of state,
|
|
380
|
+
and a future ``jax.vmap`` over problems can batch boundary
|
|
381
|
+
conditions per element.
|
|
382
|
+
x_term_pin: Terminal-state boundary condition, shape ``(n_states,)``.
|
|
383
|
+
``jnp.nan`` where the state is not pinned at tf (``final_type`` is
|
|
384
|
+
not ``"Fix"``).
|
|
376
385
|
"""
|
|
377
386
|
|
|
378
387
|
x: jnp.ndarray
|
|
@@ -394,6 +403,8 @@ class AlgorithmState:
|
|
|
394
403
|
actual_reduction: jnp.ndarray
|
|
395
404
|
acceptance_ratio: jnp.ndarray
|
|
396
405
|
adaptive_state_code: jnp.ndarray
|
|
406
|
+
x_init_pin: jnp.ndarray
|
|
407
|
+
x_term_pin: jnp.ndarray
|
|
397
408
|
|
|
398
409
|
# Field order is the source of truth for tree_flatten / tree_unflatten;
|
|
399
410
|
# keep _FIELDS in sync with the dataclass field declarations above.
|
|
@@ -417,6 +428,8 @@ class AlgorithmState:
|
|
|
417
428
|
"actual_reduction",
|
|
418
429
|
"acceptance_ratio",
|
|
419
430
|
"adaptive_state_code",
|
|
431
|
+
"x_init_pin",
|
|
432
|
+
"x_term_pin",
|
|
420
433
|
)
|
|
421
434
|
|
|
422
435
|
def replace(self, **changes) -> "AlgorithmState":
|
|
@@ -475,6 +488,17 @@ class AlgorithmState:
|
|
|
475
488
|
else:
|
|
476
489
|
lam_cost_init = np.full(n_states, weights.lam_cost)
|
|
477
490
|
|
|
491
|
+
# Boundary-condition pins: the physical value where the state is fixed
|
|
492
|
+
# at t0 / tf, ``nan`` elsewhere. The subproblem only reads these at
|
|
493
|
+
# ``"Fix"`` entries, so the sentinel marks "unpinned" without poisoning
|
|
494
|
+
# any value the solver consumes.
|
|
495
|
+
x_initial = np.asarray(settings.sim.x.initial, dtype=float).reshape(-1)
|
|
496
|
+
x_final = np.asarray(settings.sim.x.final, dtype=float).reshape(-1)
|
|
497
|
+
init_fixed = np.asarray(settings.sim.x.initial_type) == "Fix"
|
|
498
|
+
final_fixed = np.asarray(settings.sim.x.final_type) == "Fix"
|
|
499
|
+
x_init_pin = np.where(init_fixed, x_initial, np.nan)
|
|
500
|
+
x_term_pin = np.where(final_fixed, x_final, np.nan)
|
|
501
|
+
|
|
478
502
|
return cls(
|
|
479
503
|
x=put(jnp.asarray(settings.sim.x.guess, dtype=f)),
|
|
480
504
|
u=put(jnp.asarray(settings.sim.u.guess, dtype=f)),
|
|
@@ -495,6 +519,8 @@ class AlgorithmState:
|
|
|
495
519
|
actual_reduction=put(jnp.asarray(0.0, dtype=f)),
|
|
496
520
|
acceptance_ratio=put(jnp.asarray(0.0, dtype=f)),
|
|
497
521
|
adaptive_state_code=put(jnp.asarray(int(AdaptiveStateCode.INITIAL), dtype=i)),
|
|
522
|
+
x_init_pin=put(jnp.asarray(x_init_pin, dtype=f)),
|
|
523
|
+
x_term_pin=put(jnp.asarray(x_term_pin, dtype=f)),
|
|
498
524
|
)
|
|
499
525
|
|
|
500
526
|
|
|
@@ -798,15 +824,21 @@ class Algorithm(ABC):
|
|
|
798
824
|
@abstractmethod
|
|
799
825
|
def initialize(
|
|
800
826
|
self,
|
|
801
|
-
|
|
802
|
-
discretization_solver: callable,
|
|
803
|
-
jax_constraints: "LoweredJaxConstraints",
|
|
827
|
+
iteration_fn: Callable,
|
|
804
828
|
emitter: callable,
|
|
805
|
-
|
|
829
|
+
jax_constraints: "LoweredJaxConstraints",
|
|
806
830
|
settings: "Config",
|
|
807
|
-
discretization_solver_impulsive: Optional[Callable] = None,
|
|
808
831
|
) -> None:
|
|
809
|
-
"""
|
|
832
|
+
"""Store the fused SCP iteration body and per-iteration infrastructure.
|
|
833
|
+
|
|
834
|
+
Args:
|
|
835
|
+
iteration_fn: The JAX-pure ``(state, params) -> (next_state,
|
|
836
|
+
diagnostics)`` body built by
|
|
837
|
+
:func:`~openscvx.algorithms.scvx.iteration.make_scp_iteration`.
|
|
838
|
+
emitter: Per-iteration diagnostics sink (printing queue / no-op).
|
|
839
|
+
jax_constraints: Lowered JAX constraints the body operates over.
|
|
840
|
+
settings: Problem configuration.
|
|
841
|
+
"""
|
|
810
842
|
raise NotImplementedError
|
|
811
843
|
|
|
812
844
|
@abstractmethod
|