Major release.
Dependency changes
* Dropped support for Python 3.6, 3.7 and 3.8.
* Minimum NumPy version changed to 1.22 per NEP 29.
API changes
* Interface to sampler classes simplified to remove previous `sample_chain` and `sample_chains_with_adaptive_warm_up` methods in favour of combining all functions into a single `sample_chains` method, which now requires arguments to be passed specifying both number of warm-up iterations (`n_warm_up_iter`, can be zero) and number of main iterations (`n_main_iter`). All arguments to `sample_chain` other than `n_warm_up_iter`, `n_main_iter` and `init_states` are now keyword only.
* `metric` and optional arguments specifying derivatives (for example `grad_neg_log_dens` and `jacob_constr`) to system classes are now all keyword only.
* `sample_chains` methods now return named tuples with entries `final_states`, `traces` and `statistics`.
* `memmap_enabled` keyword argument to `sample_chains` removed and replaced with `force_memmap` argument, with adjusted semantics that memory mapping is now always enabled when sampling chain in parallel on multiple processes, with `force_memmap` allowing memory mapping to also be used when sampling a chain or chains on a single process.
Bug fixes
* Bug due to `mici.transitions.Transition.statistic_types` being shared across subclasses as a mutable set fixed.
* Accept probabilities now computed using `exp(min(.))` rather than `min(exp(.))` to improve numerical stability.
* `reverse_norm` argument to `ConstrainedLeapfrogIntegrator` initializer was previously ignored - this is now fixed.
* Usages of deprecated `numpy.bool` type removed.
New, changed and removed features
* Added implicit midpoint integrator (`mici.integrators.ImplicitMidpointIntegrator`) for non-separable Hamiltonian systems, with `dh2_dpos` method added to `EuclideanMetricSystem` to allow also using with implicit midpoint integrator for testing purposes.
* Added family of symmetric composition integrators described in [Blanes, Casas, Sanz-Serna (2014)](https://doi.org/10.1137/130932740).
* Added option to record traces during warm-up (`trace_warm_up` argument to `sample_chains` method).
* Added new `mici.interop` module with convenience functions for converting Mici `sample_chains` output to an `arviz.InferenceData` object, sampling a PyMC model with Mici and sampling a PyStan model with Mici.
* Added new projection solver for use with `ConstrainedLeapfrogIntegrator` which performs a Newton iteration with backtracking line search (`mici.solvers.solve_projection_onto_manifold_newton_with_line_search`).
* Default for `projection_solver` argument to `ConstrainedLeapfrogIntegrator` initializer changed to `mici.solvers.solve_projection_onto_manifold_newton`.
* Step size adapter now allows using custom reducer for combining per-chain adapted step sizes.
* Current step size now recorded in integration transition statistics (with key `step_size`) allowing live monitoring using `monitor_stats` argument to `sample_chains`.
* Handling of matrices initialised with non finite values improved with new `mici.errors.LinAlgError` exception being raised.
* Automatic chain truncation on keyboard interrupt removed.
* Norm functions now do not explicitly use NumPy API, instead using array methods / operator overloads, to allow using to array-like inputs such as `jax.Array` instances.
Documentation and packaging
* Documentation now built using Sphinx.
* Additional details and references added to docstrings and formatting improved.
* Project metadata now stored in `pyproject.toml` file with `setup.py` script removed.