InterpolatePy 3.3.0__tar.gz → 3.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/ALGORITHMS.md +1 -1
  2. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/PKG-INFO +2 -2
  3. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/README.md +1 -1
  4. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/CMakeLists.txt +1 -1
  5. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/cubic_bspline_interpolation.cpp +8 -9
  6. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/modified_log_quaternion_interpolation.cpp +39 -1
  7. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/algorithms.md +1 -1
  8. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/api-reference.md +1 -1
  9. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/changelog.md +10 -0
  10. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/index.md +1 -1
  11. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/troubleshooting.md +1 -1
  12. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/pyproject.toml +1 -1
  13. interpolatepy-3.3.1/tests/test_cpp_parity.py +143 -0
  14. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/uv.lock +1 -1
  15. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.editorconfig +0 -0
  16. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.gitattributes +0 -0
  17. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.github/FUNDING.yml +0 -0
  18. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.github/workflows/docs.yml +0 -0
  19. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.github/workflows/pre-commit.yml +0 -0
  20. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.github/workflows/publish.yml +0 -0
  21. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.github/workflows/test.yml +0 -0
  22. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.gitignore +0 -0
  23. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.pre-commit-config.yaml +0 -0
  24. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/.python-version +0 -0
  25. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/LICENSE +0 -0
  26. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/codecov.yml +0 -0
  27. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/CMakeLists.txt +0 -0
  28. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_acc_splines.cpp +0 -0
  29. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_bspline.cpp +0 -0
  30. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_cubic_spline.cpp +0 -0
  31. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_motion.cpp +0 -0
  32. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_paths.cpp +0 -0
  33. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_quaternion.cpp +0 -0
  34. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_smoothing_search.cpp +0 -0
  35. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_smoothing_spline.cpp +0 -0
  36. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/bind_tridiagonal.cpp +0 -0
  37. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/bindings/module.cpp +0 -0
  38. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/cmake/InterpolateCppConfig.cmake.in +0 -0
  39. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/cmake/version.hpp.in +0 -0
  40. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/CMakeLists.txt +0 -0
  41. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/bspline_approx_smooth_example.cpp +0 -0
  42. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/bspline_cubic_example.cpp +0 -0
  43. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/bspline_example.cpp +0 -0
  44. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/bspline_interpolator_example.cpp +0 -0
  45. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/concepts_example.cpp +0 -0
  46. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/cubic_smoothing_example.cpp +0 -0
  47. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/cubic_spline_acc1_example.cpp +0 -0
  48. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/cubic_spline_acc2_example.cpp +0 -0
  49. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/cubic_spline_example.cpp +0 -0
  50. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/double_s_example.cpp +0 -0
  51. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/parabolic_linear_example.cpp +0 -0
  52. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/paths_example.cpp +0 -0
  53. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/polynomial_example.cpp +0 -0
  54. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/quaternion_example.cpp +0 -0
  55. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/shared/example_utils.hpp +0 -0
  56. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/spring_quaternion_example.cpp +0 -0
  57. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/examples/trapezoidal_example.cpp +0 -0
  58. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/bspline/approximation_bspline.hpp +0 -0
  59. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/bspline/bspline.hpp +0 -0
  60. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/bspline/bspline_interpolator.hpp +0 -0
  61. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/bspline/bspline_parameters.hpp +0 -0
  62. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/bspline/cubic_bspline_interpolation.hpp +0 -0
  63. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/bspline/smoothing_cubic_bspline.hpp +0 -0
  64. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/concepts.hpp +0 -0
  65. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/config.hpp +0 -0
  66. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/motion/double_s_trajectory.hpp +0 -0
  67. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/motion/motion_types.hpp +0 -0
  68. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/motion/parabolic_blend_trajectory.hpp +0 -0
  69. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/motion/polynomial_trajectory.hpp +0 -0
  70. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/motion/trapezoidal_trajectory.hpp +0 -0
  71. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/path/circular_path.hpp +0 -0
  72. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/path/frenet_frame.hpp +0 -0
  73. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/path/linear_path.hpp +0 -0
  74. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/path/linear_traj.hpp +0 -0
  75. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/quat/log_quaternion_interpolation.hpp +0 -0
  76. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/quat/modified_log_quaternion_interpolation.hpp +0 -0
  77. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/quat/quaternion.hpp +0 -0
  78. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/quat/quaternion_spline.hpp +0 -0
  79. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/quat/shooting_quaternion_interpolation.hpp +0 -0
  80. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/quat/spring_quaternion_interpolation.hpp +0 -0
  81. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/quat/squad_c2.hpp +0 -0
  82. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/spline/cubic_smoothing_spline.hpp +0 -0
  83. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/spline/cubic_spline.hpp +0 -0
  84. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/spline/cubic_spline_with_acc1.hpp +0 -0
  85. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/spline/cubic_spline_with_acc2.hpp +0 -0
  86. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/spline/smoothing_search.hpp +0 -0
  87. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/spline/spline_parameters.hpp +0 -0
  88. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/include/interpolatecpp/tridiagonal.hpp +0 -0
  89. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/approximation_bspline.cpp +0 -0
  90. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/bspline.cpp +0 -0
  91. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/bspline_interpolator.cpp +0 -0
  92. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/circular_path.cpp +0 -0
  93. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/cubic_smoothing_spline.cpp +0 -0
  94. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/cubic_spline.cpp +0 -0
  95. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/cubic_spline_with_acc1.cpp +0 -0
  96. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/cubic_spline_with_acc2.cpp +0 -0
  97. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/double_s_trajectory.cpp +0 -0
  98. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/frenet_frame.cpp +0 -0
  99. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/linear_path.cpp +0 -0
  100. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/linear_traj.cpp +0 -0
  101. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/log_quaternion_interpolation.cpp +0 -0
  102. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/parabolic_blend_trajectory.cpp +0 -0
  103. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/polynomial_trajectory.cpp +0 -0
  104. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/quaternion.cpp +0 -0
  105. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/quaternion_spline.cpp +0 -0
  106. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/shooting_quaternion_interpolation.cpp +0 -0
  107. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/shooting_solver.cpp +0 -0
  108. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/shooting_solver.hpp +0 -0
  109. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/smoothing_cubic_bspline.cpp +0 -0
  110. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/smoothing_search.cpp +0 -0
  111. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/spring_energy.hpp +0 -0
  112. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/spring_gauss_newton.cpp +0 -0
  113. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/spring_quaternion_interpolation.cpp +0 -0
  114. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/spring_solver.cpp +0 -0
  115. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/squad_c2.cpp +0 -0
  116. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/src/trapezoidal_trajectory.cpp +0 -0
  117. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/CMakeLists.txt +0 -0
  118. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/shared/test_data.hpp +0 -0
  119. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_bspline.cpp +0 -0
  120. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_bspline_variants.cpp +0 -0
  121. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_concepts.cpp +0 -0
  122. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_cubic_smoothing_spline.cpp +0 -0
  123. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_cubic_spline.cpp +0 -0
  124. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_cubic_spline_with_acc1.cpp +0 -0
  125. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_cubic_spline_with_acc2.cpp +0 -0
  126. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_double_s_trajectory.cpp +0 -0
  127. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_parabolic_blend_trajectory.cpp +0 -0
  128. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_paths.cpp +0 -0
  129. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_polynomial_trajectory.cpp +0 -0
  130. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_quaternion.cpp +0 -0
  131. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_quaternion_spline.cpp +0 -0
  132. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_shooting_quaternion.cpp +0 -0
  133. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_smoothing_search.cpp +0 -0
  134. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_spring_quaternion.cpp +0 -0
  135. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_trapezoidal_trajectory.cpp +0 -0
  136. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/cpp/tests/test_tridiagonal.cpp +0 -0
  137. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/architecture.md +0 -0
  138. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/assets/extra.css +0 -0
  139. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/assets/extra.js +0 -0
  140. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/contributing.md +0 -0
  141. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/examples.md +0 -0
  142. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/installation.md +0 -0
  143. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/quickstart.md +0 -0
  144. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/tutorials/motion-profiles.md +0 -0
  145. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/tutorials/path-planning.md +0 -0
  146. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/tutorials/quaternion-interpolation.md +0 -0
  147. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/tutorials/spline-interpolation.md +0 -0
  148. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/docs/user-guide.md +0 -0
  149. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/b_spline_approx_ex.py +0 -0
  150. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/b_spline_cubic_ex.py +0 -0
  151. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/b_spline_ex.py +0 -0
  152. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/b_spline_interpolate_ex.py +0 -0
  153. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/b_spline_smooth_ex.py +0 -0
  154. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/c_s_smoot_search_ex.py +0 -0
  155. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/c_s_smoothing_ex.py +0 -0
  156. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/c_s_with_acc1_ex.py +0 -0
  157. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/c_s_with_acc2_ex.py +0 -0
  158. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/cubic_spline_ex.py +0 -0
  159. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/double_s_ex.py +0 -0
  160. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/frenet_frame_ex.py +0 -0
  161. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/lin_poly_parabolic_ex.py +0 -0
  162. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/linear_ex.py +0 -0
  163. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/log_quat_new_ex.py +0 -0
  164. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/lqi_spiral_frenet_ex.py +0 -0
  165. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/main.py +0 -0
  166. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/mlqi_spiral_frenet_ex.py +0 -0
  167. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/polynomials_ex.py +0 -0
  168. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/protocols_ex.py +0 -0
  169. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/quat_visualization_ex.py +0 -0
  170. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/shooting_quaternion_benchmark.py +0 -0
  171. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/simple_paths_ex.py +0 -0
  172. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/spring_quaternion_ex.py +0 -0
  173. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/spring_solver_benchmark.py +0 -0
  174. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/squad_c2_ex.py +0 -0
  175. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/examples/trapezoidal_ex.py +0 -0
  176. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/graphify-out/GRAPH_REPORT.md +0 -0
  177. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/mkdocs.yml +0 -0
  178. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/scripts/__init__.py +0 -0
  179. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/scripts/check_doc_snippets.py +0 -0
  180. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/scripts/check_python_examples.py +0 -0
  181. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/__init__.py +0 -0
  182. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/__init__.py +0 -0
  183. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_bspline.py +0 -0
  184. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_direct.py +0 -0
  185. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_motion_double_s.py +0 -0
  186. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_motion_parabolic.py +0 -0
  187. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_motion_polynomial.py +0 -0
  188. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_motion_trapezoidal.py +0 -0
  189. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_paths.py +0 -0
  190. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_quaternion.py +0 -0
  191. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_quaternion_shooting.py +0 -0
  192. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_quaternion_spring.py +0 -0
  193. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_adapters/_spline.py +0 -0
  194. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_api.py +0 -0
  195. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/_backend.py +0 -0
  196. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/__init__.py +0 -0
  197. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/_approximation_system.py +0 -0
  198. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/_interpolation_system.py +0 -0
  199. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/_parameterization.py +0 -0
  200. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/approximation.py +0 -0
  201. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/core.py +0 -0
  202. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/cubic.py +0 -0
  203. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/interpolation.py +0 -0
  204. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/bsplines/smoothing.py +0 -0
  205. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/linalg.py +0 -0
  206. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/motion/__init__.py +0 -0
  207. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/motion/_double_s_planner.py +0 -0
  208. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/motion/double_s.py +0 -0
  209. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/motion/parabolic.py +0 -0
  210. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/motion/polynomial.py +0 -0
  211. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/motion/trapezoidal.py +0 -0
  212. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/paths/__init__.py +0 -0
  213. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/paths/frenet.py +0 -0
  214. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/paths/geometric.py +0 -0
  215. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/paths/linear.py +0 -0
  216. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/protocols.py +0 -0
  217. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/py.typed +0 -0
  218. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/__init__.py +0 -0
  219. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/_shooting_solver.py +0 -0
  220. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/_spring_energy.py +0 -0
  221. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/_spring_gauss_newton.py +0 -0
  222. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/_spring_slerp.py +0 -0
  223. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/_spring_solver.py +0 -0
  224. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/core.py +0 -0
  225. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/logarithmic.py +0 -0
  226. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/shooting.py +0 -0
  227. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/spline.py +0 -0
  228. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/spring.py +0 -0
  229. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/quaternion/squad.py +0 -0
  230. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/splines/__init__.py +0 -0
  231. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/splines/acceleration1.py +0 -0
  232. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/splines/acceleration2.py +0 -0
  233. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/splines/cubic.py +0 -0
  234. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/splines/search.py +0 -0
  235. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/splines/smoothing.py +0 -0
  236. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/version.py +0 -0
  237. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/visualization/__init__.py +0 -0
  238. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/visualization/bspline.py +0 -0
  239. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/visualization/quaternion.py +0 -0
  240. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/src/interpolatepy/visualization/quaternion_math.py +0 -0
  241. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/__init__.py +0 -0
  242. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/inv_test.py +0 -0
  243. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_b_spline.py +0 -0
  244. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_b_spline_variants.py +0 -0
  245. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_backend.py +0 -0
  246. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_cubic_spline.py +0 -0
  247. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_lin_poly_parabolic.py +0 -0
  248. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_linear.py +0 -0
  249. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_log_quat.py +0 -0
  250. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_motion_profiles.py +0 -0
  251. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_native_adapter_api.py +0 -0
  252. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_package_structure.py +0 -0
  253. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_path_planning.py +0 -0
  254. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_polynomials.py +0 -0
  255. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_protocols.py +0 -0
  256. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_quat_interp.py +0 -0
  257. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_quat_visualization.py +0 -0
  258. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_shooting_quaternion.py +0 -0
  259. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_smoothing.py +0 -0
  260. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_spring_gauss_newton.py +0 -0
  261. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_spring_performance.py +0 -0
  262. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_spring_quaternion.py +0 -0
  263. {interpolatepy-3.3.0 → interpolatepy-3.3.1}/tests/test_squad_c2.py +0 -0
@@ -1,6 +1,6 @@
1
1
  # InterpolatePy algorithm guide
2
2
 
3
- This page is a compact map of the algorithms exposed by InterpolatePy 3.3.0.
3
+ This page is a compact map of the algorithms exposed by InterpolatePy 3.3.1.
4
4
  For constructor signatures and complete method documentation, use the
5
5
  [API reference](docs/api-reference.md). For worked code, use the
6
6
  [tutorials](docs/user-guide.md) and [`examples/`](examples/).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: InterpolatePy
3
- Version: 3.3.0
3
+ Version: 3.3.1
4
4
  Summary: A comprehensive Python library for generating smooth trajectories and curves with precise control over position, velocity, acceleration, and jerk profiles
5
5
  Keywords: interpolation,trajectory planning,motion profiles,robotics,b-splines,cubic splines,frenet frames,path generation,motion control
6
6
  Author-Email: Giorgio Medico <giorgio.medico11@gmail.com>
@@ -56,7 +56,7 @@ at import time.
56
56
  python -m pip install InterpolatePy
57
57
  ```
58
58
 
59
- InterpolatePy 3.3.0 requires Python 3.11 or newer, NumPy 1.26 or newer,
59
+ InterpolatePy 3.3.1 requires Python 3.11 or newer, NumPy 1.26 or newer,
60
60
  and SciPy 1.11 or newer. Install plotting support when needed:
61
61
 
62
62
  ```bash
@@ -20,7 +20,7 @@ at import time.
20
20
  python -m pip install InterpolatePy
21
21
  ```
22
22
 
23
- InterpolatePy 3.3.0 requires Python 3.11 or newer, NumPy 1.26 or newer,
23
+ InterpolatePy 3.3.1 requires Python 3.11 or newer, NumPy 1.26 or newer,
24
24
  and SciPy 1.11 or newer. Install plotting support when needed:
25
25
 
26
26
  ```bash
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.21)
3
3
  if(DEFINED SKBUILD_PROJECT_VERSION)
4
4
  set(INTERPOLATECPP_VERSION "${SKBUILD_PROJECT_VERSION}")
5
5
  else()
6
- set(INTERPOLATECPP_VERSION "3.3.0")
6
+ set(INTERPOLATECPP_VERSION "3.3.1")
7
7
  endif()
8
8
 
9
9
  project(InterpolateCpp
@@ -111,19 +111,18 @@ Eigen::MatrixXd CubicBSplineInterpolation::calculate_control_points(
111
111
  const double b3_k1 = basis_vals[1];
112
112
  const double b3_k2 = basis_vals[2];
113
113
 
114
+ // Independent tests, not if/else: at n == 2 the only row is both first and last.
115
+ main_diag[k - 1] = b3_k1;
116
+ rhs.row(k - 1) = interpolation_points_.row(k);
114
117
  if (k == 1) {
115
- main_diag[0] = b3_k1;
116
- upper_diag[0] = b3_k2;
117
- rhs.row(0) = interpolation_points_.row(k) - b3_k * cp.row(1);
118
- } else if (k == n - 1) {
119
- lower_diag[k - 2] = b3_k;
120
- main_diag[k - 1] = b3_k1;
121
- rhs.row(k - 1) = interpolation_points_.row(k) - b3_k2 * cp.row(n + 1);
118
+ rhs.row(k - 1) -= b3_k * cp.row(1);
122
119
  } else {
123
120
  lower_diag[k - 2] = b3_k;
124
- main_diag[k - 1] = b3_k1;
121
+ }
122
+ if (k == n - 1) {
123
+ rhs.row(k - 1) -= b3_k2 * cp.row(n + 1);
124
+ } else {
125
125
  upper_diag[k - 1] = b3_k2;
126
- rhs.row(k - 1) = interpolation_points_.row(k);
127
126
  }
128
127
  }
129
128
 
@@ -1,6 +1,8 @@
1
1
  #include <interpolatecpp/quat/modified_log_quaternion_interpolation.hpp>
2
2
 
3
+ #include <algorithm>
3
4
  #include <cmath>
5
+ #include <numbers>
4
6
  #include <stdexcept>
5
7
 
6
8
  namespace interpolatecpp::quat {
@@ -15,6 +17,19 @@ void ModifiedLogQuaternionInterpolation::ensure_quaternion_continuity() {
15
17
  }
16
18
  }
17
19
 
20
+ namespace {
21
+
22
+ // Unlike to_axis_angle(), keeps the sign of w so the angle spans [0, 2*pi].
23
+ std::pair<Eigen::Vector3d, double> axis_angle_raw(const Quaternion& q, double eps) {
24
+ const double s = q.w();
25
+ const double sin_half = std::sqrt(std::max(0.0, 1.0 - s * s));
26
+ const Eigen::Vector3d axis =
27
+ sin_half < eps ? Eigen::Vector3d::UnitX() : Eigen::Vector3d(q.vec() / sin_half);
28
+ return {axis, 2.0 * std::acos(std::clamp(s, -1.0, 1.0))};
29
+ }
30
+
31
+ } // namespace
32
+
18
33
  std::pair<Eigen::VectorXd, Eigen::MatrixXd>
19
34
  ModifiedLogQuaternionInterpolation::transform_to_theta_xyz() const {
20
35
  const int n = static_cast<int>(quaternions_.size());
@@ -22,11 +37,34 @@ ModifiedLogQuaternionInterpolation::transform_to_theta_xyz() const {
22
37
  Eigen::MatrixXd xyz_values(n, 3);
23
38
 
24
39
  for (int i = 0; i < n; ++i) {
25
- auto [axis, angle] = quaternions_[i].to_axis_angle();
40
+ auto [axis, angle] = axis_angle_raw(quaternions_[i], kEpsilon);
41
+ // Keep the axis on the previous sample's side so theta stays on one branch.
42
+ if (i > 0 && axis.dot(xyz_values.row(i - 1).transpose()) < 0.0) {
43
+ axis = -axis;
44
+ angle = 2.0 * std::numbers::pi - angle;
45
+ }
26
46
  theta_values[i] = angle;
27
47
  xyz_values.row(i) = axis.transpose();
28
48
  }
29
49
 
50
+ // Same algorithm as np.unwrap, so jumps of exactly pi resolve identically.
51
+ constexpr double pi = std::numbers::pi;
52
+ double correction = 0.0;
53
+ double prev_raw = theta_values[0];
54
+ for (int i = 1; i < n; ++i) {
55
+ const double raw = theta_values[i];
56
+ const double dd = raw - prev_raw;
57
+ prev_raw = raw;
58
+ if (std::abs(dd) >= pi) {
59
+ double dd_mod = dd + pi - 2.0 * pi * std::floor((dd + pi) / (2.0 * pi)) - pi;
60
+ if (dd_mod == -pi && dd > 0.0) {
61
+ dd_mod = pi;
62
+ }
63
+ correction += dd_mod - dd;
64
+ }
65
+ theta_values[i] = raw + correction;
66
+ }
67
+
30
68
  return {theta_values, xyz_values};
31
69
  }
32
70
 
@@ -1,6 +1,6 @@
1
1
  # Algorithms
2
2
 
3
- This guide summarizes the numerical families in InterpolatePy 3.3.0 and helps
3
+ This guide summarizes the numerical families in InterpolatePy 3.3.1 and helps
4
4
  select between them. The [API reference](api-reference.md) supplies signatures;
5
5
  the tutorials supply complete code.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # API reference
2
2
 
3
- This page documents the supported Python API for InterpolatePy 3.3.0. Import
3
+ This page documents the supported Python API for InterpolatePy 3.3.1. Import
4
4
  these objects from `interpolatepy` unless a module-qualified exception is shown.
5
5
 
6
6
  !!! note "Backend-dependent class identity"
@@ -3,6 +3,16 @@
3
3
  This changelog records released InterpolatePy behavior. Dates and versions match
4
4
  the repository tags. The project follows [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## 3.3.1 — 2026-09-27
7
+
8
+ ### Fixed
9
+
10
+ - C++ `CubicBSplineInterpolation` now applies the end-velocity correction with
11
+ three waypoints, matching the Python implementation.
12
+ - C++ `ModifiedLogQuaternionInterpolation` now keeps the rotation axis on one
13
+ side and unwraps the angle like the Python implementation, fixing rotations
14
+ past π and varying-axis sequences.
15
+
6
16
  ## 3.3.0 — 2026-09-19
7
17
 
8
18
  ### Added
@@ -5,7 +5,7 @@
5
5
  [![Python](https://img.shields.io/badge/python-3.11+-blue)](https://www.python.org/downloads/)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/GiorgioMedico/InterpolatePy/blob/main/LICENSE)
7
7
 
8
- InterpolatePy 3.3.0 provides trajectory planning and interpolation for scalar
8
+ InterpolatePy 3.3.1 provides trajectory planning and interpolation for scalar
9
9
  motion, parametric curves, 3D paths, and rotations. It runs with a NumPy/SciPy
10
10
  implementation by default and can transparently use an optional C++20 backend.
11
11
 
@@ -22,7 +22,7 @@ Check the installed version:
22
22
  python -c "import interpolatepy as ip; print(ip.__version__)"
23
23
  ```
24
24
 
25
- This documentation targets 3.3.0. Import public algorithms from `interpolatepy`.
25
+ This documentation targets 3.3.1. Import public algorithms from `interpolatepy`.
26
26
  The trapezoidal `TrajectoryParams` is the intentional exception:
27
27
 
28
28
  ```python
@@ -10,7 +10,7 @@ maintainers = [
10
10
  ]
11
11
  description = "A comprehensive Python library for generating smooth trajectories and curves with precise control over position, velocity, acceleration, and jerk profiles"
12
12
  readme = "README.md"
13
- version = "3.3.0"
13
+ version = "3.3.1"
14
14
  license = "MIT"
15
15
  license-files = ["LICENSE"]
16
16
  requires-python = ">=3.11"
@@ -0,0 +1,143 @@
1
+ """Parity of the C++ backend against the pure-Python reference at small n."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ import numpy as np
8
+ import numpy.testing as npt
9
+ import pytest
10
+
11
+ import interpolatepy as ip
12
+ from interpolatepy.bsplines.cubic import CubicBSplineInterpolation as PyCubicBSplineInterpolation
13
+ from interpolatepy.bsplines.smoothing import BSplineParams as PyBSplineParams
14
+ from interpolatepy.bsplines.smoothing import SmoothingCubicBSpline as PySmoothingCubicBSpline
15
+ from interpolatepy.quaternion import logarithmic as py_logarithmic
16
+ from interpolatepy.quaternion.core import Quaternion as PyQuaternion
17
+ from interpolatepy.splines.acceleration1 import CubicSplineWithAcceleration1 as PyCubicSplineWithAcceleration1
18
+ from interpolatepy.splines.acceleration2 import CubicSplineWithAcceleration2 as PyCubicSplineWithAcceleration2
19
+ from interpolatepy.splines.acceleration2 import SplineParameters as PySplineParameters
20
+ from interpolatepy.splines.cubic import CubicSpline as PyCubicSpline
21
+ from interpolatepy.splines.smoothing import CubicSmoothingSpline as PyCubicSmoothingSpline
22
+
23
+ pytestmark = pytest.mark.skipif(not ip.HAS_CPP, reason="C++ backend not available")
24
+
25
+ TOL = 1e-9
26
+ METHODS = ["equally_spaced", "chord_length", "centripetal"]
27
+ FIELD_POINTS = [[0.0, 0.0, 0.0], [0.5, 0.2, 0.4], [1.0, 0.0, 1.0]]
28
+
29
+
30
+ def _points(n: int) -> np.ndarray:
31
+ extra = [[1.4, 0.6, 0.7], [2.0, 0.1, 0.3], [2.3, -0.5, 0.9]]
32
+ return np.array(FIELD_POINTS + extra[: n - 3])
33
+
34
+
35
+ def _bspline_grid(curve: Any) -> np.ndarray:
36
+ return np.array([curve.evaluate(u) for u in np.linspace(curve.u_min, curve.u_max, 201)])
37
+
38
+
39
+ class TestCubicBSplineInterpolationParity:
40
+ @pytest.mark.parametrize("n", [3, 4, 5, 6])
41
+ @pytest.mark.parametrize("method", METHODS)
42
+ @pytest.mark.parametrize("velocities", [False, True])
43
+ def test_matches_python_and_hits_waypoints(self, n: int, method: str, velocities: bool) -> None:
44
+ points = _points(n)
45
+ kwargs: dict[str, Any] = {"v0": [0.3, -0.2, 0.5], "vn": [-0.4, 0.1, 0.2]} if velocities else {}
46
+ cpp = ip.CubicBSplineInterpolation(points, method=method, **kwargs)
47
+ py = PyCubicBSplineInterpolation(points, method=method, **kwargs)
48
+
49
+ npt.assert_allclose(cpp.control_points, py.control_points, atol=TOL)
50
+ npt.assert_allclose(_bspline_grid(cpp), _bspline_grid(py), atol=TOL)
51
+ for u, point in zip(cpp.u_bars, points):
52
+ npt.assert_allclose(cpp.evaluate(u), point, atol=TOL)
53
+
54
+ @pytest.mark.parametrize("method", METHODS)
55
+ def test_auto_derivatives_three_points(self, method: str) -> None:
56
+ cpp = ip.CubicBSplineInterpolation(FIELD_POINTS, method=method, auto_derivatives=True)
57
+ py = PyCubicBSplineInterpolation(FIELD_POINTS, method=method, auto_derivatives=True)
58
+ npt.assert_allclose(_bspline_grid(cpp), _bspline_grid(py), atol=TOL)
59
+
60
+
61
+ class TestSmallestNSplineParity:
62
+ """Tridiagonal/banded solvers with boundary-row corrections, at their smallest n."""
63
+
64
+ t = np.linspace(0.0, 1.0, 301)
65
+
66
+ @pytest.mark.parametrize(("v0", "vn"), [(0.0, 0.0), (0.7, -0.3)])
67
+ def test_cubic_spline(self, v0: float, vn: float) -> None:
68
+ args = ([0.0, 1.0, 2.5], [0.0, 1.0, 0.2])
69
+ cpp, py = ip.CubicSpline(*args, v0=v0, vn=vn), PyCubicSpline(*args, v0=v0, vn=vn)
70
+ t = self.t * 2.5
71
+ npt.assert_allclose(cpp.evaluate(t), py.evaluate(t), atol=TOL)
72
+
73
+ @pytest.mark.parametrize("n", [3, 4])
74
+ def test_cubic_spline_with_acceleration1(self, n: int) -> None:
75
+ args = ([0.0, 1.0, 2.5, 3.0][:n], [0.0, 1.0, 0.2, 0.8][:n])
76
+ kw: dict[str, Any] = {"v0": 0.4, "vn": -0.2, "a0": 0.1, "an": 0.3}
77
+ cpp, py = ip.CubicSplineWithAcceleration1(*args, **kw), PyCubicSplineWithAcceleration1(*args, **kw)
78
+ t = self.t * args[0][-1]
79
+ npt.assert_allclose(cpp.evaluate(t), py.evaluate(t), atol=TOL)
80
+
81
+ @pytest.mark.parametrize("n", [2, 3])
82
+ def test_cubic_spline_with_acceleration2(self, n: int) -> None:
83
+ args = ([0.0, 1.0, 2.5][:n], [0.0, 1.0, 0.2][:n])
84
+ kw: dict[str, Any] = {"v0": 0.4, "vn": -0.2, "a0": 0.1, "an": 0.3}
85
+ cpp = ip.CubicSplineWithAcceleration2(*args, ip.SplineParameters(**kw))
86
+ py = PyCubicSplineWithAcceleration2(*args, PySplineParameters(**kw))
87
+ t = self.t * args[0][-1]
88
+ npt.assert_allclose(cpp.evaluate(t), py.evaluate(t), atol=TOL)
89
+
90
+ def test_cubic_smoothing_spline(self) -> None:
91
+ args = ([0.0, 1.0, 2.5], [0.0, 1.0, 0.2])
92
+ kw: dict[str, Any] = {"mu": 0.6, "v0": 0.4, "vn": -0.2}
93
+ cpp, py = ip.CubicSmoothingSpline(*args, **kw), PyCubicSmoothingSpline(*args, **kw)
94
+ t = self.t * 2.5
95
+ npt.assert_allclose(cpp.evaluate(t), py.evaluate(t), atol=TOL)
96
+
97
+ @pytest.mark.parametrize("enforce_endpoints", [False, True])
98
+ @pytest.mark.parametrize("method", METHODS)
99
+ def test_smoothing_cubic_bspline(self, enforce_endpoints: bool, method: str) -> None:
100
+ kw: dict[str, Any] = {
101
+ "mu": 0.7,
102
+ "method": method,
103
+ "enforce_endpoints": enforce_endpoints,
104
+ "v0": [0.3, 0.0, 0.1],
105
+ }
106
+ cpp = ip.SmoothingCubicBSpline(FIELD_POINTS, ip.BSplineParams(**kw))
107
+ py = PySmoothingCubicBSpline(FIELD_POINTS, PyBSplineParams(**kw))
108
+ npt.assert_allclose(_bspline_grid(cpp), _bspline_grid(py), atol=TOL)
109
+
110
+
111
+ def _z_rotation(angle: float) -> PyQuaternion:
112
+ return PyQuaternion(np.cos(angle / 2.0), 0.0, 0.0, np.sin(angle / 2.0))
113
+
114
+
115
+ def _as_array(q: PyQuaternion) -> np.ndarray:
116
+ return np.array([q.w, q.x, q.y, q.z])
117
+
118
+
119
+ @pytest.mark.parametrize("name", ["ModifiedLogQuaternionInterpolation", "LogQuaternionInterpolation"])
120
+ class TestLogQuaternionParity:
121
+ times = (0.0, 0.2, 0.4, 0.6, 0.8, 1.0)
122
+
123
+ def _pair(self, name: str, quats: list[PyQuaternion]) -> tuple[Any, Any]:
124
+ return getattr(ip, name)(self.times, quats), getattr(py_logarithmic, name)(self.times, quats)
125
+
126
+ def test_rotation_past_pi_is_monotone(self, name: str) -> None:
127
+ quats = [_z_rotation(a) for a in np.linspace(0.0, 3.6, len(self.times))]
128
+ cpp, py = self._pair(name, quats)
129
+ t = np.linspace(0.0, 1.0, 241)
130
+ cpp_q = np.array([_as_array(cpp.evaluate(ti)) for ti in t])
131
+ npt.assert_allclose(cpp_q, [_as_array(py.evaluate(ti)) for ti in t], atol=TOL)
132
+
133
+ angles = np.unwrap(2.0 * np.arctan2(cpp_q[:, 3], cpp_q[:, 0]))
134
+ assert np.all(np.diff(angles) > 0.0)
135
+ npt.assert_allclose(angles[-1], 3.6, atol=TOL)
136
+
137
+ def test_varying_axis_matches_python(self, name: str) -> None:
138
+ rng = np.random.default_rng(7)
139
+ quats = [PyQuaternion(*(q / np.linalg.norm(q))) for q in rng.normal(size=(len(self.times), 4))]
140
+ cpp, py = self._pair(name, quats)
141
+ for ti in np.linspace(0.0, 1.0, 241):
142
+ npt.assert_allclose(_as_array(cpp.evaluate(ti)), _as_array(py.evaluate(ti)), atol=TOL)
143
+ npt.assert_allclose(cpp.evaluate_velocity(ti), py.evaluate_velocity(ti), atol=1e-8)
@@ -652,7 +652,7 @@ wheels = [
652
652
 
653
653
  [[package]]
654
654
  name = "interpolatepy"
655
- version = "3.3.0"
655
+ version = "3.3.1"
656
656
  source = { editable = "." }
657
657
  dependencies = [
658
658
  { name = "numpy" },
File without changes
File without changes
File without changes