sleipnirgroup-jormungandr 0.6.7.dev57__tar.gz → 0.6.7.dev64__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.
Potentially problematic release.
This version of sleipnirgroup-jormungandr might be problematic. Click here for more details.
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/CMakeLists.txt +47 -22
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/PKG-INFO +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/cmake/Pybind11Mkdoc.cmake +21 -1
- sleipnirgroup_jormungandr-0.6.7.dev64/cmake/Pybind11MkdocPostprocess.cmake +12 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/pyproject.toml +27 -0
- sleipnirgroup_jormungandr-0.6.7.dev64/python/cpp/arity.hpp +42 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/autodiff/bind_variable_block.cpp +55 -23
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/autodiff/bind_variable_matrix.cpp +63 -52
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/docstrings.hpp +422 -422
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/optimization/bind_ocp.cpp +17 -0
- sleipnirgroup_jormungandr-0.6.7.dev64/python/cpp/optimization/bind_problem.cpp +216 -0
- sleipnirgroup_jormungandr-0.6.7.dev64/python/cpp/slice_tuple.hpp +21 -0
- sleipnirgroup_jormungandr-0.6.7.dev64/python/cpp/text_wrap.hpp +84 -0
- sleipnirgroup_jormungandr-0.6.7.dev64/python/postprocess_stubs.py +166 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/src/sleipnir/__init__.py +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/src/sleipnir/autodiff/__init__.py +1 -3
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/src/sleipnir/optimization/__init__.py +5 -1
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/autodiff/gradient_test.py +20 -20
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/autodiff/hessian_test.py +31 -30
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/autodiff/jacobian_test.py +11 -11
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/autodiff/variable_matrix_test.py +21 -21
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/autodiff/variable_test.py +3 -3
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/arm_on_elevator_problem_test.py +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/cart_pole_ocp_test.py +3 -3
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/cart_pole_problem_test.py +2 -2
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/cart_pole_util.py +8 -3
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/constraints_test.py +4 -4
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/decision_variable_test.py +4 -4
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/differential_drive_ocp_test.py +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/differential_drive_problem_test.py +2 -2
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/differential_drive_util.py +8 -3
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/double_integrator_problem_test.py +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/flywheel_ocp_test.py +5 -5
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/flywheel_problem_test.py +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/linear_problem_test.py +2 -2
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/multistart_test.py +5 -3
- sleipnirgroup_jormungandr-0.6.7.dev64/python/test/optimization/near.py +2 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/nonlinear_problem_test.py +7 -7
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/problem_spy_test.py +7 -5
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/quadratic_problem_test.py +6 -6
- sleipnirgroup_jormungandr-0.6.7.dev64/python/test/optimization/rk4.py +44 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/solver/exit_status_test.py +15 -15
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/test/optimization/trivial_problem_test.py +3 -3
- sleipnirgroup_jormungandr-0.6.7.dev57/python/cpp/optimization/bind_problem.cpp +0 -156
- sleipnirgroup_jormungandr-0.6.7.dev57/python/test/optimization/near.py +0 -2
- sleipnirgroup_jormungandr-0.6.7.dev57/python/test/optimization/rk4.py +0 -18
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/LICENSE.txt +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/README.md +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/SleipnirConfig.cmake.in +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/cmake/BuildTypes.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/cmake/CompilerFlags.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/cmake/SubdirList.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/cmake/arm-none-eabi.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/expression.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/expression_graph.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/expression_type.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/gradient.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/hessian.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/jacobian.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/sleipnir_base.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/slice.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/variable.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/variable_block.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/autodiff/variable_matrix.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/multistart.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/ocp/dynamics_type.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/ocp/timestep_method.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/ocp/transcription_method.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/ocp.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/problem.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/exit_status.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/ipm.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/ipm_matrix_callbacks.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/iteration_info.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/newton.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/newton_matrix_callbacks.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/options.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/sqp.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/sqp_matrix_callbacks.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/all_finite.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/append_as_triplets.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/bounds.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/dense_kkt_solver.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/feasibility_restoration.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/filter.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/fraction_to_the_boundary_rule.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/inertia.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/kkt_error.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/kkt_solver.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/problem_scaling.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/sparse_inf_norms.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/optimization/solver/util/sparse_kkt_solver.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/assert.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/concepts.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/empty.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/function_ref.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/intrusive_shared_ptr.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/pool.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/print.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/print_diagnostics.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/profiler.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/scope_exit.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/spy.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/include/sleipnir/util/symbol_exports.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/autodiff/bind_expression_type.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/autodiff/bind_gradient.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/autodiff/bind_hessian.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/autodiff/bind_jacobian.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/autodiff/bind_variable.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/binders.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/for_each_type.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/main.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/optimization/bind_equality_constraints.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/optimization/bind_inequality_constraints.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/optimization/ocp/bind_dynamics_type.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/optimization/ocp/bind_timestep_method.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/optimization/ocp/bind_transcription_method.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/optimization/solver/bind_exit_status.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/optimization/solver/bind_iteration_info.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/python/cpp/try_cast.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/autodiff/gradient.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/autodiff/hessian.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/autodiff/jacobian.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/autodiff/variable_matrix.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/optimization/ocp.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/optimization/problem.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/optimization/solver/ipm.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/optimization/solver/newton.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/optimization/solver/sqp.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/src/util/pool.cpp +0 -0
{sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/CMakeLists.txt
RENAMED
|
@@ -301,7 +301,9 @@ if(SLEIPNIR_BUILD_PYTHON)
|
|
|
301
301
|
if(DEFINED PY_BUILD_CMAKE_MODULE_NAME)
|
|
302
302
|
set(PY_DEST ${PY_BUILD_CMAKE_MODULE_NAME})
|
|
303
303
|
else()
|
|
304
|
-
set(PY_DEST
|
|
304
|
+
set(PY_DEST
|
|
305
|
+
lib/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/sleipnir
|
|
306
|
+
)
|
|
305
307
|
endif()
|
|
306
308
|
|
|
307
309
|
# nanobind dependency
|
|
@@ -343,47 +345,70 @@ if(SLEIPNIR_BUILD_PYTHON)
|
|
|
343
345
|
LIBRARY DESTINATION ${PY_DEST}
|
|
344
346
|
)
|
|
345
347
|
|
|
348
|
+
# py-build-cmake copies the pure Python sources into the wheel itself.
|
|
349
|
+
# Install them for plain CMake installs as well.
|
|
350
|
+
if(NOT DEFINED PY_BUILD_CMAKE_MODULE_NAME)
|
|
351
|
+
install(
|
|
352
|
+
DIRECTORY python/src/sleipnir/
|
|
353
|
+
DESTINATION ${PY_DEST}
|
|
354
|
+
COMPONENT python_modules
|
|
355
|
+
FILES_MATCHING
|
|
356
|
+
PATTERN "*.py"
|
|
357
|
+
PATTERN "__pycache__" EXCLUDE
|
|
358
|
+
)
|
|
359
|
+
endif()
|
|
360
|
+
|
|
361
|
+
# Generate stubs at install time because only the install tree has the
|
|
362
|
+
# sleipnir/ package layout needed to import the module by its fully
|
|
363
|
+
# qualified name `sleipnir._sleipnir`.
|
|
364
|
+
#
|
|
365
|
+
# Importing sleipnir._sleipnir requires the directory containing the
|
|
366
|
+
# sleipnir package (i.e., PY_DEST's parent) to be on the Python path. For
|
|
367
|
+
# py-build-cmake builds, PY_DEST has no parent. For plain CMake installs,
|
|
368
|
+
# PY_DEST's parent is lib/pythonX.Y.
|
|
369
|
+
cmake_path(GET PY_DEST PARENT_PATH PY_DEST_PARENT)
|
|
346
370
|
nanobind_add_stub(
|
|
347
371
|
_sleipnir_stub
|
|
348
372
|
INSTALL_TIME
|
|
349
|
-
MARKER_FILE
|
|
350
|
-
MODULE _sleipnir
|
|
351
|
-
OUTPUT
|
|
352
|
-
PYTHON_PATH
|
|
373
|
+
MARKER_FILE ${PY_DEST}/py.typed
|
|
374
|
+
MODULE sleipnir._sleipnir
|
|
375
|
+
OUTPUT ${PY_DEST}/_sleipnir/__init__.pyi
|
|
376
|
+
PYTHON_PATH ${PY_DEST_PARENT}
|
|
353
377
|
DEPENDS _sleipnir
|
|
354
378
|
COMPONENT python_modules
|
|
355
379
|
)
|
|
356
380
|
nanobind_add_stub(
|
|
357
381
|
_sleipnir_autodiff_stub
|
|
358
382
|
INSTALL_TIME
|
|
359
|
-
MODULE _sleipnir.autodiff
|
|
360
|
-
OUTPUT
|
|
361
|
-
PYTHON_PATH
|
|
383
|
+
MODULE sleipnir._sleipnir.autodiff
|
|
384
|
+
OUTPUT ${PY_DEST}/_sleipnir/autodiff.pyi
|
|
385
|
+
PYTHON_PATH ${PY_DEST_PARENT}
|
|
362
386
|
DEPENDS _sleipnir
|
|
363
387
|
COMPONENT python_modules
|
|
364
388
|
)
|
|
365
389
|
nanobind_add_stub(
|
|
366
390
|
_sleipnir_optimization_stub
|
|
367
391
|
INSTALL_TIME
|
|
368
|
-
MODULE _sleipnir.optimization
|
|
369
|
-
OUTPUT
|
|
370
|
-
PYTHON_PATH
|
|
392
|
+
MODULE sleipnir._sleipnir.optimization
|
|
393
|
+
OUTPUT ${PY_DEST}/_sleipnir/optimization.pyi
|
|
394
|
+
PYTHON_PATH ${PY_DEST_PARENT}
|
|
371
395
|
DEPENDS _sleipnir
|
|
372
396
|
COMPONENT python_modules
|
|
373
397
|
)
|
|
398
|
+
install(
|
|
399
|
+
CODE
|
|
400
|
+
"execute_process(
|
|
401
|
+
COMMAND \"${Python_EXECUTABLE}\"
|
|
402
|
+
\"${CMAKE_CURRENT_SOURCE_DIR}/python/postprocess_stubs.py\"
|
|
403
|
+
${PY_DEST}/_sleipnir/autodiff.pyi
|
|
404
|
+
${PY_DEST}/_sleipnir/optimization.pyi
|
|
405
|
+
WORKING_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}\"
|
|
406
|
+
COMMAND_ERROR_IS_FATAL ANY
|
|
407
|
+
)"
|
|
408
|
+
COMPONENT python_modules
|
|
409
|
+
)
|
|
374
410
|
|
|
375
411
|
if(NOT CMAKE_CROSSCOMPILING)
|
|
376
|
-
# pybind11_mkdoc dependency
|
|
377
|
-
FetchContent_Declare(
|
|
378
|
-
pybind11_mkdoc
|
|
379
|
-
GIT_REPOSITORY https://github.com/pybind/pybind11_mkdoc.git
|
|
380
|
-
GIT_TAG v3.0.0
|
|
381
|
-
GIT_SHALLOW ON
|
|
382
|
-
EXCLUDE_FROM_ALL
|
|
383
|
-
SYSTEM
|
|
384
|
-
)
|
|
385
|
-
FetchContent_MakeAvailable(pybind11_mkdoc)
|
|
386
|
-
|
|
387
412
|
set(sleipnir_headers
|
|
388
413
|
${CMAKE_CURRENT_SOURCE_DIR}/include/sleipnir/autodiff/expression_type.hpp
|
|
389
414
|
${CMAKE_CURRENT_SOURCE_DIR}/include/sleipnir/autodiff/gradient.hpp
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
function(pybind11_mkdoc target headers)
|
|
2
2
|
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
|
3
3
|
|
|
4
|
+
# Check that pybind11_mkdoc is installed
|
|
5
|
+
execute_process(
|
|
6
|
+
COMMAND ${Python3_EXECUTABLE} -c "import pybind11_mkdoc"
|
|
7
|
+
RESULT_VARIABLE pybind11_mkdoc_result
|
|
8
|
+
OUTPUT_QUIET
|
|
9
|
+
ERROR_QUIET
|
|
10
|
+
)
|
|
11
|
+
if(NOT pybind11_mkdoc_result EQUAL 0)
|
|
12
|
+
message(
|
|
13
|
+
FATAL_ERROR
|
|
14
|
+
"pybind11_mkdoc not found for ${Python3_EXECUTABLE}. Install it with `pip install --group docstrings`."
|
|
15
|
+
)
|
|
16
|
+
endif()
|
|
17
|
+
|
|
4
18
|
# Target compiler flags
|
|
5
19
|
get_target_property(target_flags ${target} INCLUDE_DIRECTORIES)
|
|
6
20
|
list(TRANSFORM target_flags PREPEND "-I")
|
|
@@ -60,7 +74,13 @@ function(pybind11_mkdoc target headers)
|
|
|
60
74
|
${CMAKE_CURRENT_SOURCE_DIR}/python/cpp/docstrings.hpp
|
|
61
75
|
${target_flags} ${clang_flags} ${eigen_flags} ${small_vector_flags}
|
|
62
76
|
-std=c++23
|
|
63
|
-
|
|
77
|
+
COMMAND
|
|
78
|
+
${CMAKE_COMMAND}
|
|
79
|
+
-DFILE=${CMAKE_CURRENT_SOURCE_DIR}/python/cpp/docstrings.hpp -P
|
|
80
|
+
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Pybind11MkdocPostprocess.cmake
|
|
81
|
+
DEPENDS
|
|
82
|
+
${headers}
|
|
83
|
+
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Pybind11MkdocPostprocess.cmake
|
|
64
84
|
)
|
|
65
85
|
|
|
66
86
|
# Add docstrings target
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Replaces pybind11_mkdoc's docstring pointers with constexpr arrays
|
|
2
|
+
#
|
|
3
|
+
# Usage: cmake -DFILE=<docstrings.hpp> -P Pybind11MkdocPostprocess.cmake
|
|
4
|
+
|
|
5
|
+
file(READ ${FILE} contents)
|
|
6
|
+
string(
|
|
7
|
+
REGEX REPLACE "\nstatic const char \\*([A-Za-z0-9_]+) ="
|
|
8
|
+
"\nconstexpr char \\1[] ="
|
|
9
|
+
contents
|
|
10
|
+
"${contents}"
|
|
11
|
+
)
|
|
12
|
+
file(WRITE ${FILE} "${contents}")
|
{sleipnirgroup_jormungandr-0.6.7.dev57 → sleipnirgroup_jormungandr-0.6.7.dev64}/pyproject.toml
RENAMED
|
@@ -21,8 +21,11 @@ build-backend = "py_build_cmake.build"
|
|
|
21
21
|
|
|
22
22
|
[dependency-groups]
|
|
23
23
|
dev = [
|
|
24
|
+
"mypy>=2.4.0",
|
|
24
25
|
"pytest>=9.1.1",
|
|
26
|
+
"scipy-stubs",
|
|
25
27
|
]
|
|
28
|
+
docstrings = ["pybind11-mkdoc~=3.0.0"]
|
|
26
29
|
|
|
27
30
|
[tool.py-build-cmake.cmake]
|
|
28
31
|
build_type = "Release"
|
|
@@ -54,8 +57,29 @@ exclude = []
|
|
|
54
57
|
python_abi = "abi3"
|
|
55
58
|
abi3_minimum_cpython_version = 312
|
|
56
59
|
|
|
60
|
+
[tool.mypy]
|
|
61
|
+
files = [
|
|
62
|
+
"benchmarks",
|
|
63
|
+
"docs/generate_website.py",
|
|
64
|
+
"examples",
|
|
65
|
+
"python/postprocess_stubs.py",
|
|
66
|
+
"python/test",
|
|
67
|
+
"tools",
|
|
68
|
+
]
|
|
69
|
+
allow_redefinition_new = true
|
|
70
|
+
disallow_incomplete_defs = true
|
|
71
|
+
disallow_untyped_defs = true
|
|
72
|
+
explicit_package_bases = true
|
|
73
|
+
local_partial_types = true
|
|
74
|
+
mypy_path = ["examples/current_manager", "python/test/optimization"]
|
|
75
|
+
|
|
76
|
+
[[tool.mypy.overrides]]
|
|
77
|
+
module = "mpl_toolkits.*"
|
|
78
|
+
ignore_missing_imports = true
|
|
79
|
+
|
|
57
80
|
[tool.pytest.ini_options]
|
|
58
81
|
minversion = "6.0"
|
|
82
|
+
pythonpath = ["examples/current_manager"]
|
|
59
83
|
testpaths = ["python/test", "examples/current_manager/test"]
|
|
60
84
|
|
|
61
85
|
[tool.uv]
|
|
@@ -66,8 +90,11 @@ cache-keys = [
|
|
|
66
90
|
{ file = "include/**" },
|
|
67
91
|
{ file = "pyproject.toml" },
|
|
68
92
|
{ file = "python/cpp/**/*.cpp" },
|
|
93
|
+
{ file = "python/cpp/arity.hpp" },
|
|
69
94
|
{ file = "python/cpp/binders.hpp" },
|
|
70
95
|
{ file = "python/cpp/for_each_type.hpp" },
|
|
96
|
+
{ file = "python/cpp/slice_tuple.hpp" },
|
|
97
|
+
{ file = "python/cpp/text_wrap.hpp" },
|
|
71
98
|
{ file = "python/cpp/try_cast.hpp" },
|
|
72
99
|
{ file = "python/src/**" },
|
|
73
100
|
{ file = "src/**" },
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Copyright (c) Sleipnir contributors
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <cstddef>
|
|
6
|
+
#include <type_traits>
|
|
7
|
+
|
|
8
|
+
namespace slp {
|
|
9
|
+
|
|
10
|
+
/// Type implicitly convertible to any type. Used for counting aggregate
|
|
11
|
+
/// members.
|
|
12
|
+
struct AnyType {
|
|
13
|
+
template <typename T>
|
|
14
|
+
// NOLINTNEXTLINE (google-explicit-constructor)
|
|
15
|
+
operator T() const;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/// Returns the number of members in aggregate type T.
|
|
19
|
+
///
|
|
20
|
+
/// @tparam T Aggregate type.
|
|
21
|
+
/// @tparam Args Initializers for the members counted so far.
|
|
22
|
+
template <typename T, typename... Args>
|
|
23
|
+
requires std::is_aggregate_v<T>
|
|
24
|
+
consteval size_t member_count() {
|
|
25
|
+
if constexpr (requires { T{Args{}..., AnyType{}}; }) {
|
|
26
|
+
return member_count<T, Args..., AnyType>();
|
|
27
|
+
} else {
|
|
28
|
+
return sizeof...(Args);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// Returns the number of parameters of a lambda.
|
|
33
|
+
///
|
|
34
|
+
/// @tparam F Lambda type.
|
|
35
|
+
template <typename F>
|
|
36
|
+
consteval size_t lambda_param_count() {
|
|
37
|
+
return []<typename R, typename C, typename... Args>(R (C::*)(Args...) const) {
|
|
38
|
+
return sizeof...(Args);
|
|
39
|
+
}(&F::operator());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
} // namespace slp
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include <nanobind/operators.h>
|
|
7
7
|
#include <nanobind/stl/function.h>
|
|
8
8
|
#include <nanobind/stl/string.h>
|
|
9
|
+
#include <nanobind/stl/tuple.h>
|
|
9
10
|
#include <nanobind/stl/vector.h>
|
|
10
11
|
|
|
11
12
|
#include <stdint.h>
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
#include <functional>
|
|
16
17
|
#include <stdexcept>
|
|
17
18
|
#include <string>
|
|
19
|
+
#include <tuple>
|
|
18
20
|
|
|
19
21
|
#include <Eigen/Core>
|
|
20
22
|
#include <sleipnir/autodiff/slice.hpp>
|
|
@@ -25,6 +27,7 @@
|
|
|
25
27
|
|
|
26
28
|
#include "docstrings.hpp"
|
|
27
29
|
#include "for_each_type.hpp"
|
|
30
|
+
#include "slice_tuple.hpp"
|
|
28
31
|
#include "try_cast.hpp"
|
|
29
32
|
|
|
30
33
|
namespace nb = nanobind;
|
|
@@ -68,7 +71,7 @@ void bind_variable_block(
|
|
|
68
71
|
"row"_a, "value"_a);
|
|
69
72
|
cls.def(
|
|
70
73
|
"__setitem__",
|
|
71
|
-
[](VariableBlock<VariableMatrix<double>>& self,
|
|
74
|
+
[](VariableBlock<VariableMatrix<double>>& self, SliceTuple slices,
|
|
72
75
|
nb::object value) {
|
|
73
76
|
if (slices.size() != 2) {
|
|
74
77
|
throw nb::index_error(
|
|
@@ -151,31 +154,32 @@ void bind_variable_block(
|
|
|
151
154
|
cls.def(
|
|
152
155
|
"__getitem__",
|
|
153
156
|
[](VariableBlock<VariableMatrix<double>>& self,
|
|
154
|
-
|
|
157
|
+
std::tuple<int, int> slices) -> Variable<double>& {
|
|
158
|
+
auto [row, col] = slices;
|
|
159
|
+
|
|
160
|
+
if (row >= self.rows() || col >= self.cols()) {
|
|
161
|
+
throw std::out_of_range("Index out of bounds");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (row < 0) {
|
|
165
|
+
row += self.rows();
|
|
166
|
+
}
|
|
167
|
+
if (col < 0) {
|
|
168
|
+
col += self.cols();
|
|
169
|
+
}
|
|
170
|
+
return self[row, col];
|
|
171
|
+
},
|
|
172
|
+
nb::rv_policy::reference_internal, "slices"_a,
|
|
173
|
+
DOC(slp, VariableBlock, operator, array));
|
|
174
|
+
cls.def(
|
|
175
|
+
"__getitem__",
|
|
176
|
+
[](VariableBlock<VariableMatrix<double>>& self,
|
|
177
|
+
SliceTuple slices) -> VariableBlock<VariableMatrix<double>> {
|
|
155
178
|
if (slices.size() != 2) {
|
|
156
179
|
throw nb::index_error(
|
|
157
180
|
std::format("Expected 2 slices, got {}.", slices.size()).c_str());
|
|
158
181
|
}
|
|
159
182
|
|
|
160
|
-
// If both indices are integers instead of slices, return Variable
|
|
161
|
-
// instead of VariableBlock
|
|
162
|
-
if (nb::isinstance<int>(slices[0]) && nb::isinstance<int>(slices[1])) {
|
|
163
|
-
int row = nb::cast<int>(slices[0]);
|
|
164
|
-
int col = nb::cast<int>(slices[1]);
|
|
165
|
-
|
|
166
|
-
if (row >= self.rows() || col >= self.cols()) {
|
|
167
|
-
throw std::out_of_range("Index out of bounds");
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (row < 0) {
|
|
171
|
-
row += self.rows();
|
|
172
|
-
}
|
|
173
|
-
if (col < 0) {
|
|
174
|
-
col += self.cols();
|
|
175
|
-
}
|
|
176
|
-
return nb::cast(self[row, col]);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
183
|
Slice row_slice;
|
|
180
184
|
int row_slice_length;
|
|
181
185
|
Slice col_slice;
|
|
@@ -211,8 +215,7 @@ void bind_variable_block(
|
|
|
211
215
|
col_slice_length = 1;
|
|
212
216
|
}
|
|
213
217
|
|
|
214
|
-
return
|
|
215
|
-
self[row_slice, row_slice_length, col_slice, col_slice_length]);
|
|
218
|
+
return self[row_slice, row_slice_length, col_slice, col_slice_length];
|
|
216
219
|
},
|
|
217
220
|
nb::keep_alive<0, 1>(), DOC(slp, VariableBlock, operator, array),
|
|
218
221
|
"slices"_a);
|
|
@@ -223,6 +226,31 @@ void bind_variable_block(
|
|
|
223
226
|
nb::overload_cast<int>(&VariableBlock<VariableMatrix<double>>::col),
|
|
224
227
|
"col"_a, DOC(slp, VariableBlock, col));
|
|
225
228
|
|
|
229
|
+
// Matrix-matrix multiplication. Products with a VariableMatrix on the left
|
|
230
|
+
// are bound on VariableMatrix.
|
|
231
|
+
for (const char* name : {"__mul__", "__matmul__"}) {
|
|
232
|
+
cls.def(
|
|
233
|
+
name,
|
|
234
|
+
[](const VariableBlock<VariableMatrix<double>>& lhs,
|
|
235
|
+
const VariableBlock<VariableMatrix<double>>& rhs) {
|
|
236
|
+
return lhs * rhs;
|
|
237
|
+
},
|
|
238
|
+
nb::is_operator(), "rhs"_a);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Matrix multiplication with NumPy arrays. These are also handled by
|
|
242
|
+
// __array_ufunc__ below, but type checkers only see these overloads.
|
|
243
|
+
cls.def(
|
|
244
|
+
"__matmul__",
|
|
245
|
+
[](const VariableBlock<VariableMatrix<double>>& lhs,
|
|
246
|
+
nb::DRef<Eigen::MatrixXd> rhs) { return lhs * rhs; },
|
|
247
|
+
nb::is_operator(), "rhs"_a);
|
|
248
|
+
cls.def(
|
|
249
|
+
"__rmatmul__",
|
|
250
|
+
[](const VariableBlock<VariableMatrix<double>>& rhs,
|
|
251
|
+
nb::DRef<Eigen::MatrixXd> lhs) { return lhs * rhs; },
|
|
252
|
+
nb::is_operator(), "lhs"_a);
|
|
253
|
+
|
|
226
254
|
// https://numpy.org/doc/stable/user/basics.dispatch.html
|
|
227
255
|
cls.def(
|
|
228
256
|
"__array_ufunc__",
|
|
@@ -302,6 +330,10 @@ void bind_variable_block(
|
|
|
302
330
|
|
|
303
331
|
return nb::not_implemented();
|
|
304
332
|
},
|
|
333
|
+
// nanobind can't annotate nb::args or nb::kwargs, so the stub needs an
|
|
334
|
+
// explicit signature
|
|
335
|
+
nb::sig("def __array_ufunc__(self, ufunc: object, method: str, "
|
|
336
|
+
"*inputs: object, **kwargs: object) -> object"),
|
|
305
337
|
"ufunc"_a, "method"_a, "inputs"_a, "kwargs"_a);
|
|
306
338
|
|
|
307
339
|
cls.def(nb::self + nb::self, "rhs"_a);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include <nanobind/operators.h>
|
|
7
7
|
#include <nanobind/stl/function.h>
|
|
8
8
|
#include <nanobind/stl/string.h>
|
|
9
|
+
#include <nanobind/stl/tuple.h>
|
|
9
10
|
#include <nanobind/stl/vector.h>
|
|
10
11
|
|
|
11
12
|
#include <stdint.h>
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
#include <functional>
|
|
16
17
|
#include <stdexcept>
|
|
17
18
|
#include <string>
|
|
19
|
+
#include <tuple>
|
|
18
20
|
#include <vector>
|
|
19
21
|
|
|
20
22
|
#include <Eigen/Core>
|
|
@@ -26,6 +28,7 @@
|
|
|
26
28
|
|
|
27
29
|
#include "docstrings.hpp"
|
|
28
30
|
#include "for_each_type.hpp"
|
|
31
|
+
#include "slice_tuple.hpp"
|
|
29
32
|
#include "try_cast.hpp"
|
|
30
33
|
|
|
31
34
|
namespace nb = nanobind;
|
|
@@ -90,7 +93,7 @@ void bind_variable_matrix(nb::module_& autodiff,
|
|
|
90
93
|
"row"_a, "value"_a);
|
|
91
94
|
cls.def(
|
|
92
95
|
"__setitem__",
|
|
93
|
-
[](VariableMatrix<double>& self,
|
|
96
|
+
[](VariableMatrix<double>& self, SliceTuple slices, nb::object value) {
|
|
94
97
|
if (slices.size() != 2) {
|
|
95
98
|
throw nb::index_error(
|
|
96
99
|
std::format("Expected 2 slices, got {}.", slices.size()).c_str());
|
|
@@ -170,31 +173,33 @@ void bind_variable_matrix(nb::module_& autodiff,
|
|
|
170
173
|
DOC(slp, VariableMatrix, operator, array, 3));
|
|
171
174
|
cls.def(
|
|
172
175
|
"__getitem__",
|
|
173
|
-
[](VariableMatrix<double>& self,
|
|
176
|
+
[](VariableMatrix<double>& self,
|
|
177
|
+
std::tuple<int, int> slices) -> Variable<double>& {
|
|
178
|
+
auto [row, col] = slices;
|
|
179
|
+
|
|
180
|
+
if (row >= self.rows() || col >= self.cols()) {
|
|
181
|
+
throw std::out_of_range("Index out of bounds");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (row < 0) {
|
|
185
|
+
row += self.rows();
|
|
186
|
+
}
|
|
187
|
+
if (col < 0) {
|
|
188
|
+
col += self.cols();
|
|
189
|
+
}
|
|
190
|
+
return self[row, col];
|
|
191
|
+
},
|
|
192
|
+
nb::rv_policy::reference_internal, "slices"_a,
|
|
193
|
+
DOC(slp, VariableMatrix, operator, array));
|
|
194
|
+
cls.def(
|
|
195
|
+
"__getitem__",
|
|
196
|
+
[](VariableMatrix<double>& self,
|
|
197
|
+
SliceTuple slices) -> VariableBlock<VariableMatrix<double>> {
|
|
174
198
|
if (slices.size() != 2) {
|
|
175
199
|
throw nb::index_error(
|
|
176
200
|
std::format("Expected 2 slices, got {}.", slices.size()).c_str());
|
|
177
201
|
}
|
|
178
202
|
|
|
179
|
-
// If both indices are integers instead of slices, return Variable
|
|
180
|
-
// instead of VariableBlock
|
|
181
|
-
if (nb::isinstance<int>(slices[0]) && nb::isinstance<int>(slices[1])) {
|
|
182
|
-
int row = nb::cast<int>(slices[0]);
|
|
183
|
-
int col = nb::cast<int>(slices[1]);
|
|
184
|
-
|
|
185
|
-
if (row >= self.rows() || col >= self.cols()) {
|
|
186
|
-
throw std::out_of_range("Index out of bounds");
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (row < 0) {
|
|
190
|
-
row += self.rows();
|
|
191
|
-
}
|
|
192
|
-
if (col < 0) {
|
|
193
|
-
col += self.cols();
|
|
194
|
-
}
|
|
195
|
-
return nb::cast(self[row, col]);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
203
|
Slice row_slice;
|
|
199
204
|
int row_slice_length;
|
|
200
205
|
Slice col_slice;
|
|
@@ -227,8 +232,7 @@ void bind_variable_matrix(nb::module_& autodiff,
|
|
|
227
232
|
col_slice_length = 1;
|
|
228
233
|
}
|
|
229
234
|
|
|
230
|
-
return
|
|
231
|
-
self[row_slice, row_slice_length, col_slice, col_slice_length]);
|
|
235
|
+
return self[row_slice, row_slice_length, col_slice, col_slice_length];
|
|
232
236
|
},
|
|
233
237
|
nb::keep_alive<0, 1>(), "slices"_a,
|
|
234
238
|
DOC(slp, VariableMatrix, operator, array));
|
|
@@ -237,43 +241,46 @@ void bind_variable_matrix(nb::module_& autodiff,
|
|
|
237
241
|
cls.def("col", nb::overload_cast<int>(&VariableMatrix<double>::col), "col"_a,
|
|
238
242
|
DOC(slp, VariableMatrix, col));
|
|
239
243
|
|
|
240
|
-
// Matrix-matrix multiplication
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
244
|
+
// Matrix-matrix multiplication. Products with a VariableBlock on the left are
|
|
245
|
+
// bound on VariableBlock.
|
|
246
|
+
for (const char* name : {"__mul__", "__matmul__"}) {
|
|
247
|
+
cls.def(
|
|
248
|
+
name,
|
|
249
|
+
[](const VariableMatrix<double>& lhs,
|
|
250
|
+
const VariableMatrix<double>& rhs) { return lhs * rhs; },
|
|
251
|
+
nb::is_operator(), "rhs"_a);
|
|
252
|
+
cls.def(
|
|
253
|
+
name,
|
|
254
|
+
[](const VariableMatrix<double>& lhs,
|
|
255
|
+
const VariableBlock<VariableMatrix<double>>& rhs) {
|
|
256
|
+
return lhs * rhs;
|
|
257
|
+
},
|
|
258
|
+
nb::is_operator(), "rhs"_a);
|
|
259
|
+
}
|
|
260
|
+
for (const char* name : {"__rmul__", "__rmatmul__"}) {
|
|
261
|
+
cls.def(
|
|
262
|
+
name,
|
|
263
|
+
[](const VariableMatrix<double>& rhs,
|
|
264
|
+
const VariableBlock<VariableMatrix<double>>& lhs) {
|
|
265
|
+
return lhs * rhs;
|
|
266
|
+
},
|
|
267
|
+
nb::is_operator(), "lhs"_a);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Matrix multiplication with NumPy arrays. These are also handled by
|
|
271
|
+
// __array_ufunc__ below, but type checkers only see these overloads.
|
|
247
272
|
cls.def(
|
|
248
|
-
"
|
|
249
|
-
[](const VariableMatrix<double>& lhs,
|
|
250
|
-
const VariableBlock<VariableMatrix<double>>& rhs) {
|
|
273
|
+
"__matmul__",
|
|
274
|
+
[](const VariableMatrix<double>& lhs, nb::DRef<Eigen::MatrixXd> rhs) {
|
|
251
275
|
return lhs * rhs;
|
|
252
276
|
},
|
|
253
277
|
nb::is_operator(), "rhs"_a);
|
|
254
278
|
cls.def(
|
|
255
|
-
"
|
|
256
|
-
[](const VariableMatrix<double>& rhs,
|
|
257
|
-
const VariableBlock<VariableMatrix<double>>& lhs) {
|
|
279
|
+
"__rmatmul__",
|
|
280
|
+
[](const VariableMatrix<double>& rhs, nb::DRef<Eigen::MatrixXd> lhs) {
|
|
258
281
|
return lhs * rhs;
|
|
259
282
|
},
|
|
260
283
|
nb::is_operator(), "lhs"_a);
|
|
261
|
-
cls.def(
|
|
262
|
-
"__mul__",
|
|
263
|
-
[](const VariableBlock<VariableMatrix<double>>& lhs,
|
|
264
|
-
const VariableBlock<VariableMatrix<double>>& rhs) {
|
|
265
|
-
return lhs * rhs;
|
|
266
|
-
},
|
|
267
|
-
nb::is_operator(), "rhs"_a);
|
|
268
|
-
for_each_type<VariableMatrix<double>, VariableBlock<VariableMatrix<double>>>(
|
|
269
|
-
[&]<typename L> {
|
|
270
|
-
for_each_type<VariableMatrix<double>,
|
|
271
|
-
VariableBlock<VariableMatrix<double>>>([&]<typename R> {
|
|
272
|
-
cls.def(
|
|
273
|
-
"__matmul__", [](L&& lhs, R&& rhs) { return lhs * rhs; },
|
|
274
|
-
nb::is_operator(), "rhs"_a);
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
284
|
|
|
278
285
|
// https://numpy.org/doc/stable/user/basics.dispatch.html
|
|
279
286
|
cls.def(
|
|
@@ -354,6 +361,10 @@ void bind_variable_matrix(nb::module_& autodiff,
|
|
|
354
361
|
|
|
355
362
|
return nb::not_implemented();
|
|
356
363
|
},
|
|
364
|
+
// nanobind can't annotate nb::args or nb::kwargs, so the stub needs an
|
|
365
|
+
// explicit signature
|
|
366
|
+
nb::sig("def __array_ufunc__(self, ufunc: object, method: str, "
|
|
367
|
+
"*inputs: object, **kwargs: object) -> object"),
|
|
357
368
|
"ufunc"_a, "method"_a, "inputs"_a, "kwargs"_a);
|
|
358
369
|
|
|
359
370
|
cls.def(nb::self + nb::self, "rhs"_a);
|