openscvx 0.4.1.dev153__tar.gz → 0.4.1.dev155__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 (336) hide show
  1. {openscvx-0.4.1.dev153/openscvx.egg-info → openscvx-0.4.1.dev155}/PKG-INFO +1 -1
  2. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/__init__.py +2 -1
  3. openscvx-0.4.1.dev155/openscvx/_version.py +24 -0
  4. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/penalized_trust_region.py +10 -10
  5. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/discretization/__init__.py +19 -8
  6. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/discretization/linearize_discretize.py +58 -23
  7. openscvx-0.4.1.dev155/openscvx/discretization/linearize_discretize_sparse.py +346 -0
  8. openscvx-0.4.1.dev155/openscvx/discretization/sparse_utils/__init__.py +11 -0
  9. openscvx-0.4.1.dev155/openscvx/discretization/sparse_utils/bcoo_helpers.py +63 -0
  10. openscvx-0.4.1.dev155/openscvx/discretization/sparse_utils/sparse_jacobian.py +177 -0
  11. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/integrators/__init__.py +8 -2
  12. openscvx-0.4.1.dev155/openscvx/integrators/diffrax.py +151 -0
  13. openscvx-0.4.1.dev155/openscvx/integrators/runge_kutta.py +88 -0
  14. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/dynamics.py +10 -1
  15. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/problem.py +19 -7
  16. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/propagation/propagation.py +9 -1
  17. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lower.py +5 -0
  18. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/caching.py +28 -11
  19. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155/openscvx.egg-info}/PKG-INFO +1 -1
  20. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/SOURCES.txt +5 -0
  21. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_brachistochrone.py +2 -0
  22. openscvx-0.4.1.dev155/tests/test_discretization.py +420 -0
  23. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_examples.py +0 -4
  24. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_integrators.py +22 -0
  25. openscvx-0.4.1.dev153/openscvx/_version.py +0 -34
  26. openscvx-0.4.1.dev153/openscvx/integrators/runge_kutta.py +0 -281
  27. openscvx-0.4.1.dev153/tests/test_discretization.py +0 -132
  28. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/assets/logo.svg +0 -0
  29. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/release-drafter.yml +0 -0
  30. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/_docs.yml +0 -0
  31. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/branch-name.yml +0 -0
  32. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/docs.yml +0 -0
  33. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/lint.yml +0 -0
  34. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/nightly.yml +0 -0
  35. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/release-drafter.yml +0 -0
  36. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/release.yml +0 -0
  37. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/tests-integration.yml +0 -0
  38. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/tests-unit.yml +0 -0
  39. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.gitignore +0 -0
  40. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/CONTRIBUTING.md +0 -0
  41. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/LICENSE +0 -0
  42. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/README.md +0 -0
  43. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/constraint_reformulation.md +0 -0
  44. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/control_parameterization.md +0 -0
  45. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/discretization.md +0 -0
  46. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/ocp.md +0 -0
  47. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/scvx.md +0 -0
  48. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/time_dilation.md +0 -0
  49. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UnderTheHood/lowering_architecture.md +0 -0
  50. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
  51. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/00_introduction.md +0 -0
  52. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
  53. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
  54. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
  55. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
  56. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/05_visualization.md +0 -0
  57. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/06_logic.md +0 -0
  58. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/07_lie.md +0 -0
  59. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/08_mpcc.md +0 -0
  60. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/favicon.png +0 -0
  61. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/ct-scvx_dark.png +0 -0
  62. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/ct-scvx_light.png +0 -0
  63. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/ctcs_dark.png +0 -0
  64. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/ctcs_light.png +0 -0
  65. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/problem_class_dark.png +0 -0
  66. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/problem_class_light.png +0 -0
  67. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/logo.svg +0 -0
  68. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/citation.md +0 -0
  69. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/examples.md +0 -0
  70. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/getting-started.md +0 -0
  71. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/index.md +0 -0
  72. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/javascripts/mathjax.js +0 -0
  73. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/abstract/brachistochrone.py +0 -0
  74. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/abstract/impulsive.py +0 -0
  75. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/abstract/stl_integer_variable.py +0 -0
  76. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/abstract/stl_or.py +0 -0
  77. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/arm/three_link_arm.py +0 -0
  78. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car.py +0 -0
  79. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_disjoint.py +0 -0
  80. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_obstacle_conditional.py +0 -0
  81. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_obstacle_stl.py +0 -0
  82. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_stl_or.py +0 -0
  83. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_waypoint_stl.py +0 -0
  84. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/cinema_vp.py +0 -0
  85. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/dr_double_integrator.py +0 -0
  86. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/dr_vp.py +0 -0
  87. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/dr_vp_nodal.py +0 -0
  88. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/dr_vp_polytope.py +0 -0
  89. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/drone_racing.py +0 -0
  90. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/logo.py +0 -0
  91. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/logo_utils/acl_logo.svg +0 -0
  92. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/logo_utils/svg_path_utils.py +0 -0
  93. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/obstacle_avoidance.py +0 -0
  94. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/obstacle_avoidance_nodal.py +0 -0
  95. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/obstacle_avoidance_vmap.py +0 -0
  96. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/double_integrator_discrete.py +0 -0
  97. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/double_integrator_drone_racing.py +0 -0
  98. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/dubins_car_circle_analytical.py +0 -0
  99. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/dubins_car_circle_discrete.py +0 -0
  100. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
  101. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/plotting.py +0 -0
  102. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/plotting_viser.py +0 -0
  103. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
  104. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
  105. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
  106. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/cinema_vp_realtime.py +0 -0
  107. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/drone_racing_realtime.py +0 -0
  108. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/dubins_car_realtime.py +0 -0
  109. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
  110. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/rocket/3DoF_pdg.py +0 -0
  111. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/spacecraft/hohmann_transfer.py +0 -0
  112. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/spacecraft/proxops_cw.py +0 -0
  113. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/ctlos_cine.gif +0 -0
  114. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/ctlos_dr.gif +0 -0
  115. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/dtlos_cine.gif +0 -0
  116. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/dtlos_dr.gif +0 -0
  117. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/openscvx_logo.svg +0 -0
  118. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/openscvx_logo_square.png +0 -0
  119. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/oscvx_structure_full_dark.svg +0 -0
  120. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/video_preview.png +0 -0
  121. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/__init__.py +0 -0
  122. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background.avif +0 -0
  123. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background@1x.avif +0 -0
  124. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background@2x.avif +0 -0
  125. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background@3x.avif +0 -0
  126. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background@4x.avif +0 -0
  127. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars.avif +0 -0
  128. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars@1x.avif +0 -0
  129. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars@2x.avif +0 -0
  130. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars@3x.avif +0 -0
  131. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars@4x.avif +0 -0
  132. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon.avif +0 -0
  133. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon@1x.avif +0 -0
  134. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon@2x.avif +0 -0
  135. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon@3x.avif +0 -0
  136. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon@4x.avif +0 -0
  137. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1.avif +0 -0
  138. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1@1x.avif +0 -0
  139. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1@2x.avif +0 -0
  140. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1@3x.avif +0 -0
  141. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1@4x.avif +0 -0
  142. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space.avif +0 -0
  143. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space@1x.avif +0 -0
  144. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space@2x.avif +0 -0
  145. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space@3x.avif +0 -0
  146. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space@4x.avif +0 -0
  147. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth.avif +0 -0
  148. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth@1x.avif +0 -0
  149. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth@2x.avif +0 -0
  150. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth@3x.avif +0 -0
  151. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth@4x.avif +0 -0
  152. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/javascripts/parallax.js +0 -0
  153. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/logo.svg +0 -0
  154. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/stylesheets/custom.css +0 -0
  155. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/stylesheets/parallax.css +0 -0
  156. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/home.html +0 -0
  157. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/main.html +0 -0
  158. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/partials/parallax/hero.html +0 -0
  159. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/partials/parallax.html +0 -0
  160. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/mkdocs.yml +0 -0
  161. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/__main__.py +0 -0
  162. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/__init__.py +0 -0
  163. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/augmented_lagrangian.py +0 -0
  164. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/base.py +0 -0
  165. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/constant_proximal_weight.py +0 -0
  166. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/optimization_results.py +0 -0
  167. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/ramp_proximal_weight.py +0 -0
  168. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/config.py +0 -0
  169. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/discretization/base.py +0 -0
  170. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/expert/__init__.py +0 -0
  171. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/expert/byof.py +0 -0
  172. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/expert/lowering.py +0 -0
  173. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/expert/validation.py +0 -0
  174. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/init/__init__.py +0 -0
  175. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/init/interpolation.py +0 -0
  176. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/loader.py +0 -0
  177. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/__init__.py +0 -0
  178. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/cvxpy_constraints.py +0 -0
  179. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/cvxpy_variables.py +0 -0
  180. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/jax_constraints.py +0 -0
  181. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/parameters.py +0 -0
  182. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/problem.py +0 -0
  183. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/unified.py +0 -0
  184. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/__init__.py +0 -0
  185. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/plotting.py +0 -0
  186. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/scp_iteration.py +0 -0
  187. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/__init__.py +0 -0
  188. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/animated.py +0 -0
  189. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/orbits.py +0 -0
  190. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/plotly_integration.py +0 -0
  191. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/primitives.py +0 -0
  192. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/scp.py +0 -0
  193. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/server.py +0 -0
  194. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/propagation/__init__.py +0 -0
  195. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/propagation/post_processing.py +0 -0
  196. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/solvers/__init__.py +0 -0
  197. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/solvers/base.py +0 -0
  198. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/solvers/ptr_solver.py +0 -0
  199. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/__init__.py +0 -0
  200. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/augmentation.py +0 -0
  201. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/builder.py +0 -0
  202. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/constraint_set.py +0 -0
  203. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/__init__.py +0 -0
  204. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/arithmetic.py +0 -0
  205. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/array.py +0 -0
  206. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/constraint.py +0 -0
  207. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/control.py +0 -0
  208. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/expr.py +0 -0
  209. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/lie/__init__.py +0 -0
  210. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
  211. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/lie/se3.py +0 -0
  212. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/lie/so3.py +0 -0
  213. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/linalg.py +0 -0
  214. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/logic.py +0 -0
  215. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/math.py +0 -0
  216. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/spatial.py +0 -0
  217. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/state.py +0 -0
  218. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/stl.py +0 -0
  219. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/stljax.py +0 -0
  220. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/time.py +0 -0
  221. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/variable.py +0 -0
  222. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/vmap.py +0 -0
  223. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/hashing.py +0 -0
  224. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/__init__.py +0 -0
  225. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
  226. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
  227. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
  228. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
  229. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
  230. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
  231. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
  232. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
  233. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
  234. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
  235. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
  236. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
  237. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
  238. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
  239. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
  240. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
  241. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/array.py +0 -0
  242. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
  243. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/control.py +0 -0
  244. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
  245. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
  246. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
  247. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
  248. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/math.py +0 -0
  249. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
  250. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/state.py +0 -0
  251. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
  252. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
  253. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
  254. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/__init__.py +0 -0
  255. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/_registry.py +0 -0
  256. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/array.py +0 -0
  257. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/constraint.py +0 -0
  258. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/lie.py +0 -0
  259. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/linalg.py +0 -0
  260. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/logic.py +0 -0
  261. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/math.py +0 -0
  262. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/parser.py +0 -0
  263. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/spatial.py +0 -0
  264. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/stl.py +0 -0
  265. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/stljax.py +0 -0
  266. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/tokenizer.py +0 -0
  267. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/preprocessing.py +0 -0
  268. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/problem.py +0 -0
  269. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/sparsity.py +0 -0
  270. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/unified.py +0 -0
  271. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/__init__.py +0 -0
  272. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/cache.py +0 -0
  273. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/printing.py +0 -0
  274. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/profiling.py +0 -0
  275. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/utils.py +0 -0
  276. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/dependency_links.txt +0 -0
  277. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/entry_points.txt +0 -0
  278. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/requires.txt +0 -0
  279. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/top_level.txt +0 -0
  280. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/pyproject.toml +0 -0
  281. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/scripts/gen_example_pages.py +0 -0
  282. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/scripts/gen_ref_pages.py +0 -0
  283. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/setup.cfg +0 -0
  284. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/__init__.py +0 -0
  285. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/brachistochrone_analytical.py +0 -0
  286. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/expr/__init__.py +0 -0
  287. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/expr/test_gmsr.py +0 -0
  288. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/fixtures/brachistochrone.json +0 -0
  289. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/fixtures/brachistochrone.yaml +0 -0
  290. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/hohmann_analytical.py +0 -0
  291. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/__init__.py +0 -0
  292. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/__init__.py +0 -0
  293. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_arithmetic.py +0 -0
  294. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_array.py +0 -0
  295. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_constraint.py +0 -0
  296. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_expr.py +0 -0
  297. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_lie.py +0 -0
  298. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_linalg.py +0 -0
  299. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_logic.py +0 -0
  300. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_math.py +0 -0
  301. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_node_reference.py +0 -0
  302. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_parameters.py +0 -0
  303. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_scaling.py +0 -0
  304. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_spatial.py +0 -0
  305. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_stl.py +0 -0
  306. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_variable.py +0 -0
  307. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_vmap.py +0 -0
  308. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/__init__.py +0 -0
  309. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_array.py +0 -0
  310. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_constraint.py +0 -0
  311. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_lie.py +0 -0
  312. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_linalg.py +0 -0
  313. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_load.py +0 -0
  314. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_logic.py +0 -0
  315. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_math.py +0 -0
  316. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_parser.py +0 -0
  317. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_spatial.py +0 -0
  318. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_stl.py +0 -0
  319. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_tokenizer.py +0 -0
  320. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_vmap.py +0 -0
  321. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_augmentation.py +0 -0
  322. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_hashing.py +0 -0
  323. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_lower_cvxpy.py +0 -0
  324. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_lower_jax.py +0 -0
  325. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_preprocessing.py +0 -0
  326. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_sparsity.py +0 -0
  327. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_unified.py +0 -0
  328. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_autotuning.py +0 -0
  329. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_cvxpygen_optional.py +0 -0
  330. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_expert.py +0 -0
  331. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_impulsive.py +0 -0
  332. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_init.py +0 -0
  333. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_loader.py +0 -0
  334. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_optimization_results.py +0 -0
  335. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_plotting.py +0 -0
  336. {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_propagation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscvx
3
- Version: 0.4.1.dev153
3
+ Version: 0.4.1.dev155
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 @@ from openscvx.algorithms import (
18
18
  RampProximalWeight,
19
19
  )
20
20
  from openscvx.algorithms.optimization_results import OptimizationResults
21
- from openscvx.discretization import LinearizeDiscretize
21
+ from openscvx.discretization import LinearizeDiscretize, LinearizeDiscretizeSparse
22
22
  from openscvx.expert import ByofSpec
23
23
  from openscvx.loader import load_dict, load_json, load_yaml
24
24
  from openscvx.problem import Problem
@@ -173,6 +173,7 @@ __all__ = [
173
173
  "ByofSpec",
174
174
  # Discretization
175
175
  "LinearizeDiscretize",
176
+ "LinearizeDiscretizeSparse",
176
177
  # Convex Solver
177
178
  "PTRSolver",
178
179
  # Algorithm & Autotuning
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.4.1.dev155'
22
+ __version_tuple__ = version_tuple = (0, 4, 1, 'dev155')
23
+
24
+ __commit_id__ = commit_id = 'gbd34ba2e8'
@@ -347,8 +347,8 @@ class PenalizedTrustRegion(Algorithm):
347
347
  init_state = AlgorithmState.from_settings(settings, self.weights)
348
348
 
349
349
  # Solve a dumb problem to initialize DPP and JAX jacobians
350
- _, _, _, x_prop, V_multi_shoot = self._discretization_solver.call(
351
- init_state.x, init_state.u.astype(float), params
350
+ _, _, _, x_prop, V_multi_shoot = self._invoke_solver(
351
+ self._discretization_solver, init_state.x, init_state.u.astype(float), params
352
352
  )
353
353
 
354
354
  init_state.add_discretization(V_multi_shoot.__array__())
@@ -399,15 +399,15 @@ class PenalizedTrustRegion(Algorithm):
399
399
  # Compute discretization before subproblem only for the first iteration
400
400
  if state.k == 1:
401
401
  t0 = time.time()
402
- _, _, _, x_prop, V_multi_shoot = self._discretization_solver.call(
403
- state.x, state.u.astype(float), params
402
+ _, _, _, x_prop, V_multi_shoot = self._invoke_solver(
403
+ self._discretization_solver, state.x, state.u.astype(float), params
404
404
  )
405
405
 
406
406
  u_state = state.u.astype(float)
407
407
  x0_prior = self._recover_prior_node_from_initial(settings, state.x[0])
408
408
  x_nodes_prior = np.vstack((x0_prior, np.asarray(x_prop)))
409
- _, _, _, W_multi_shoot = self._discretization_solver_impulsive.call(
410
- x_nodes_prior, u_state, params
409
+ _, _, _, W_multi_shoot = self._invoke_solver(
410
+ self._discretization_solver_impulsive, x_nodes_prior, u_state, params
411
411
  )
412
412
  dis_time = time.time() - t0
413
413
 
@@ -435,15 +435,15 @@ class PenalizedTrustRegion(Algorithm):
435
435
  candidate.J_lin = J_total
436
436
 
437
437
  t0 = time.time()
438
- _, _, _, x_prop, V_multi_shoot = self._discretization_solver.call(
439
- candidate.x, candidate.u.astype(float), params
438
+ _, _, _, x_prop, V_multi_shoot = self._invoke_solver(
439
+ self._discretization_solver, candidate.x, candidate.u.astype(float), params
440
440
  )
441
441
 
442
442
  u_candidate = candidate.u.astype(float)
443
443
  x0_prior = self._recover_prior_node_from_initial(settings, candidate.x[0])
444
444
  x_nodes_prior = np.vstack((x0_prior, np.asarray(x_prop)))
445
- x_prop_plus, D_d, E_d, W_multi_shoot = self._discretization_solver_impulsive.call(
446
- x_nodes_prior, u_candidate, params
445
+ x_prop_plus, D_d, E_d, W_multi_shoot = self._invoke_solver(
446
+ self._discretization_solver_impulsive, x_nodes_prior, u_candidate, params
447
447
  )
448
448
 
449
449
  dis_time = time.time() - t0
@@ -11,9 +11,9 @@ intermediate types, but the input (continuous nonlinear dynamics + reference
11
11
  trajectory) and output (discrete-time linear matrices A_d, B_d, C_d) are
12
12
  always consistent.
13
13
 
14
- The default implementation is :class:`LinearizeDiscretize`, which computes
15
- continuous-time Jacobians via JAX autodiff and integrates them alongside the
16
- nonlinear dynamics through an augmented state vector.
14
+ :class:`Problem` uses :class:`LinearizeDiscretizeSparse` by default (sparse
15
+ Jacobians and compact variational integration when sparsity patterns exist).
16
+ :class:`LinearizeDiscretize` is the dense linearize-then-discretize scheme.
17
17
  """
18
18
 
19
19
  import inspect
@@ -25,6 +25,8 @@ from .linearize_discretize import (
25
25
  calculate_impulsive_discretization,
26
26
  get_impulsive_discretization_solver,
27
27
  )
28
+ from .linearize_discretize_sparse import LinearizeDiscretizeSparse
29
+ from .sparse_utils import color_columns, make_sparse_jacobian_fns
28
30
 
29
31
  # ---------------------------------------------------------------------------
30
32
  # Spec resolver — turn a dict into a Discretizer instance
@@ -32,6 +34,7 @@ from .linearize_discretize import (
32
34
 
33
35
  _DISCRETIZER_MAP = {
34
36
  "LinearizeDiscretize": LinearizeDiscretize,
37
+ "LinearizeDiscretizeSparse": LinearizeDiscretizeSparse,
35
38
  }
36
39
 
37
40
 
@@ -41,16 +44,21 @@ def _resolve_discretizer(val: Any) -> Discretizer:
41
44
  Accepted forms:
42
45
 
43
46
  * **instance** — already-constructed :class:`Discretizer` (pass-through).
44
- * **dict** — keyword arguments passed to :class:`LinearizeDiscretize`.
45
- An optional ``"type"`` key selects the class (currently only
46
- ``"LinearizeDiscretize"``).
47
+ * **dict** — keyword arguments passed to the selected discretizer class.
48
+ An optional ``"type"`` key selects the class (defaults to
49
+ :class:`LinearizeDiscretizeSparse`).
47
50
 
48
51
  Examples::
49
52
 
50
- # Dict with keyword overrides (default class)
53
+ # Dict with keyword overrides (default class: LinearizeDiscretizeSparse)
51
54
  _resolve_discretizer({"dis_type": "ZOH", "ode_solver": "Dopri8"})
52
55
 
53
- # Dict with explicit type
56
+ # Configure integrator behavior (forwarded to Diffrax / diffeqsolve)
57
+ _resolve_discretizer(
58
+ {"diffrax_kwargs": {"num_substeps": 100, "max_steps": 20_000}}
59
+ )
60
+
61
+ # Dict with explicit dense discretizer
54
62
  _resolve_discretizer({"type": "LinearizeDiscretize", "dis_type": "ZOH"})
55
63
 
56
64
  # Instance pass-through
@@ -82,7 +90,10 @@ def _resolve_discretizer(val: Any) -> Discretizer:
82
90
  __all__ = [
83
91
  "Discretizer",
84
92
  "LinearizeDiscretize",
93
+ "LinearizeDiscretizeSparse",
85
94
  "_resolve_discretizer",
86
95
  "calculate_impulsive_discretization",
96
+ "color_columns",
87
97
  "get_impulsive_discretization_solver",
98
+ "make_sparse_jacobian_fns",
88
99
  ]
@@ -1,11 +1,16 @@
1
- from typing import TYPE_CHECKING, List, Optional
1
+ from typing import TYPE_CHECKING, Any, List, Optional
2
2
 
3
3
  import jax
4
4
  import jax.numpy as jnp
5
5
  import numpy as np
6
6
 
7
7
  from openscvx.discretization.base import Discretizer
8
- from openscvx.integrators import solve_ivp_diffrax, solve_ivp_rk45
8
+ from openscvx.integrators import (
9
+ DEFAULT_DIFFRAX_ATOL,
10
+ DEFAULT_DIFFRAX_RTOL,
11
+ solve_ivp_diffrax,
12
+ solve_ivp_rk45,
13
+ )
9
14
 
10
15
  if TYPE_CHECKING:
11
16
  from openscvx.config import Config
@@ -31,29 +36,61 @@ class LinearizeDiscretize(Discretizer):
31
36
  ode_solver: Diffrax solver name. Any solver from
32
37
  `Diffrax <https://docs.kidger.site/diffrax/usage/how-to-choose-a-solver/>`_
33
38
  is valid. Defaults to ``"Tsit5"``.
34
- custom_integrator: Use the built-in fixed-step RK45 integrator
35
- instead of Diffrax. Faster but less robust. Defaults to ``False``.
36
- atol: Absolute tolerance for the ODE solver. Defaults to ``1e-3``.
37
- rtol: Relative tolerance for the ODE solver. Defaults to ``1e-6``.
38
- args: Extra keyword arguments forwarded to
39
- :func:`diffrax.diffeqsolve`. Defaults to ``{}``.
39
+ diffrax_kwargs: Preferred Diffrax keyword overrides. These map to
40
+ :func:`openscvx.integrators.solve_ivp_diffrax` kwargs, and unknown
41
+ keys are forwarded to :func:`diffrax.diffeqsolve` (e.g.
42
+ ``stepsize_controller``). Set ``rtol``/``atol`` here when using
43
+ the default PID controller. Defaults to ``{}``.
40
44
  """
41
45
 
42
46
  def __init__(
43
47
  self,
44
48
  dis_type: str = "FOH",
45
49
  ode_solver: str = "Tsit5",
46
- custom_integrator: bool = False,
47
- atol: float = 1e-3,
48
- rtol: float = 1e-6,
49
- args: Optional[dict] = None,
50
+ diffrax_kwargs: Optional[dict[str, Any]] = None,
50
51
  ):
51
52
  self.dis_type = dis_type
52
53
  self.ode_solver = ode_solver
53
- self.custom_integrator = custom_integrator
54
- self.atol = atol
55
- self.rtol = rtol
56
- self.args = args if args is not None else {}
54
+ self.diffrax_kwargs = dict(diffrax_kwargs) if diffrax_kwargs is not None else {}
55
+
56
+ def _resolve_diffrax_kwargs(self) -> dict[str, Any]:
57
+ """Build kwargs for :func:`solve_ivp_diffrax`.
58
+
59
+ Unknown keys from ``self.diffrax_kwargs`` are forwarded to
60
+ :func:`diffrax.diffeqsolve` via ``extra_kwargs`` so users can pass
61
+ objects like ``stepsize_controller`` directly from discretizer settings.
62
+ """
63
+ kwargs: dict[str, Any] = {
64
+ "solver_name": self.ode_solver,
65
+ "rtol": DEFAULT_DIFFRAX_RTOL,
66
+ "atol": DEFAULT_DIFFRAX_ATOL,
67
+ }
68
+
69
+ user_kwargs = dict(self.diffrax_kwargs)
70
+ extra_kwargs: dict[str, Any] = {}
71
+
72
+ nested_extra = user_kwargs.pop("extra_kwargs", None)
73
+ if nested_extra is not None:
74
+ extra_kwargs.update(dict(nested_extra))
75
+
76
+ direct_keys = {"tau_0", "num_substeps", "solver_name", "rtol", "atol"}
77
+ for key, value in user_kwargs.items():
78
+ if key in direct_keys:
79
+ kwargs[key] = value
80
+ else:
81
+ extra_kwargs[key] = value
82
+
83
+ kwargs["extra_kwargs"] = extra_kwargs
84
+ return kwargs
85
+
86
+ def _resolve_rk45_kwargs(self, *, is_not_compiled: bool) -> dict[str, Any]:
87
+ """Build kwargs for :func:`solve_ivp_rk45`."""
88
+ kwargs: dict[str, Any] = {"is_not_compiled": is_not_compiled}
89
+ direct_keys = {"tau_0", "num_substeps", "is_not_compiled"}
90
+ for key, value in self.diffrax_kwargs.items():
91
+ if key in direct_keys:
92
+ kwargs[key] = value
93
+ return kwargs
57
94
 
58
95
  def get_solver(self, dynamics: "Dynamics", settings: "Config") -> callable:
59
96
  """Create a multi-shoot discretization solver.
@@ -318,25 +355,23 @@ def _calculate_discretization(
318
355
  def dVdt_wrapped(t, y):
319
356
  return _dVdt(t, y, **integrator_args)
320
357
 
321
- # Choose integrator
322
- if discretizer.custom_integrator:
358
+ if settings.dev.debug:
359
+ rk45_kwargs = discretizer._resolve_rk45_kwargs(is_not_compiled=settings.dev.debug)
323
360
  sol = solve_ivp_rk45(
324
361
  dVdt_wrapped,
325
362
  1.0 / (N - 1),
326
363
  V0,
327
364
  args=(),
328
- is_not_compiled=settings.dev.debug,
365
+ **rk45_kwargs,
329
366
  )
330
367
  else:
368
+ diffrax_kwargs = discretizer._resolve_diffrax_kwargs()
331
369
  sol = solve_ivp_diffrax(
332
370
  dVdt_wrapped,
333
371
  1.0 / (N - 1),
334
372
  V0,
335
- solver_name=discretizer.ode_solver,
336
- rtol=discretizer.rtol,
337
- atol=discretizer.atol,
338
373
  args=(),
339
- extra_kwargs=discretizer.args,
374
+ **diffrax_kwargs,
340
375
  )
341
376
 
342
377
  Vend = sol[-1].T.reshape(-1, i4)
@@ -0,0 +1,346 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ import jax
4
+ import jax.numpy as jnp
5
+ import numpy as np
6
+
7
+ from openscvx.discretization.linearize_discretize import LinearizeDiscretize
8
+ from openscvx.integrators import solve_ivp_diffrax, solve_ivp_rk45
9
+
10
+ if TYPE_CHECKING:
11
+ from openscvx.config import Config
12
+ from openscvx.lowered import Dynamics
13
+
14
+
15
+ class LinearizeDiscretizeSparse(LinearizeDiscretize):
16
+ """Sparse variant of linearize-then-discretize.
17
+
18
+ Uses graph-coloring-based sparse Jacobian computation and a compact
19
+ augmented state vector that only integrates the structurally nonzero
20
+ entries of Φ, B_d and C_d. This reduces the ODE system dimension
21
+ from ``n_x + n_x² + 2·n_x·n_u`` to ``n_x + nnz_Ad + nnz_Bd + nnz_Cd``
22
+ per segment.
23
+
24
+ Requires ``A_c_sparsity`` and ``B_c_sparsity`` boolean arrays on the
25
+ :class:`Dynamics` object (set automatically when using the symbolic
26
+ problem interface). Falls back to the dense
27
+ :class:`LinearizeDiscretize` path when sparsity patterns are
28
+ unavailable or fully dense.
29
+
30
+ Args:
31
+ dis_type: Control hold type. ``"FOH"`` or ``"ZOH"``.
32
+ Defaults to ``"FOH"``.
33
+ ode_solver: Diffrax solver name. Defaults to ``"Tsit5"``.
34
+ diffrax_kwargs: Diffrax keyword overrides inherited from
35
+ :class:`LinearizeDiscretize`. Unknown keys are forwarded to
36
+ :func:`diffrax.diffeqsolve` via ``extra_kwargs``.
37
+ """
38
+
39
+ def get_solver(self, dynamics: "Dynamics", settings: "Config") -> callable:
40
+ """Create a sparse multi-shoot discretization solver.
41
+
42
+ When ``dynamics.A_c_sparsity`` and ``dynamics.B_c_sparsity`` are
43
+ available and the pattern is not fully dense, builds a compact-V
44
+ integration path with graph-coloring Jacobians. Otherwise
45
+ delegates to the dense parent implementation.
46
+
47
+ Args:
48
+ dynamics: System dynamics with optional sparsity annotations.
49
+ settings: Problem configuration.
50
+
51
+ Returns:
52
+ Callable ``(x, u, params) -> (A_d, B_d, C_d, x_prop, V)``.
53
+ """
54
+ from openscvx.symbolic.sparsity import discrete_sparsity
55
+
56
+ from .sparse_utils import make_sparse_jacobian_fns
57
+
58
+ A_c_pat = getattr(dynamics, "A_c_sparsity", None)
59
+ B_c_pat = getattr(dynamics, "B_c_sparsity", None)
60
+ has_sparsity = A_c_pat is not None and B_c_pat is not None
61
+
62
+ if not has_sparsity or A_c_pat.all():
63
+ return super().get_solver(dynamics, settings)
64
+
65
+ f_vmapped = jax.vmap(dynamics.f, in_axes=(0, 0, 0, None))
66
+ discretizer = self
67
+ n_x = settings.sim.n_states
68
+ n_u = settings.sim.n_controls
69
+
70
+ A_vmapped, B_vmapped = make_sparse_jacobian_fns(
71
+ dynamics.f,
72
+ A_c_pat,
73
+ B_c_pat,
74
+ n_x,
75
+ n_u,
76
+ )
77
+
78
+ Ad_pat, Bd_pat, Cd_pat = discrete_sparsity(
79
+ A_c_pat,
80
+ B_c_pat,
81
+ self.dis_type,
82
+ )
83
+ Ad_r, Ad_c = np.where(Ad_pat)
84
+ Bd_r, Bd_c = np.where(Bd_pat)
85
+ Cd_r, Cd_c = np.where(Cd_pat)
86
+
87
+ sparse_layout = (
88
+ jnp.array(Ad_r),
89
+ jnp.array(Ad_c),
90
+ len(Ad_r),
91
+ jnp.array(Bd_r),
92
+ jnp.array(Bd_c),
93
+ len(Bd_r),
94
+ jnp.array(Cd_r),
95
+ jnp.array(Cd_c),
96
+ len(Cd_r),
97
+ )
98
+
99
+ return lambda x, u, params: _calculate_discretization_sparse(
100
+ x=x,
101
+ u=u,
102
+ state_dot=f_vmapped,
103
+ A=A_vmapped,
104
+ B=B_vmapped,
105
+ settings=settings,
106
+ discretizer=discretizer,
107
+ params=params,
108
+ sparse_layout=sparse_layout,
109
+ )
110
+
111
+
112
+ def _dVdt_sparse(
113
+ tau: float,
114
+ V: jnp.ndarray,
115
+ u_cur: np.ndarray,
116
+ u_next: np.ndarray,
117
+ state_dot: callable,
118
+ A: callable,
119
+ B: callable,
120
+ n_x: int,
121
+ n_u: int,
122
+ N: int,
123
+ dis_type: str,
124
+ S_x: np.ndarray,
125
+ c_x: np.ndarray,
126
+ S_u: np.ndarray,
127
+ c_u: np.ndarray,
128
+ inv_S_x: np.ndarray,
129
+ inv_S_u: np.ndarray,
130
+ params: dict,
131
+ Ad_rows: jnp.ndarray,
132
+ Ad_cols: jnp.ndarray,
133
+ nnz_Ad: int,
134
+ Bd_rows: jnp.ndarray,
135
+ Bd_cols: jnp.ndarray,
136
+ nnz_Bd: int,
137
+ Cd_rows: jnp.ndarray,
138
+ Cd_cols: jnp.ndarray,
139
+ nnz_Cd: int,
140
+ ) -> jnp.ndarray:
141
+ """Time derivative of the *compact* augmented state for sparse variational integration.
142
+
143
+ Instead of storing the full flattened Φ, B_d, C_d matrices (``n_x²`` and
144
+ ``n_x·n_u`` entries each), this function only tracks the structurally
145
+ nonzero entries as determined by ``discrete_sparsity``.
146
+
147
+ The compact layout per segment is::
148
+
149
+ V = [x(n_x), Φ_nz(nnz_Ad), B_d_nz(nnz_Bd), C_d_nz(nnz_Cd)]
150
+
151
+ At each evaluation the compact values are scattered into dense matrices
152
+ for the matmul, and the derivative is gathered back at the nonzero
153
+ positions.
154
+
155
+ Args:
156
+ tau: Normalized time in [0, 1] within the current segment.
157
+ V: Flattened compact augmented state, shape
158
+ ``((N-1) * (n_x + nnz_Ad + nnz_Bd + nnz_Cd),)``.
159
+ Ad_rows, Ad_cols: Row/column indices of A_d structural nonzeros.
160
+ nnz_Ad: Number of A_d structural nonzeros.
161
+ Bd_rows, Bd_cols: Row/column indices of B_d structural nonzeros.
162
+ nnz_Bd: Number of B_d structural nonzeros.
163
+ Cd_rows, Cd_cols: Row/column indices of C_d structural nonzeros.
164
+ nnz_Cd: Number of C_d structural nonzeros.
165
+ (remaining args identical to :func:`_dVdt`)
166
+
167
+ Returns:
168
+ Flattened time derivative of the compact augmented state.
169
+ """
170
+ nodes = jnp.arange(0, N - 1)
171
+
172
+ aug_dim = n_x + nnz_Ad + nnz_Bd + nnz_Cd
173
+ i_phi = n_x
174
+ i_bd = n_x + nnz_Ad
175
+ i_cd = n_x + nnz_Ad + nnz_Bd
176
+
177
+ V = V.reshape(-1, aug_dim)
178
+
179
+ if dis_type == "ZOH":
180
+ beta = 0.0
181
+ elif dis_type == "FOH":
182
+ beta = tau * N
183
+ alpha = 1 - beta
184
+
185
+ u = u_cur + beta * (u_next - u_cur)
186
+ x = V[:, :n_x]
187
+ u = u[: x.shape[0]]
188
+ batch = x.shape[0]
189
+
190
+ F = state_dot(x, u, nodes, params)
191
+ dfdx = A(x, u, nodes, params)
192
+ dfdu = B(x, u, nodes, params)
193
+
194
+ # Φ: scatter compact → dense, matmul, gather back
195
+ phi_nz = V[:, i_phi:i_bd]
196
+ Phi = jnp.zeros((batch, n_x, n_x)).at[:, Ad_rows, Ad_cols].set(phi_nz)
197
+ dPhi_nz = jnp.matmul(dfdx, Phi)[:, Ad_rows, Ad_cols]
198
+
199
+ # B_d: scatter, matmul + forcing, gather
200
+ bd_nz = V[:, i_bd:i_cd]
201
+ Bd = jnp.zeros((batch, n_x, n_u)).at[:, Bd_rows, Bd_cols].set(bd_nz)
202
+ dBd_nz = (jnp.matmul(dfdx, Bd) + dfdu * alpha)[:, Bd_rows, Bd_cols]
203
+
204
+ # C_d: scatter, matmul + forcing, gather
205
+ cd_nz = V[:, i_cd:]
206
+ Cd = jnp.zeros((batch, n_x, n_u)).at[:, Cd_rows, Cd_cols].set(cd_nz)
207
+ dCd_nz = (jnp.matmul(dfdx, Cd) + dfdu * beta)[:, Cd_rows, Cd_cols]
208
+
209
+ return jnp.concatenate([F, dPhi_nz, dBd_nz, dCd_nz], axis=-1).reshape(-1)
210
+
211
+
212
+ def _calculate_discretization_sparse(
213
+ x: np.ndarray,
214
+ u: np.ndarray,
215
+ state_dot: callable,
216
+ A: callable,
217
+ B: callable,
218
+ settings: "Config",
219
+ discretizer: "LinearizeDiscretizeSparse",
220
+ params: dict,
221
+ sparse_layout: tuple,
222
+ ) -> tuple[jnp.ndarray, jnp.ndarray, jnp.ndarray, jnp.ndarray, jnp.ndarray]:
223
+ """Integrate the compact variational equations to produce discrete-time matrices.
224
+
225
+ Uses the structurally nonzero entries of Φ, B_d and C_d to form a
226
+ reduced augmented state, integrates with :func:`_dVdt_sparse`, then
227
+ scatters the results back into dense matrices for downstream
228
+ compatibility.
229
+
230
+ Args:
231
+ x: Reference state trajectory, shape ``(N, n_x)``.
232
+ u: Reference control trajectory, shape ``(N, n_u)``.
233
+ state_dot: Vmapped time-dilated dynamics.
234
+ A: Vmapped state Jacobian ``∂F/∂x``.
235
+ B: Vmapped control Jacobian ``∂F/∂u``.
236
+ settings: Problem configuration.
237
+ discretizer: Discretizer instance with integrator settings.
238
+ params: Parameters forwarded to dynamics callables.
239
+ sparse_layout: Tuple
240
+ ``(Ad_rows, Ad_cols, nnz_Ad, Bd_rows, Bd_cols, nnz_Bd,
241
+ Cd_rows, Cd_cols, nnz_Cd)``.
242
+
243
+ Returns:
244
+ Tuple ``(A_d, B_d, C_d, x_prop, V)``.
245
+ """
246
+ n_x = settings.sim.n_states
247
+ n_u = settings.sim.n_controls
248
+ N = settings.sim.n
249
+
250
+ (
251
+ Ad_rows,
252
+ Ad_cols,
253
+ nnz_Ad,
254
+ Bd_rows,
255
+ Bd_cols,
256
+ nnz_Bd,
257
+ Cd_rows,
258
+ Cd_cols,
259
+ nnz_Cd,
260
+ ) = sparse_layout
261
+
262
+ aug_dim = n_x + nnz_Ad + nnz_Bd + nnz_Cd
263
+
264
+ V0 = jnp.zeros((N - 1, aug_dim))
265
+ V0 = V0.at[:, :n_x].set(x[:-1].astype(float))
266
+ phi0_nz = (Ad_rows == Ad_cols).astype(x.dtype)
267
+ V0 = V0.at[:, n_x : n_x + nnz_Ad].set(jnp.broadcast_to(phi0_nz[None], (N - 1, nnz_Ad)))
268
+ V0 = V0.reshape(-1)
269
+
270
+ integrator_args = dict(
271
+ u_cur=u[:-1].astype(float),
272
+ u_next=u[1:].astype(float),
273
+ state_dot=state_dot,
274
+ A=A,
275
+ B=B,
276
+ n_x=n_x,
277
+ n_u=n_u,
278
+ N=N,
279
+ dis_type=discretizer.dis_type,
280
+ S_x=settings.sim.S_x,
281
+ c_x=settings.sim.c_x,
282
+ S_u=settings.sim.S_u,
283
+ c_u=settings.sim.c_u,
284
+ inv_S_x=settings.sim.inv_S_x,
285
+ inv_S_u=settings.sim.inv_S_u,
286
+ params=params,
287
+ Ad_rows=Ad_rows,
288
+ Ad_cols=Ad_cols,
289
+ nnz_Ad=nnz_Ad,
290
+ Bd_rows=Bd_rows,
291
+ Bd_cols=Bd_cols,
292
+ nnz_Bd=nnz_Bd,
293
+ Cd_rows=Cd_rows,
294
+ Cd_cols=Cd_cols,
295
+ nnz_Cd=nnz_Cd,
296
+ )
297
+
298
+ def dVdt_wrapped(t, y):
299
+ return _dVdt_sparse(t, y, **integrator_args)
300
+
301
+ if settings.dev.debug:
302
+ rk45_kwargs = discretizer._resolve_rk45_kwargs(is_not_compiled=settings.dev.debug)
303
+ sol = solve_ivp_rk45(
304
+ dVdt_wrapped,
305
+ 1.0 / (N - 1),
306
+ V0,
307
+ args=(),
308
+ **rk45_kwargs,
309
+ )
310
+ else:
311
+ diffrax_kwargs = discretizer._resolve_diffrax_kwargs()
312
+ sol = solve_ivp_diffrax(
313
+ dVdt_wrapped,
314
+ 1.0 / (N - 1),
315
+ V0,
316
+ args=(),
317
+ **diffrax_kwargs,
318
+ )
319
+
320
+ Vend = sol[-1].T.reshape(-1, aug_dim)
321
+
322
+ x_prop = Vend[:, :n_x]
323
+ phi_nz = Vend[:, n_x : n_x + nnz_Ad]
324
+ bd_nz = Vend[:, n_x + nnz_Ad : n_x + nnz_Ad + nnz_Bd]
325
+ cd_nz = Vend[:, n_x + nnz_Ad + nnz_Bd :]
326
+
327
+ A_bar = jnp.zeros((N - 1, n_x, n_x)).at[:, Ad_rows, Ad_cols].set(phi_nz)
328
+ B_bar = jnp.zeros((N - 1, n_x, n_u)).at[:, Bd_rows, Bd_cols].set(bd_nz)
329
+ C_bar = jnp.zeros((N - 1, n_x, n_u))
330
+ if nnz_Cd > 0:
331
+ C_bar = C_bar.at[:, Cd_rows, Cd_cols].set(cd_nz)
332
+
333
+ # Reconstruct a dense-layout Vmulti so that
334
+ # DiscretizationResult.from_V can unpack it unchanged.
335
+ Vend_dense = jnp.concatenate(
336
+ [
337
+ x_prop,
338
+ A_bar.reshape(N - 1, n_x * n_x),
339
+ B_bar.reshape(N - 1, n_x * n_u),
340
+ C_bar.reshape(N - 1, n_x * n_u),
341
+ ],
342
+ axis=-1,
343
+ )
344
+ Vmulti = Vend_dense.reshape(-1, 1)
345
+
346
+ return A_bar, B_bar, C_bar, x_prop, Vmulti
@@ -0,0 +1,11 @@
1
+ """Sparse linear algebra helpers built on ``jax.experimental.sparse``."""
2
+
3
+ from .bcoo_helpers import precompute_sparse_indices, sparse_matmul_batched
4
+ from .sparse_jacobian import color_columns, make_sparse_jacobian_fns
5
+
6
+ __all__ = [
7
+ "color_columns",
8
+ "make_sparse_jacobian_fns",
9
+ "precompute_sparse_indices",
10
+ "sparse_matmul_batched",
11
+ ]