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.
- {openscvx-0.4.1.dev153/openscvx.egg-info → openscvx-0.4.1.dev155}/PKG-INFO +1 -1
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/__init__.py +2 -1
- openscvx-0.4.1.dev155/openscvx/_version.py +24 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/penalized_trust_region.py +10 -10
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/discretization/__init__.py +19 -8
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/discretization/linearize_discretize.py +58 -23
- openscvx-0.4.1.dev155/openscvx/discretization/linearize_discretize_sparse.py +346 -0
- openscvx-0.4.1.dev155/openscvx/discretization/sparse_utils/__init__.py +11 -0
- openscvx-0.4.1.dev155/openscvx/discretization/sparse_utils/bcoo_helpers.py +63 -0
- openscvx-0.4.1.dev155/openscvx/discretization/sparse_utils/sparse_jacobian.py +177 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/integrators/__init__.py +8 -2
- openscvx-0.4.1.dev155/openscvx/integrators/diffrax.py +151 -0
- openscvx-0.4.1.dev155/openscvx/integrators/runge_kutta.py +88 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/dynamics.py +10 -1
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/problem.py +19 -7
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/propagation/propagation.py +9 -1
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lower.py +5 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/caching.py +28 -11
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155/openscvx.egg-info}/PKG-INFO +1 -1
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/SOURCES.txt +5 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_brachistochrone.py +2 -0
- openscvx-0.4.1.dev155/tests/test_discretization.py +420 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_examples.py +0 -4
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_integrators.py +22 -0
- openscvx-0.4.1.dev153/openscvx/_version.py +0 -34
- openscvx-0.4.1.dev153/openscvx/integrators/runge_kutta.py +0 -281
- openscvx-0.4.1.dev153/tests/test_discretization.py +0 -132
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/release-drafter.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/_docs.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/branch-name.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/docs.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/lint.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/nightly.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/release-drafter.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/release.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/tests-integration.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.github/workflows/tests-unit.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/.gitignore +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/CONTRIBUTING.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/LICENSE +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/README.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/constraint_reformulation.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/control_parameterization.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/discretization.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/ocp.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/scvx.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/Foundations/time_dilation.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UnderTheHood/lowering_architecture.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/00_introduction.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/05_visualization.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/06_logic.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/07_lie.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/UsersGuide/08_mpcc.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/favicon.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/ct-scvx_dark.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/ct-scvx_light.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/ctcs_dark.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/ctcs_light.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/problem_class_dark.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/images/problem_class_light.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/citation.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/examples.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/getting-started.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/index.md +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/docs/javascripts/mathjax.js +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/abstract/brachistochrone.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/abstract/impulsive.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/abstract/stl_integer_variable.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/abstract/stl_or.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/arm/three_link_arm.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_disjoint.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_obstacle_conditional.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_obstacle_stl.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_stl_or.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/car/dubins_car_waypoint_stl.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/cinema_vp.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/dr_double_integrator.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/dr_vp.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/dr_vp_nodal.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/dr_vp_polytope.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/drone_racing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/logo.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/logo_utils/acl_logo.svg +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/logo_utils/svg_path_utils.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/obstacle_avoidance.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/obstacle_avoidance_nodal.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/drone/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/double_integrator_discrete.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/double_integrator_drone_racing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/dubins_car_circle_analytical.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/dubins_car_circle_discrete.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/plotting.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/plotting_viser.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/cinema_vp_realtime.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/drone_racing_realtime.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/dubins_car_realtime.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/rocket/3DoF_pdg.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/spacecraft/hohmann_transfer.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/examples/spacecraft/proxops_cw.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/ctlos_cine.gif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/ctlos_dr.gif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/dtlos_cine.gif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/dtlos_dr.gif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/openscvx_logo.svg +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/openscvx_logo_square.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/oscvx_structure_full_dark.svg +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/figures/video_preview.png +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background@1x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background@2x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background@3x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/1-background@4x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars@1x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars@2x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars@3x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/2-mars@4x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon@1x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon@2x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon@3x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/3-moon@4x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1@1x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1@2x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1@3x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/4-sat1@4x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space@1x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space@2x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space@3x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/5-space@4x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth@1x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth@2x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth@3x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/images/layers/6-earth@4x.avif +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/javascripts/parallax.js +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/stylesheets/custom.css +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/assets/stylesheets/parallax.css +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/home.html +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/main.html +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/partials/parallax/hero.html +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/material/overrides/partials/parallax.html +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/mkdocs.yml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/__main__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/augmented_lagrangian.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/base.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/constant_proximal_weight.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/optimization_results.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/ramp_proximal_weight.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/config.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/discretization/base.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/expert/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/expert/byof.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/expert/lowering.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/expert/validation.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/init/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/init/interpolation.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/loader.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/cvxpy_constraints.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/cvxpy_variables.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/jax_constraints.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/parameters.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/problem.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/lowered/unified.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/plotting.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/scp_iteration.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/animated.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/orbits.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/plotly_integration.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/primitives.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/scp.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/plotting/viser/server.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/propagation/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/propagation/post_processing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/solvers/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/solvers/base.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/solvers/ptr_solver.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/augmentation.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/builder.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/constraint_set.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/arithmetic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/array.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/constraint.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/control.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/expr.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/lie/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/lie/se3.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/lie/so3.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/linalg.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/logic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/math.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/spatial.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/state.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/stl.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/stljax.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/time.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/variable.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/expr/vmap.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/hashing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/array.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/control.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/math.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/state.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/_registry.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/array.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/constraint.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/lie.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/linalg.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/logic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/math.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/parser.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/spatial.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/stl.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/stljax.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/parser/tokenizer.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/preprocessing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/problem.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/sparsity.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/symbolic/unified.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/cache.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/printing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/profiling.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/utils/utils.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/dependency_links.txt +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/entry_points.txt +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/requires.txt +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx.egg-info/top_level.txt +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/pyproject.toml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/scripts/gen_example_pages.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/scripts/gen_ref_pages.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/setup.cfg +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/brachistochrone_analytical.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/expr/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/expr/test_gmsr.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/fixtures/brachistochrone.json +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/fixtures/brachistochrone.yaml +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/hohmann_analytical.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_arithmetic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_array.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_constraint.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_expr.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_lie.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_linalg.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_logic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_math.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_node_reference.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_parameters.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_scaling.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_spatial.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_stl.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_variable.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/expr/test_vmap.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/__init__.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_array.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_constraint.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_lie.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_linalg.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_load.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_logic.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_math.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_parser.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_spatial.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_stl.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_tokenizer.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/parser/test_vmap.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_augmentation.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_hashing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_lower_cvxpy.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_lower_jax.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_preprocessing.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_sparsity.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/symbolic/test_unified.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_autotuning.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_cvxpygen_optional.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_expert.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_impulsive.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_init.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_loader.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_optimization_results.py +0 -0
- {openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/tests/test_plotting.py +0 -0
- {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.
|
|
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'
|
{openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/algorithms/penalized_trust_region.py
RENAMED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
45
|
-
An optional ``"type"`` key selects the class (
|
|
46
|
-
|
|
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
|
-
#
|
|
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
|
]
|
{openscvx-0.4.1.dev153 → openscvx-0.4.1.dev155}/openscvx/discretization/linearize_discretize.py
RENAMED
|
@@ -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
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
322
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
]
|