openscvx 0.4.1.dev144__tar.gz → 0.4.1.dev146__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.dev144/openscvx.egg-info → openscvx-0.4.1.dev146}/PKG-INFO +1 -1
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/_version.py +3 -3
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/algorithms/__init__.py +11 -3
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/algorithms/augmented_lagrangian.py +7 -5
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/algorithms/base.py +312 -13
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/algorithms/optimization_results.py +1 -1
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/algorithms/penalized_trust_region.py +50 -20
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/algorithms/ramp_proximal_weight.py +4 -2
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/lowered/cvxpy_variables.py +1 -1
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/scp_iteration.py +3 -2
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/problem.py +7 -3
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/solvers/ptr_solver.py +5 -4
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lower.py +1 -1
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146/openscvx.egg-info}/PKG-INFO +1 -1
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_autotuning.py +35 -36
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_optimization_results.py +1 -1
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/release-drafter.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/_docs.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/branch-name.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/docs.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/lint.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/nightly.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/release-drafter.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/release.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/tests-integration.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.github/workflows/tests-unit.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/.gitignore +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/CONTRIBUTING.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/LICENSE +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/README.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/Foundations/constraint_reformulation.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/Foundations/control_parameterization.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/Foundations/discretization.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/Foundations/ocp.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/Foundations/scvx.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/Foundations/time_dilation.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UnderTheHood/lowering_architecture.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UsersGuide/00_introduction.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UsersGuide/05_visualization.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UsersGuide/06_logic.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/UsersGuide/07_lie.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/assets/favicon.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/assets/images/ct-scvx_dark.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/assets/images/ct-scvx_light.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/assets/images/ctcs_dark.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/assets/images/ctcs_light.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/assets/images/problem_class_dark.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/assets/images/problem_class_light.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/citation.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/examples.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/getting-started.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/index.md +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/docs/javascripts/mathjax.js +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/abstract/brachistochrone.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/abstract/impulsive.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/arm/three_link_arm.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/car/dubins_car.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/car/dubins_car_conditional.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/car/dubins_car_disjoint.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/car/dubins_car_stljax.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/cinema_vp.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/dr_double_integrator.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/dr_vp.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/dr_vp_nodal.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/dr_vp_polytope.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/drone_racing.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/logo.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/logo_utils/acl_logo.svg +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/logo_utils/svg_path_utils.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/obstacle_avoidance.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/obstacle_avoidance_nodal.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/drone/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/plotting.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/plotting_viser.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/realtime/cinema_vp_realtime.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/realtime/drone_racing_realtime.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/realtime/dubins_car_realtime.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/rocket/3DoF_pdg.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/spacecraft/hohmann_transfer.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/examples/spacecraft/proxops_cw.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/figures/ctlos_cine.gif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/figures/ctlos_dr.gif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/figures/dtlos_cine.gif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/figures/dtlos_dr.gif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/figures/openscvx_logo.svg +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/figures/openscvx_logo_square.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/figures/oscvx_structure_full_dark.svg +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/figures/video_preview.png +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/1-background.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/1-background@1x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/1-background@2x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/1-background@3x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/1-background@4x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/2-mars.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/2-mars@1x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/2-mars@2x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/2-mars@3x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/2-mars@4x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/3-moon.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/3-moon@1x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/3-moon@2x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/3-moon@3x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/3-moon@4x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/4-sat1.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/4-sat1@1x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/4-sat1@2x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/4-sat1@3x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/4-sat1@4x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/5-space.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/5-space@1x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/5-space@2x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/5-space@3x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/5-space@4x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/6-earth.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/6-earth@1x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/6-earth@2x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/6-earth@3x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/images/layers/6-earth@4x.avif +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/javascripts/parallax.js +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/stylesheets/custom.css +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/assets/stylesheets/parallax.css +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/home.html +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/main.html +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/partials/parallax/hero.html +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/material/overrides/partials/parallax.html +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/mkdocs.yml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/__main__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/algorithms/constant_proximal_weight.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/config.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/discretization/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/discretization/base.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/discretization/linearize_discretize.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/expert/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/expert/byof.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/expert/lowering.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/expert/validation.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/init/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/init/interpolation.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/integrators/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/integrators/runge_kutta.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/loader.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/lowered/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/lowered/cvxpy_constraints.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/lowered/dynamics.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/lowered/jax_constraints.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/lowered/parameters.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/lowered/problem.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/lowered/unified.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/plotting.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/viser/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/viser/animated.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/viser/orbits.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/viser/plotly_integration.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/viser/primitives.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/viser/scp.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/plotting/viser/server.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/propagation/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/propagation/post_processing.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/propagation/propagation.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/solvers/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/solvers/base.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/augmentation.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/builder.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/constraint_set.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/arithmetic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/array.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/constraint.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/control.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/expr.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/lie/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/lie/se3.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/lie/so3.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/linalg.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/logic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/math.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/spatial.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/state.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/stl.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/time.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/variable.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/expr/vmap.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/hashing.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/array.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/control.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/math.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/state.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/_registry.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/array.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/constraint.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/lie.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/linalg.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/logic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/math.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/parser.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/spatial.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/stl.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/parser/tokenizer.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/preprocessing.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/problem.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/sparsity.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/symbolic/unified.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/utils/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/utils/cache.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/utils/caching.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/utils/printing.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/utils/profiling.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx/utils/utils.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx.egg-info/SOURCES.txt +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx.egg-info/dependency_links.txt +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx.egg-info/entry_points.txt +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx.egg-info/requires.txt +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/openscvx.egg-info/top_level.txt +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/pyproject.toml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/scripts/gen_example_pages.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/scripts/gen_ref_pages.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/setup.cfg +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/brachistochrone_analytical.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/fixtures/brachistochrone.json +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/fixtures/brachistochrone.yaml +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/hohmann_analytical.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_arithmetic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_array.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_constraint.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_expr.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_lie.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_linalg.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_logic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_math.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_node_reference.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_parameters.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_scaling.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_spatial.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_variable.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/expr/test_vmap.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/__init__.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_array.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_constraint.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_lie.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_linalg.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_load.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_logic.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_math.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_parser.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_spatial.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_stl.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_tokenizer.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/parser/test_vmap.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/test_augmentation.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/test_hashing.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/test_lower_cvxpy.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/test_lower_jax.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/test_preprocessing.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/test_sparsity.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/symbolic/test_unified.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_brachistochrone.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_cvxpygen_optional.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_discretization.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_examples.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_expert.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_impulsive.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_init.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_integrators.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_loader.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/tests/test_plotting.py +0 -0
- {openscvx-0.4.1.dev144 → openscvx-0.4.1.dev146}/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.dev146
|
|
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
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.4.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 4, 1, '
|
|
31
|
+
__version__ = version = '0.4.1.dev146'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 4, 1, 'dev146')
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g66b4191a1'
|
|
@@ -140,7 +140,9 @@ def _resolve_autotuner(val: Any) -> Any:
|
|
|
140
140
|
raise TypeError(f"Invalid autotuner keyword argument: {e}. Valid keys: {valid}") from None
|
|
141
141
|
|
|
142
142
|
|
|
143
|
-
def _resolve_algorithm(
|
|
143
|
+
def _resolve_algorithm(
|
|
144
|
+
kwargs: dict, states: list = None, controls: list = None
|
|
145
|
+
) -> "PenalizedTrustRegion":
|
|
144
146
|
"""Build a :class:`PenalizedTrustRegion` from a user-supplied dict.
|
|
145
147
|
|
|
146
148
|
Supports a nested ``autotuner`` key that is resolved via
|
|
@@ -149,7 +151,11 @@ def _resolve_algorithm(kwargs: dict, states: list = None) -> "PenalizedTrustRegi
|
|
|
149
151
|
Args:
|
|
150
152
|
kwargs: Algorithm keyword arguments (e.g. ``lam_cost``, ``autotuner``).
|
|
151
153
|
states: Symbolic State objects, forwarded to the algorithm constructor
|
|
152
|
-
so that dict-valued ``lam_cost`` can be expanded
|
|
154
|
+
so that dict-valued ``lam_cost`` / ``lam_prox`` can be expanded
|
|
155
|
+
immediately.
|
|
156
|
+
controls: Symbolic Control objects, forwarded to the algorithm
|
|
157
|
+
constructor so that dict-valued ``lam_prox`` can be expanded
|
|
158
|
+
immediately.
|
|
153
159
|
"""
|
|
154
160
|
kwargs = dict(kwargs) # copy to avoid mutating the caller's dict
|
|
155
161
|
|
|
@@ -157,9 +163,11 @@ def _resolve_algorithm(kwargs: dict, states: list = None) -> "PenalizedTrustRegi
|
|
|
157
163
|
if "autotuner" in kwargs:
|
|
158
164
|
kwargs["autotuner"] = _resolve_autotuner(kwargs["autotuner"])
|
|
159
165
|
|
|
160
|
-
# Forward states so dict
|
|
166
|
+
# Forward states/controls so dict weights can be expanded eagerly
|
|
161
167
|
if states is not None:
|
|
162
168
|
kwargs.setdefault("states", states)
|
|
169
|
+
if controls is not None:
|
|
170
|
+
kwargs.setdefault("controls", controls)
|
|
163
171
|
|
|
164
172
|
try:
|
|
165
173
|
return PenalizedTrustRegion(**kwargs)
|
|
@@ -116,7 +116,7 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
116
116
|
candidate_x_prop: np.ndarray,
|
|
117
117
|
settings: Config,
|
|
118
118
|
lam_vc: np.ndarray,
|
|
119
|
-
lam_prox:
|
|
119
|
+
lam_prox: np.ndarray,
|
|
120
120
|
) -> np.ndarray:
|
|
121
121
|
"""Update virtual control penalty weights from state violation.
|
|
122
122
|
|
|
@@ -126,7 +126,9 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
126
126
|
"""
|
|
127
127
|
nu = (settings.sim.inv_S_x @ abs(candidate.x[1:] - candidate_x_prop).T).T
|
|
128
128
|
mask = nu > self.ep
|
|
129
|
-
|
|
129
|
+
# TODO: (haynec) use per-variable lam_prox to scale VC updates proportionally
|
|
130
|
+
lam_prox_scalar = float(np.max(lam_prox))
|
|
131
|
+
scale = self.eta_lambda * (1 / (2 * lam_prox_scalar))
|
|
130
132
|
case1 = lam_vc + nu * scale
|
|
131
133
|
case2 = lam_vc + (nu**2) / self.ep * scale
|
|
132
134
|
vc_new = np.where(mask, case1, case2)
|
|
@@ -222,12 +224,12 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
222
224
|
|
|
223
225
|
if rho < self.eta_0:
|
|
224
226
|
# Reject Solution and higher weight
|
|
225
|
-
lam_prox_k1 =
|
|
227
|
+
lam_prox_k1 = np.minimum(self.lam_prox_max, self.gamma_1 * lam_prox_k)
|
|
226
228
|
state.lam_prox_history.append(lam_prox_k1)
|
|
227
229
|
adaptive_state = "Reject Higher"
|
|
228
230
|
elif rho >= self.eta_0 and rho < self.eta_1:
|
|
229
231
|
# Accept Solution with heigher weight
|
|
230
|
-
lam_prox_k1 =
|
|
232
|
+
lam_prox_k1 = np.minimum(self.lam_prox_max, self.gamma_1 * lam_prox_k)
|
|
231
233
|
state.lam_prox_history.append(lam_prox_k1)
|
|
232
234
|
|
|
233
235
|
# Update virtual control weight matrix
|
|
@@ -255,7 +257,7 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
255
257
|
adaptive_state = "Accept Constant"
|
|
256
258
|
else:
|
|
257
259
|
# Accept Solution with lower weight
|
|
258
|
-
lam_prox_k1 =
|
|
260
|
+
lam_prox_k1 = np.maximum(self.lam_prox_min, self.gamma_2 * lam_prox_k)
|
|
259
261
|
state.lam_prox_history.append(lam_prox_k1)
|
|
260
262
|
# Update virtual control weight matrix
|
|
261
263
|
candidate.lam_vc = self._update_virtual_control_weights(
|
|
@@ -17,6 +17,7 @@ if TYPE_CHECKING:
|
|
|
17
17
|
from openscvx.config import Config
|
|
18
18
|
from openscvx.lowered.jax_constraints import LoweredJaxConstraints
|
|
19
19
|
from openscvx.solvers import ConvexSolver
|
|
20
|
+
from openscvx.symbolic.expr.control import Control
|
|
20
21
|
from openscvx.symbolic.expr.state import State
|
|
21
22
|
|
|
22
23
|
|
|
@@ -101,6 +102,207 @@ def _expand_lam_cost_dict(
|
|
|
101
102
|
return lam_arr
|
|
102
103
|
|
|
103
104
|
|
|
105
|
+
def _expand_lam_vc_dict(
|
|
106
|
+
lam_vc_dict: Dict[str, Union[float, list, np.ndarray]],
|
|
107
|
+
states: List["State"],
|
|
108
|
+
) -> np.ndarray:
|
|
109
|
+
"""Expand a ``{state_name: weight}`` dict to a per-state VC weight array.
|
|
110
|
+
|
|
111
|
+
Maps user-provided per-state virtual control weights to a dense array
|
|
112
|
+
using each state's ``_slice``. States not present in the dict default
|
|
113
|
+
to ``1.0`` (neutral weight — dynamics violations are still penalised at
|
|
114
|
+
the base rate).
|
|
115
|
+
|
|
116
|
+
Per-state values may be:
|
|
117
|
+
|
|
118
|
+
* **scalar** — broadcast to every component and every node.
|
|
119
|
+
* **1-D array** of length ``n_components`` — per-component weight,
|
|
120
|
+
same for every node.
|
|
121
|
+
* **2-D array** of shape ``(K, n_components)`` — per-node-per-component.
|
|
122
|
+
When any state supplies a 2-D value the output is 2-D with first
|
|
123
|
+
dimension *K* (all 2-D entries must agree on *K*).
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
lam_vc_dict: Mapping from state names to VC weights.
|
|
127
|
+
states: List of State objects (must already have ``_slice`` assigned).
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
np.ndarray of shape ``(n_states,)`` when all entries are scalar/1-D,
|
|
131
|
+
or ``(K, n_states)`` when any entry is 2-D.
|
|
132
|
+
|
|
133
|
+
Raises:
|
|
134
|
+
ValueError: If the dict contains unknown state names or 2-D entries
|
|
135
|
+
disagree on the number of nodes.
|
|
136
|
+
"""
|
|
137
|
+
n_states = sum(s.shape[0] if len(s.shape) > 0 else 1 for s in states)
|
|
138
|
+
|
|
139
|
+
valid_names = {s.name for s in states}
|
|
140
|
+
unknown = set(lam_vc_dict.keys()) - valid_names
|
|
141
|
+
if unknown:
|
|
142
|
+
raise ValueError(
|
|
143
|
+
f"lam_vc dict contains unknown state name(s): {unknown}. "
|
|
144
|
+
f"Valid state names: {sorted(valid_names)}"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# First pass: determine if any entry is 2-D and infer K.
|
|
148
|
+
n_nodes: Optional[int] = None
|
|
149
|
+
for state in states:
|
|
150
|
+
if state.name not in lam_vc_dict:
|
|
151
|
+
continue
|
|
152
|
+
val = np.asarray(lam_vc_dict[state.name], dtype=float)
|
|
153
|
+
if val.ndim == 2:
|
|
154
|
+
if n_nodes is None:
|
|
155
|
+
n_nodes = val.shape[0]
|
|
156
|
+
elif val.shape[0] != n_nodes:
|
|
157
|
+
raise ValueError(
|
|
158
|
+
f"lam_vc['{state.name}'] has {val.shape[0]} rows, but a "
|
|
159
|
+
f"previous entry had {n_nodes} rows. All 2-D entries "
|
|
160
|
+
f"must have the same number of rows (n_nodes-1)."
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Build the output array.
|
|
164
|
+
if n_nodes is not None:
|
|
165
|
+
lam_arr = np.ones((n_nodes, n_states))
|
|
166
|
+
else:
|
|
167
|
+
lam_arr = np.ones(n_states)
|
|
168
|
+
|
|
169
|
+
for state in states:
|
|
170
|
+
if state.name not in lam_vc_dict:
|
|
171
|
+
continue
|
|
172
|
+
val = np.asarray(lam_vc_dict[state.name], dtype=float)
|
|
173
|
+
n_components = state.shape[0] if len(state.shape) > 0 else 1
|
|
174
|
+
|
|
175
|
+
if val.ndim == 0:
|
|
176
|
+
# Scalar — broadcast to all components (and all nodes if 2-D).
|
|
177
|
+
lam_arr[..., state._slice] = float(val)
|
|
178
|
+
elif val.ndim == 1:
|
|
179
|
+
if val.shape[0] != n_components:
|
|
180
|
+
raise ValueError(
|
|
181
|
+
f"lam_vc['{state.name}'] has length {val.shape[0]}, "
|
|
182
|
+
f"expected scalar or length {n_components}"
|
|
183
|
+
)
|
|
184
|
+
lam_arr[..., state._slice] = val
|
|
185
|
+
elif val.ndim == 2:
|
|
186
|
+
if val.shape[1] != n_components:
|
|
187
|
+
raise ValueError(
|
|
188
|
+
f"lam_vc['{state.name}'] has {val.shape[1]} columns, expected {n_components}"
|
|
189
|
+
)
|
|
190
|
+
lam_arr[:, state._slice] = val
|
|
191
|
+
else:
|
|
192
|
+
raise ValueError(
|
|
193
|
+
f"lam_vc['{state.name}'] has {val.ndim} dimensions, expected scalar, 1-D, or 2-D"
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
return lam_arr
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _expand_lam_prox_dict(
|
|
200
|
+
lam_prox_dict: Dict[str, Union[float, list, np.ndarray]],
|
|
201
|
+
states: List["State"],
|
|
202
|
+
controls: List["Control"],
|
|
203
|
+
) -> np.ndarray:
|
|
204
|
+
"""Expand a ``{name: weight}`` dict to a per-variable proximal weight array.
|
|
205
|
+
|
|
206
|
+
Maps user-provided per-state/per-control trust region weights to a dense
|
|
207
|
+
array using each variable's ``_slice``. Variables not present in the dict
|
|
208
|
+
default to ``1.0``.
|
|
209
|
+
|
|
210
|
+
Per-variable values may be:
|
|
211
|
+
|
|
212
|
+
* **scalar** — broadcast to every component and every node.
|
|
213
|
+
* **1-D array** of length ``n_components`` — per-component weight,
|
|
214
|
+
same for every node.
|
|
215
|
+
* **2-D array** of shape ``(K, n_components)`` — per-node-per-component.
|
|
216
|
+
When any variable supplies a 2-D value the output is 2-D with first
|
|
217
|
+
dimension *K* (all 2-D entries must agree on *K*).
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
lam_prox_dict: Mapping from state/control names to proximal weights.
|
|
221
|
+
states: List of State objects (must already have ``_slice`` assigned).
|
|
222
|
+
controls: List of Control objects (must already have ``_slice`` assigned).
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
np.ndarray of shape ``(n_states + n_controls,)`` when all entries are
|
|
226
|
+
scalar/1-D, or ``(K, n_states + n_controls)`` when any entry is 2-D.
|
|
227
|
+
|
|
228
|
+
Raises:
|
|
229
|
+
ValueError: If the dict contains unknown names or 2-D entries disagree
|
|
230
|
+
on the number of nodes.
|
|
231
|
+
"""
|
|
232
|
+
n_states = sum(s.shape[0] if len(s.shape) > 0 else 1 for s in states)
|
|
233
|
+
n_controls = sum(c.shape[0] if len(c.shape) > 0 else 1 for c in controls)
|
|
234
|
+
n_total = n_states + n_controls
|
|
235
|
+
|
|
236
|
+
valid_state_names = {s.name for s in states}
|
|
237
|
+
valid_control_names = {c.name for c in controls}
|
|
238
|
+
valid_names = valid_state_names | valid_control_names
|
|
239
|
+
unknown = set(lam_prox_dict.keys()) - valid_names
|
|
240
|
+
if unknown:
|
|
241
|
+
raise ValueError(
|
|
242
|
+
f"lam_prox dict contains unknown name(s): {unknown}. Valid names: {sorted(valid_names)}"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# Build a unified list of (name, n_components, slice_in_output).
|
|
246
|
+
# States occupy columns [0, n_states), controls occupy [n_states, n_total).
|
|
247
|
+
variables: list = []
|
|
248
|
+
for s in states:
|
|
249
|
+
nc = s.shape[0] if len(s.shape) > 0 else 1
|
|
250
|
+
variables.append((s.name, nc, s._slice))
|
|
251
|
+
for c in controls:
|
|
252
|
+
nc = c.shape[0] if len(c.shape) > 0 else 1
|
|
253
|
+
out_slice = slice(n_states + c._slice.start, n_states + c._slice.stop)
|
|
254
|
+
variables.append((c.name, nc, out_slice))
|
|
255
|
+
|
|
256
|
+
# First pass: determine if any entry is 2-D and infer K.
|
|
257
|
+
n_nodes: Optional[int] = None
|
|
258
|
+
for name, n_comp, _ in variables:
|
|
259
|
+
if name not in lam_prox_dict:
|
|
260
|
+
continue
|
|
261
|
+
val = np.asarray(lam_prox_dict[name], dtype=float)
|
|
262
|
+
if val.ndim == 2:
|
|
263
|
+
if n_nodes is None:
|
|
264
|
+
n_nodes = val.shape[0]
|
|
265
|
+
elif val.shape[0] != n_nodes:
|
|
266
|
+
raise ValueError(
|
|
267
|
+
f"lam_prox['{name}'] has {val.shape[0]} rows, but a "
|
|
268
|
+
f"previous entry had {n_nodes} rows. All 2-D entries "
|
|
269
|
+
f"must have the same number of rows (n_nodes)."
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
# Build the output array.
|
|
273
|
+
if n_nodes is not None:
|
|
274
|
+
lam_arr = np.ones((n_nodes, n_total))
|
|
275
|
+
else:
|
|
276
|
+
lam_arr = np.ones(n_total)
|
|
277
|
+
|
|
278
|
+
for name, n_comp, out_slice in variables:
|
|
279
|
+
if name not in lam_prox_dict:
|
|
280
|
+
continue
|
|
281
|
+
val = np.asarray(lam_prox_dict[name], dtype=float)
|
|
282
|
+
|
|
283
|
+
if val.ndim == 0:
|
|
284
|
+
lam_arr[..., out_slice] = float(val)
|
|
285
|
+
elif val.ndim == 1:
|
|
286
|
+
if val.shape[0] != n_comp:
|
|
287
|
+
raise ValueError(
|
|
288
|
+
f"lam_prox['{name}'] has length {val.shape[0]}, "
|
|
289
|
+
f"expected scalar or length {n_comp}"
|
|
290
|
+
)
|
|
291
|
+
lam_arr[..., out_slice] = val
|
|
292
|
+
elif val.ndim == 2:
|
|
293
|
+
if val.shape[1] != n_comp:
|
|
294
|
+
raise ValueError(
|
|
295
|
+
f"lam_prox['{name}'] has {val.shape[1]} columns, expected {n_comp}"
|
|
296
|
+
)
|
|
297
|
+
lam_arr[:, out_slice] = val
|
|
298
|
+
else:
|
|
299
|
+
raise ValueError(
|
|
300
|
+
f"lam_prox['{name}'] has {val.ndim} dimensions, expected scalar, 1-D, or 2-D"
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
return lam_arr
|
|
304
|
+
|
|
305
|
+
|
|
104
306
|
@dataclass
|
|
105
307
|
class Weights:
|
|
106
308
|
"""Normalized SCP weights used internally by the algorithm and autotuner.
|
|
@@ -120,8 +322,13 @@ class Weights:
|
|
|
120
322
|
drift.
|
|
121
323
|
|
|
122
324
|
Attributes:
|
|
123
|
-
lam_prox: Trust region (proximal) weight (normalized).
|
|
124
|
-
|
|
325
|
+
lam_prox: Trust region (proximal) weight (normalized). Scalar or
|
|
326
|
+
array of shape ``(n_states + n_controls,)`` or
|
|
327
|
+
``(N, n_states + n_controls)`` for per-variable / per-node
|
|
328
|
+
weighting.
|
|
329
|
+
lam_vc: Virtual control penalty weight (normalized). Scalar or
|
|
330
|
+
array of shape ``(n_states,)`` or ``(n_nodes-1, n_states)``
|
|
331
|
+
for per-state / per-node weighting.
|
|
125
332
|
lam_cost: Cost weight per state (normalized). Scalar or array of
|
|
126
333
|
shape ``(n_states,)`` for per-state weighting.
|
|
127
334
|
lam_vb: Global virtual buffer penalty weight (normalized). Scalar
|
|
@@ -135,8 +342,8 @@ class Weights:
|
|
|
135
342
|
:meth:`set_vb_arrays`.
|
|
136
343
|
"""
|
|
137
344
|
|
|
138
|
-
lam_prox: float = 1e0
|
|
139
|
-
lam_vc: float = 1e1
|
|
345
|
+
lam_prox: Union[float, np.ndarray] = 1e0
|
|
346
|
+
lam_vc: Union[float, np.ndarray] = 1e1
|
|
140
347
|
lam_cost: Union[float, np.ndarray] = 1e-1
|
|
141
348
|
lam_vb: float = 0.0
|
|
142
349
|
lam_vb_nodal: Optional[np.ndarray] = None
|
|
@@ -144,12 +351,20 @@ class Weights:
|
|
|
144
351
|
|
|
145
352
|
def __post_init__(self):
|
|
146
353
|
# Coerce lists/lists-of-lists to numpy arrays.
|
|
354
|
+
if isinstance(self.lam_prox, (list, tuple)):
|
|
355
|
+
self.lam_prox = np.asarray(self.lam_prox, dtype=float)
|
|
356
|
+
if isinstance(self.lam_vc, (list, tuple)):
|
|
357
|
+
self.lam_vc = np.asarray(self.lam_vc, dtype=float)
|
|
147
358
|
if isinstance(self.lam_cost, (list, tuple)):
|
|
148
359
|
self.lam_cost = np.asarray(self.lam_cost, dtype=float)
|
|
149
360
|
|
|
150
361
|
# Snapshot the user-specified values so normalize() is idempotent.
|
|
151
|
-
self._raw_lam_prox =
|
|
152
|
-
|
|
362
|
+
self._raw_lam_prox = (
|
|
363
|
+
self.lam_prox.copy() if isinstance(self.lam_prox, np.ndarray) else self.lam_prox
|
|
364
|
+
)
|
|
365
|
+
self._raw_lam_vc = (
|
|
366
|
+
self.lam_vc.copy() if isinstance(self.lam_vc, np.ndarray) else self.lam_vc
|
|
367
|
+
)
|
|
153
368
|
self._raw_lam_cost = (
|
|
154
369
|
self.lam_cost.copy() if isinstance(self.lam_cost, np.ndarray) else self.lam_cost
|
|
155
370
|
)
|
|
@@ -164,6 +379,16 @@ class Weights:
|
|
|
164
379
|
making this method idempotent and safe to call after updating
|
|
165
380
|
any individual raw weight.
|
|
166
381
|
"""
|
|
382
|
+
raw_prox_max = (
|
|
383
|
+
float(np.max(self._raw_lam_prox))
|
|
384
|
+
if isinstance(self._raw_lam_prox, np.ndarray)
|
|
385
|
+
else self._raw_lam_prox
|
|
386
|
+
)
|
|
387
|
+
raw_vc_max = (
|
|
388
|
+
float(np.max(self._raw_lam_vc))
|
|
389
|
+
if isinstance(self._raw_lam_vc, np.ndarray)
|
|
390
|
+
else self._raw_lam_vc
|
|
391
|
+
)
|
|
167
392
|
raw_cost_max = (
|
|
168
393
|
float(np.max(self._raw_lam_cost))
|
|
169
394
|
if isinstance(self._raw_lam_cost, np.ndarray)
|
|
@@ -176,7 +401,7 @@ class Weights:
|
|
|
176
401
|
)
|
|
177
402
|
else:
|
|
178
403
|
raw_vb_max = self._raw_lam_vb
|
|
179
|
-
scale = max(
|
|
404
|
+
scale = max(raw_prox_max, raw_vc_max, raw_cost_max, raw_vb_max)
|
|
180
405
|
if scale > 0:
|
|
181
406
|
self.lam_prox = self._raw_lam_prox / scale
|
|
182
407
|
self.lam_vc = self._raw_lam_vc / scale
|
|
@@ -509,7 +734,7 @@ class AlgorithmState:
|
|
|
509
734
|
lam_cost_history: List[Union[float, np.ndarray]] = field(default_factory=list)
|
|
510
735
|
lam_vb_nodal_history: List[np.ndarray] = field(default_factory=list)
|
|
511
736
|
lam_vb_cross_history: List[np.ndarray] = field(default_factory=list)
|
|
512
|
-
lam_prox_history: List[
|
|
737
|
+
lam_prox_history: List[np.ndarray] = field(default_factory=list)
|
|
513
738
|
x_full: List[np.ndarray] = field(default_factory=list)
|
|
514
739
|
x_prop_full: List[np.ndarray] = field(default_factory=list)
|
|
515
740
|
|
|
@@ -715,11 +940,11 @@ class AlgorithmState:
|
|
|
715
940
|
return self.discretizations[index].E_d
|
|
716
941
|
|
|
717
942
|
@property
|
|
718
|
-
def lam_prox(self) ->
|
|
943
|
+
def lam_prox(self) -> np.ndarray:
|
|
719
944
|
"""Get current trust region weight.
|
|
720
945
|
|
|
721
946
|
Returns:
|
|
722
|
-
|
|
947
|
+
Array of shape ``(N, n_states + n_controls)``.
|
|
723
948
|
"""
|
|
724
949
|
if not self.lam_prox_history:
|
|
725
950
|
raise ValueError("lam_prox_history is empty. Initialize state using from_settings().")
|
|
@@ -787,16 +1012,22 @@ class AlgorithmState:
|
|
|
787
1012
|
|
|
788
1013
|
Args:
|
|
789
1014
|
settings: Configuration object containing initial guesses and SCP parameters
|
|
790
|
-
weights: Normalized initial weights from the algorithm.
|
|
791
|
-
``lam_vc`` is expanded to an ``(N-1, n_states)`` array here
|
|
1015
|
+
weights: Normalized initial weights from the algorithm.
|
|
1016
|
+
``lam_vc`` is expanded to an ``(N-1, n_states)`` array here
|
|
1017
|
+
(scalar or per-state values are broadcast).
|
|
792
1018
|
|
|
793
1019
|
Returns:
|
|
794
1020
|
Fresh AlgorithmState initialized from settings with copied arrays
|
|
795
1021
|
"""
|
|
796
1022
|
n = settings.sim.n
|
|
797
1023
|
n_states = settings.sim.n_states
|
|
1024
|
+
n_controls = settings.sim.n_controls
|
|
1025
|
+
n_total = n_states + n_controls
|
|
798
1026
|
lam_vc_array = np.ones((n - 1, n_states)) * weights.lam_vc
|
|
799
1027
|
|
|
1028
|
+
# Expand lam_prox to (N, n_states + n_controls) array
|
|
1029
|
+
lam_prox_array = np.ones((n, n_total)) * weights.lam_prox
|
|
1030
|
+
|
|
800
1031
|
# Expand scalar lam_cost to per-state array
|
|
801
1032
|
if isinstance(weights.lam_cost, np.ndarray):
|
|
802
1033
|
lam_cost_init = weights.lam_cost.copy()
|
|
@@ -825,7 +1056,7 @@ class AlgorithmState:
|
|
|
825
1056
|
lam_cost_history=[lam_cost_init],
|
|
826
1057
|
lam_vb_nodal_history=[weights.lam_vb_nodal.copy()],
|
|
827
1058
|
lam_vb_cross_history=[weights.lam_vb_cross.copy()],
|
|
828
|
-
lam_prox_history=[
|
|
1059
|
+
lam_prox_history=[lam_prox_array],
|
|
829
1060
|
)
|
|
830
1061
|
|
|
831
1062
|
|
|
@@ -883,6 +1114,41 @@ class Algorithm(ABC):
|
|
|
883
1114
|
#: Maximum number of SCP iterations. Subclasses must set this in ``__init__``.
|
|
884
1115
|
k_max: int
|
|
885
1116
|
|
|
1117
|
+
@staticmethod
|
|
1118
|
+
def _resolve_lam_prox(
|
|
1119
|
+
lam_prox: Union[float, Dict[str, Union[float, list, np.ndarray]]],
|
|
1120
|
+
states: Optional[List["State"]] = None,
|
|
1121
|
+
controls: Optional[List["Control"]] = None,
|
|
1122
|
+
) -> Union[float, np.ndarray]:
|
|
1123
|
+
"""Resolve a ``lam_prox`` spec to a numeric value.
|
|
1124
|
+
|
|
1125
|
+
If *lam_prox* is a float it is returned as-is. If it is a dict
|
|
1126
|
+
mapping state/control names to weights, *states* and *controls*
|
|
1127
|
+
must be provided so the dict can be expanded to a per-variable
|
|
1128
|
+
array via :func:`_expand_lam_prox_dict`.
|
|
1129
|
+
|
|
1130
|
+
Args:
|
|
1131
|
+
lam_prox: Scalar weight or ``{name: weight}`` dict.
|
|
1132
|
+
states: Symbolic State objects (required when *lam_prox* is a dict).
|
|
1133
|
+
controls: Symbolic Control objects (required when *lam_prox* is a dict).
|
|
1134
|
+
|
|
1135
|
+
Returns:
|
|
1136
|
+
float or np.ndarray of shape ``(n_states + n_controls,)`` or
|
|
1137
|
+
``(K, n_states + n_controls)``.
|
|
1138
|
+
|
|
1139
|
+
Raises:
|
|
1140
|
+
ValueError: If *lam_prox* is a dict and *states*/*controls* is ``None``.
|
|
1141
|
+
"""
|
|
1142
|
+
if isinstance(lam_prox, dict):
|
|
1143
|
+
if states is None or controls is None:
|
|
1144
|
+
raise ValueError(
|
|
1145
|
+
"lam_prox was specified as a dict but states and/or "
|
|
1146
|
+
"controls were not provided. Pass both so the dict can "
|
|
1147
|
+
"be expanded to a per-variable weight array."
|
|
1148
|
+
)
|
|
1149
|
+
return _expand_lam_prox_dict(lam_prox, states, controls)
|
|
1150
|
+
return lam_prox
|
|
1151
|
+
|
|
886
1152
|
@staticmethod
|
|
887
1153
|
def _resolve_lam_cost(
|
|
888
1154
|
lam_cost: Union[float, Dict[str, float]],
|
|
@@ -915,6 +1181,39 @@ class Algorithm(ABC):
|
|
|
915
1181
|
return _expand_lam_cost_dict(lam_cost, states)
|
|
916
1182
|
return lam_cost
|
|
917
1183
|
|
|
1184
|
+
@staticmethod
|
|
1185
|
+
def _resolve_lam_vc(
|
|
1186
|
+
lam_vc: Union[float, Dict[str, Union[float, list, np.ndarray]]],
|
|
1187
|
+
states: Optional[List["State"]] = None,
|
|
1188
|
+
) -> Union[float, np.ndarray]:
|
|
1189
|
+
"""Resolve a ``lam_vc`` spec to a numeric value.
|
|
1190
|
+
|
|
1191
|
+
If *lam_vc* is a float it is returned as-is. If it is a dict
|
|
1192
|
+
mapping state names to weights, *states* must be provided so the
|
|
1193
|
+
dict can be expanded to a per-state array via
|
|
1194
|
+
:func:`_expand_lam_vc_dict`.
|
|
1195
|
+
|
|
1196
|
+
Args:
|
|
1197
|
+
lam_vc: Scalar weight or ``{state_name: weight}`` dict.
|
|
1198
|
+
states: Symbolic State objects (required when *lam_vc* is a dict).
|
|
1199
|
+
|
|
1200
|
+
Returns:
|
|
1201
|
+
float or np.ndarray of shape ``(n_states,)`` or
|
|
1202
|
+
``(K, n_states)``.
|
|
1203
|
+
|
|
1204
|
+
Raises:
|
|
1205
|
+
ValueError: If *lam_vc* is a dict and *states* is ``None``.
|
|
1206
|
+
"""
|
|
1207
|
+
if isinstance(lam_vc, dict):
|
|
1208
|
+
if states is None:
|
|
1209
|
+
raise ValueError(
|
|
1210
|
+
"lam_vc was specified as a dict but no states were "
|
|
1211
|
+
"provided. Pass states so the dict can be expanded to "
|
|
1212
|
+
"a per-state weight array."
|
|
1213
|
+
)
|
|
1214
|
+
return _expand_lam_vc_dict(lam_vc, states)
|
|
1215
|
+
return lam_vc
|
|
1216
|
+
|
|
918
1217
|
def _resolve_lam_vb(
|
|
919
1218
|
self,
|
|
920
1219
|
N: int,
|
|
@@ -91,7 +91,7 @@ class OptimizationResults:
|
|
|
91
91
|
VC_history: list[np.ndarray] = field(default_factory=list, metadata={"npz": "array_list"})
|
|
92
92
|
|
|
93
93
|
# Convergence histories
|
|
94
|
-
lam_prox_history: list[
|
|
94
|
+
lam_prox_history: list[np.ndarray] = field(default_factory=list, metadata={"npz": "array_list"})
|
|
95
95
|
actual_reduction_history: list[float] = field(
|
|
96
96
|
default_factory=list, metadata={"npz": "float_list"}
|
|
97
97
|
)
|