Skip to content

EnginesΒΆ

SummaryΒΆ

py-ballisticcalc provides various calculation engines with identical public semantics. The relative merits of the engines are detailed in benchmarks.

Engine Name Speed Dependencies Description
rk4_engine Baseline (1x) None; default Runge-Kutta 4th-order integration
euler_engine 0.5x (slower) None Euler 1st-order integration
verlet_engine 0.7x (slower) None Verlet 2nd-order symplectic integration
cythonized_rk4_engine 50x (faster) [exts] Compiled Runge-Kutta 4th-order
cythonized_euler_engine 40x (faster) [exts] Compiled Euler integration
scipy_engine 10x (faster) scipy Advanced numerical methods
  • This project will default to the rk4_engine.
  • For higher speed and precision use the scipy_engine.
  • For maximum speed use the cythonized_rk4_engine.

To select a specific engine when creating a Calculator, use the optional engine argument:

from py_ballisticcalc import Calculator
calc = Calculator(engine="rk4_engine")
# or via entry-point path
calc = Calculator(engine="my_pkg.my_mod:MyEngine")

Cython EnginesΒΆ

Cythonized engines are compiled for maximum performance. Include the [exts] option to install those:

pip install py-ballisticcalc[exts]
uv add py-ballisticcalc[exts]

Custom EnginesΒΆ

To define a custom engine: Create a separate module with a class that implements the EngineProtocol. You can then load it like:

from py_ballisticcalc import Calculator

calc = Calculator(engine="my_library.my_module:MyAwesomeEngine")

Entry Point: You can also give the engine a named entry point in pyproject.toml/setup.py. The entry point name should end with _engine. Example:

[project.entry-points.py_ballisticcalc]
my_awesome_engine = "my_library.my_module:MyAwesomeEngine"

Then you can load the engine using the entry point name:

from py_ballisticcalc import Calculator

calc = Calculator(engine="my_awesome_engine")

Test a custom engine

To test a specific engine with the project test suite, run pytest with --engine argument. Examples:

pytest ./tests --engine="my_awesome_engine" 
# or
pytest ./tests --engine="my_library.my_module:MyAwesomeEngine"