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.
Files changed (434) hide show
  1. {openscvx-0.5.3.dev33/openscvx.egg-info → openscvx-0.5.3.dev35}/PKG-INFO +1 -1
  2. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/_version.py +3 -3
  3. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/optimization_results.py +18 -2
  4. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/problem.py +90 -16
  5. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35/openscvx.egg-info}/PKG-INFO +1 -1
  6. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/SOURCES.txt +2 -0
  7. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/scm_file_list.json +2 -0
  8. openscvx-0.5.3.dev35/openscvx.egg-info/scm_version.json +8 -0
  9. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_optimization_results.py +27 -0
  10. openscvx-0.5.3.dev35/tests/test_post_process_batched_tau_clamp.py +104 -0
  11. openscvx-0.5.3.dev35/tests/test_results_parameters.py +93 -0
  12. openscvx-0.5.3.dev33/openscvx.egg-info/scm_version.json +0 -8
  13. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/assets/logo.svg +0 -0
  14. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/release-drafter.yml +0 -0
  15. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/_docs.yml +0 -0
  16. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/branch-name.yml +0 -0
  17. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/docs.yml +0 -0
  18. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/lint.yml +0 -0
  19. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/nightly.yml +0 -0
  20. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/release-drafter.yml +0 -0
  21. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/release.yml +0 -0
  22. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/tests-integration.yml +0 -0
  23. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.github/workflows/tests-unit.yml +0 -0
  24. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.gitignore +0 -0
  25. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/.gitmodules +0 -0
  26. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/CONTRIBUTING.md +0 -0
  27. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/LICENSE +0 -0
  28. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/README.md +0 -0
  29. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/constraint_reformulation.md +0 -0
  30. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/control_parameterization.md +0 -0
  31. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/discretization.md +0 -0
  32. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/ocp.md +0 -0
  33. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/scvx.md +0 -0
  34. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/Foundations/time_dilation.md +0 -0
  35. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/batching_jit_grad.md +0 -0
  36. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/custom_algorithms_autotuners.md +0 -0
  37. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/lowering_architecture.md +0 -0
  38. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
  39. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/00_introduction.md +0 -0
  40. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
  41. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
  42. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
  43. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
  44. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/05_visualization.md +0 -0
  45. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/06_logic.md +0 -0
  46. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/07_lie.md +0 -0
  47. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/08_mpcc.md +0 -0
  48. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/UsersGuide/09_mjx_dynamics.md +0 -0
  49. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/favicon.png +0 -0
  50. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/ct-scvx_dark.png +0 -0
  51. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/ct-scvx_light.png +0 -0
  52. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/ctcs_dark.png +0 -0
  53. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/ctcs_light.png +0 -0
  54. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/problem_class_dark.png +0 -0
  55. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/images/problem_class_light.png +0 -0
  56. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/logo.svg +0 -0
  57. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/openscvx_logo_square.png +0 -0
  58. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/viser-client/index.html +0 -0
  59. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/viser-recordings/drone_racing.viser +0 -0
  60. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/assets/viser-recordings/franka_fr3v2_pick_place.viser +0 -0
  61. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/citation.md +0 -0
  62. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/examples.md +0 -0
  63. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/index.md +0 -0
  64. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/javascripts/mathjax.js +0 -0
  65. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/docs/versions.json +0 -0
  66. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/_viser_embed_export.py +0 -0
  67. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/brachistochrone.py +0 -0
  68. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/brachistochrone_batched.py +0 -0
  69. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/flappy_bird.py +0 -0
  70. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/hypersensitive.py +0 -0
  71. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/impulsive.py +0 -0
  72. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/stl_integer_variable.py +0 -0
  73. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/abstract/stl_or.py +0 -0
  74. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/aircraft/dynamic_soaring.py +0 -0
  75. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/aircraft/supersonic_time_to_climb.py +0 -0
  76. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/7_dof_arm.py +0 -0
  77. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/_camera.py +0 -0
  78. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/_render.py +0 -0
  79. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/_sensor_view.py +0 -0
  80. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/dr_vp_polytope.py +0 -0
  81. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/franka_fr3v2_pick_place.py +0 -0
  82. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/logo.py +0 -0
  83. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/animations/obstacle_avoidance_vmap.py +0 -0
  84. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/3_dof_arm.py +0 -0
  85. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/7_dof_arm.py +0 -0
  86. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/7_dof_arm_collision.py +0 -0
  87. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/7_dof_arm_vp.py +0 -0
  88. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/franka_fr3v2_pick_place.py +0 -0
  89. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/franka_fr3v2_viewplanning.py +0 -0
  90. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/arm/franka_fr3v2_viewplanning_nodal.py +0 -0
  91. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car.py +0 -0
  92. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_disjoint.py +0 -0
  93. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_obstacle_conditional.py +0 -0
  94. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_obstacle_stl.py +0 -0
  95. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_stl_or.py +0 -0
  96. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/car/dubins_car_waypoint_stl.py +0 -0
  97. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/double_integrator/_plotting.py +0 -0
  98. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/double_integrator/moving_safe_zones.py +0 -0
  99. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/2d_obstacle_avoidance_batched_ic.py +0 -0
  100. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/cinema_vp.py +0 -0
  101. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/cinema_vp_nodal.py +0 -0
  102. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/dr_double_integrator.py +0 -0
  103. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/dr_vp.py +0 -0
  104. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/dr_vp_nodal.py +0 -0
  105. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/dr_vp_polytope.py +0 -0
  106. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/drone_racing.py +0 -0
  107. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/drone_racing_batched_gates.py +0 -0
  108. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo.py +0 -0
  109. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo_utils/acl_logo.svg +0 -0
  110. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo_utils/openscvx_logo_single.svg +0 -0
  111. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo_utils/quadrotor_mesh.py +0 -0
  112. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/logo_utils/svg_path_utils.py +0 -0
  113. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/multi_agent_circle_swap.py +0 -0
  114. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/obstacle_avoidance.py +0 -0
  115. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/obstacle_avoidance_nodal.py +0 -0
  116. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/obstacle_avoidance_vmap.py +0 -0
  117. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/obstacle_avoidance_vmap_2d.py +0 -0
  118. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/drone/openscvx_logo.py +0 -0
  119. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/frax/panda_frax.py +0 -0
  120. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/frax/panda_frax_pick_place.py +0 -0
  121. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/frax/panda_frax_viewplanning.py +0 -0
  122. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/frax/panda_frax_waypoint.py +0 -0
  123. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/cartpole_mjx.py +0 -0
  124. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/double_cartpole_mjx.py +0 -0
  125. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/skydio_x2_mjx.py +0 -0
  126. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/triple_cartpole_3d_mjx.py +0 -0
  127. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/triple_cartpole_game.py +0 -0
  128. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mjx/triple_cartpole_mjx.py +0 -0
  129. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/double_integrator_discrete.py +0 -0
  130. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/double_integrator_drone_racing.py +0 -0
  131. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/dubins_car_circle_analytical.py +0 -0
  132. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/dubins_car_circle_discrete.py +0 -0
  133. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
  134. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/plotting.py +0 -0
  135. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/plotting_viser.py +0 -0
  136. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/3DoF_pdg_realtime.py +0 -0
  137. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/6DoF_pdg_realtime.py +0 -0
  138. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/3DoF_pdg_realtime_base.py +0 -0
  139. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/6DoF_pdg_realtime_base.py +0 -0
  140. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
  141. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
  142. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/dubins_car_realtime_base.py +0 -0
  143. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
  144. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/cinema_vp_realtime.py +0 -0
  145. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/drone_racing_realtime.py +0 -0
  146. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/dubins_car_realtime.py +0 -0
  147. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
  148. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/rocket/3DoF_pdg.py +0 -0
  149. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/rocket/6DoF_pdg.py +0 -0
  150. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/rocket/6DoF_pdg_batched_ic.py +0 -0
  151. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/rocket/ascent_launch_vehicle.py +0 -0
  152. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/halo_orbit.py +0 -0
  153. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/hohmann_transfer.py +0 -0
  154. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/let_transfer.py +0 -0
  155. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/proxops_cw.py +0 -0
  156. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/examples/spacecraft/relative_loitering.py +0 -0
  157. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/ctlos_cine.gif +0 -0
  158. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/ctlos_dr.gif +0 -0
  159. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/dtlos_cine.gif +0 -0
  160. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/dtlos_dr.gif +0 -0
  161. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/openscvx_logo.svg +0 -0
  162. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/openscvx_logo_square.png +0 -0
  163. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/oscvx_structure_full_dark.svg +0 -0
  164. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/figures/video_preview.png +0 -0
  165. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/__init__.py +0 -0
  166. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/assets/stylesheets/custom.css +0 -0
  167. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/assets/stylesheets/home-dropin.css +0 -0
  168. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/assets/stylesheets/home-hero.css +0 -0
  169. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/assets/stylesheets/home-viser.css +0 -0
  170. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/home.html +0 -0
  171. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/main.html +0 -0
  172. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-diagram.html +0 -0
  173. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-dropin-banner.html +0 -0
  174. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-hero.html +0 -0
  175. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-pipeline.html +0 -0
  176. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/material/overrides/partials/home-viser-strip.html +0 -0
  177. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/mkdocs.yml +0 -0
  178. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/__init__.py +0 -0
  179. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/__main__.py +0 -0
  180. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/__init__.py +0 -0
  181. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/__init__.py +0 -0
  182. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/acceptance_ratio.py +0 -0
  183. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/adaptive_proximal_weight.py +0 -0
  184. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/augmented_lagrangian.py +0 -0
  185. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/base.py +0 -0
  186. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/constant_proximal_weight.py +0 -0
  187. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/autotuner/ramp_proximal_weight.py +0 -0
  188. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/base.py +0 -0
  189. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/history.py +0 -0
  190. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/hyperparams.py +0 -0
  191. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/loop.py +0 -0
  192. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/penalty.py +0 -0
  193. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/scvx/__init__.py +0 -0
  194. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/scvx/iteration.py +0 -0
  195. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/scvx/penalized_trust_region.py +0 -0
  196. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/state.py +0 -0
  197. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/algorithms/weights.py +0 -0
  198. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/config.py +0 -0
  199. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/__init__.py +0 -0
  200. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/base.py +0 -0
  201. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/discretize_linearize.py +0 -0
  202. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/linearize_discretize.py +0 -0
  203. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/linearize_discretize_sparse.py +0 -0
  204. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/sparse_utils/__init__.py +0 -0
  205. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/sparse_utils/bcoo_helpers.py +0 -0
  206. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/discretization/sparse_utils/sparse_jacobian.py +0 -0
  207. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/expert/__init__.py +0 -0
  208. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/expert/byof.py +0 -0
  209. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/expert/lowering.py +0 -0
  210. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/expert/validation.py +0 -0
  211. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/init/__init__.py +0 -0
  212. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/init/interpolation.py +0 -0
  213. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/init/inverse_kinematics.py +0 -0
  214. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/__init__.py +0 -0
  215. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/_utils.py +0 -0
  216. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/base.py +0 -0
  217. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/frax.py +0 -0
  218. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/menagerie.py +0 -0
  219. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrations/mjx.py +0 -0
  220. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrators/__init__.py +0 -0
  221. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrators/diffrax.py +0 -0
  222. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/integrators/runge_kutta.py +0 -0
  223. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/loader.py +0 -0
  224. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/__init__.py +0 -0
  225. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/cvxpy_constraints.py +0 -0
  226. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/cvxpy_variables.py +0 -0
  227. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/dynamics.py +0 -0
  228. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/jax_constraints.py +0 -0
  229. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/parameters.py +0 -0
  230. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/problem.py +0 -0
  231. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/lowered/unified.py +0 -0
  232. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/__init__.py +0 -0
  233. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/plotting.py +0 -0
  234. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/publication.py +0 -0
  235. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/scp_iteration.py +0 -0
  236. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/__init__.py +0 -0
  237. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/animated.py +0 -0
  238. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/coordinates.py +0 -0
  239. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/orbits.py +0 -0
  240. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/plotly_integration.py +0 -0
  241. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/primitives.py +0 -0
  242. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/scp.py +0 -0
  243. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/plotting/viser/server.py +0 -0
  244. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/propagation/__init__.py +0 -0
  245. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/propagation/post_processing.py +0 -0
  246. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/propagation/propagation.py +0 -0
  247. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/__init__.py +0 -0
  248. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/base.py +0 -0
  249. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/cones.py +0 -0
  250. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/cvxpy_ptr_solver.py +0 -0
  251. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/moreau_ptr_solver.py +0 -0
  252. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/ptr_solver.py +0 -0
  253. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/solvers/qpax_ptr_solver.py +0 -0
  254. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/__init__.py +0 -0
  255. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/affine.py +0 -0
  256. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/augmentation.py +0 -0
  257. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/builder.py +0 -0
  258. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/canonicalize.py +0 -0
  259. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/constraint_set.py +0 -0
  260. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/__init__.py +0 -0
  261. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/arithmetic.py +0 -0
  262. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/array.py +0 -0
  263. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/constraint.py +0 -0
  264. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/control.py +0 -0
  265. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/expr.py +0 -0
  266. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/lie/__init__.py +0 -0
  267. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
  268. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/lie/se3.py +0 -0
  269. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/lie/so3.py +0 -0
  270. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/linalg.py +0 -0
  271. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/logic.py +0 -0
  272. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/math.py +0 -0
  273. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/parameter.py +0 -0
  274. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/spatial.py +0 -0
  275. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/state.py +0 -0
  276. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/stl.py +0 -0
  277. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/stljax.py +0 -0
  278. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/time.py +0 -0
  279. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/variable.py +0 -0
  280. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/expr/vmap.py +0 -0
  281. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/hashing.py +0 -0
  282. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lower.py +0 -0
  283. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/__init__.py +0 -0
  284. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
  285. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
  286. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
  287. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
  288. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
  289. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
  290. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
  291. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
  292. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
  293. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
  294. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
  295. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
  296. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
  297. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
  298. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
  299. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
  300. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/array.py +0 -0
  301. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
  302. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/control.py +0 -0
  303. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
  304. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
  305. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
  306. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
  307. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/math.py +0 -0
  308. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
  309. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/state.py +0 -0
  310. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
  311. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
  312. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
  313. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/__init__.py +0 -0
  314. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/_registry.py +0 -0
  315. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/array.py +0 -0
  316. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/constraint.py +0 -0
  317. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/lie.py +0 -0
  318. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/linalg.py +0 -0
  319. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/logic.py +0 -0
  320. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/math.py +0 -0
  321. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/parser.py +0 -0
  322. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/spatial.py +0 -0
  323. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/stl.py +0 -0
  324. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/stljax.py +0 -0
  325. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/parser/tokenizer.py +0 -0
  326. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/preprocessing.py +0 -0
  327. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/problem.py +0 -0
  328. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/sparsity.py +0 -0
  329. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/symbolic/unified.py +0 -0
  330. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/__init__.py +0 -0
  331. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/cache.py +0 -0
  332. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/caching.py +0 -0
  333. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/printing.py +0 -0
  334. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/profiling.py +0 -0
  335. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx/utils/utils.py +0 -0
  336. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/dependency_links.txt +0 -0
  337. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/entry_points.txt +0 -0
  338. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/requires.txt +0 -0
  339. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/openscvx.egg-info/top_level.txt +0 -0
  340. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/pyproject.toml +0 -0
  341. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/scripts/gen_example_pages.py +0 -0
  342. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/scripts/gen_ref_pages.py +0 -0
  343. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/scripts/mkdocs_copy_viser_client_hook.py +0 -0
  344. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/setup.cfg +0 -0
  345. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/__init__.py +0 -0
  346. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/_marks.py +0 -0
  347. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/__init__.py +0 -0
  348. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/_iteration_helpers.py +0 -0
  349. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/autotuner/__init__.py +0 -0
  350. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/autotuner/test_defaults_agreement.py +0 -0
  351. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/autotuner/test_hyper_overrides.py +0 -0
  352. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/autotuner/test_update_weights_jit.py +0 -0
  353. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/test_algorithm_state_pytree.py +0 -0
  354. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/test_iteration_fn_jit.py +0 -0
  355. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/test_iteration_fn_parity.py +0 -0
  356. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/algorithms/test_make_solve_loop.py +0 -0
  357. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/brachistochrone_analytical.py +0 -0
  358. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/conftest.py +0 -0
  359. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/expr/__init__.py +0 -0
  360. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/expr/test_gmsr.py +0 -0
  361. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/fixtures/brachistochrone.json +0 -0
  362. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/fixtures/brachistochrone.yaml +0 -0
  363. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/hohmann_analytical.py +0 -0
  364. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/integrations/__init__.py +0 -0
  365. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/integrations/test_mjx.py +0 -0
  366. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/integrations/test_mjx_dynamics.py +0 -0
  367. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/__init__.py +0 -0
  368. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/_iteration_callback_helpers.py +0 -0
  369. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_cvxpy_callback_jit_spike.py +0 -0
  370. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_iteration_callback_cvxpy.py +0 -0
  371. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_iteration_callback_moreau.py +0 -0
  372. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_iteration_callback_qpax.py +0 -0
  373. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_iteration_callback_vmap.py +0 -0
  374. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_moreau_ptr_solver.py +0 -0
  375. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_qpax_ptr_solver.py +0 -0
  376. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/solvers/test_subproblem_pytree.py +0 -0
  377. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/__init__.py +0 -0
  378. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/__init__.py +0 -0
  379. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_arithmetic.py +0 -0
  380. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_array.py +0 -0
  381. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_constraint.py +0 -0
  382. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_expr.py +0 -0
  383. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_lie.py +0 -0
  384. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_linalg.py +0 -0
  385. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_logic.py +0 -0
  386. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_math.py +0 -0
  387. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_node_reference.py +0 -0
  388. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_parameters.py +0 -0
  389. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_scaling.py +0 -0
  390. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_spatial.py +0 -0
  391. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_stl.py +0 -0
  392. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_variable.py +0 -0
  393. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/expr/test_vmap.py +0 -0
  394. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/__init__.py +0 -0
  395. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_array.py +0 -0
  396. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_constraint.py +0 -0
  397. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_lie.py +0 -0
  398. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_linalg.py +0 -0
  399. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_load.py +0 -0
  400. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_logic.py +0 -0
  401. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_math.py +0 -0
  402. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_parser.py +0 -0
  403. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_spatial.py +0 -0
  404. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_stl.py +0 -0
  405. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_tokenizer.py +0 -0
  406. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/parser/test_vmap.py +0 -0
  407. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_augmentation.py +0 -0
  408. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_hashing.py +0 -0
  409. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_lower_cvxpy.py +0 -0
  410. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_lower_jax.py +0 -0
  411. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_preprocessing.py +0 -0
  412. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_sparsity.py +0 -0
  413. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/symbolic/test_unified.py +0 -0
  414. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_autotuning.py +0 -0
  415. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_brachistochrone.py +0 -0
  416. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_cvxpygen_optional.py +0 -0
  417. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_discretization.py +0 -0
  418. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_examples.py +0 -0
  419. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_expert.py +0 -0
  420. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_impulsive.py +0 -0
  421. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_init.py +0 -0
  422. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_integrators.py +0 -0
  423. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_loader.py +0 -0
  424. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_multishot_propagation.py +0 -0
  425. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_plotting.py +0 -0
  426. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_propagation.py +0 -0
  427. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_batched_brachistochrone.py +0 -0
  428. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_batched_cvxpy_export_errors.py +0 -0
  429. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_batched_export_roundtrip.py +0 -0
  430. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_batched_inference.py +0 -0
  431. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_jax_bare_brachistochrone.py +0 -0
  432. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_jax_jit_brachistochrone.py +0 -0
  433. {openscvx-0.5.3.dev33 → openscvx-0.5.3.dev35}/tests/test_solve_jax_vmap_brachistochrone.py +0 -0
  434. {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.dev33
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.dev33'
22
- __version_tuple__ = version_tuple = (0, 5, 3, 'dev33')
21
+ __version__ = version = '0.5.3.dev35'
22
+ __version_tuple__ = version_tuple = (0, 5, 3, 'dev35')
23
23
 
24
- __commit_id__ = commit_id = 'g3d6f6768a'
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 internal ``_states`` /
63
- ``_controls`` metadata are stashed in the treedef's *aux* instead, so
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 get_propagation_solver, propagate_trajectory_results
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 + history for post_process() / plotting reuse.
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
- return self._format_result(
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
- return OptimizationResults.from_final_state(final_states, problem=self)
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._parameters,
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
- all elements share ``self._parameters`` for any parameter values not
2027
- embedded in the trajectory state vector.
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``. A uniform ``linspace`` grid sized from the batch
2060
- # ``T_max`` can place more output times into one normalized segment than
2061
- # that capacity when shorter trajectories are padded to the same count.
2062
- n_times = min(n_times, self.settings.prp.max_tau_len)
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.dev33
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",
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.5.2",
3
+ "distance": 35,
4
+ "node": "g43f7b7f313888f19e8586f108d8e11bed332f87f",
5
+ "dirty": false,
6
+ "branch": "main",
7
+ "node_date": "2026-07-06"
8
+ }
@@ -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()
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "0.5.2",
3
- "distance": 33,
4
- "node": "g3d6f6768a9d011c99ab12c85b6695002b0606580",
5
- "dirty": false,
6
- "branch": "main",
7
- "node_date": "2026-07-05"
8
- }
File without changes
File without changes