OwlDE: making ODEs first-class Owl citizens

Today, Owl can be used to solve a wide range of scientific problems: it provides efficient types for handling multidimensional arrays and linear algebra operations built on top of BLAS and LAPACK; it supports machine learning applications with a powerful computational graph engine and automatic differentiation pipeline. To improve efficiency, Owl allows offloading computations to distributed systems and GPUs. With the recent addition of dataframes and integration with Jupyter Notebooks provided by ocaml-jupyter, Owl has the chance to become an excellent framework for exploratory mathematical analysis.


Design of the core module
The lack of automation around type classes and dynamic typing in OCaml may seem at first a huge impediment to designing a flexible and ergonomic ODE integrator library.Indeed, such a library should ideally allow the users to seamlessly use different algorithms that require different kinds of inputs and options, and return varying kinds of outputs.Such constraints on input/output types pose a major problem for the strong static type system of OCaml, even if they are in principle implementable exploiting advanced language features, and were one of the central issues in designing OwlDE.
We iterated various options and settled on the use of first-class modules.These have been introduced in OCaml since version 3.12, and further improved in subsequent releases.With first-class modules the user can parametrise functions over modules, allowing us to find a middle ground between the verbosity of functorial code and the composability of OCaml functions.The flexibility of this API allowed us to provide integration and bindings to external frameworks like SUNDIALS or ODEPACK in a completely seamless way.Such an API allowed us to compare native implementations with industry-grade solvers, both for mathematical exploration, testing and benchmark purposes.
To give an idea of the interface, the following code allows to integrate the initial value problem The tight integration with the OCaml and Owl ecosystem allows us also to benefit from some of their strengths.The strong static type system made refactoring and code analysis an immediate task, and greatly reduced the necessary test surface.The powerful functorised ndarray subsystem exposed by Owl made the library trivially extensible also in somewhat unexpected directions.Indeed, it is possible to take the integrators exposed by OwlDE and use them to reproduce the work of (Chen, Rubanova, Bettencourt, & Duvenaud, 2018) without the need to rewrite any of the core functions, as done in adjoint_ode.Similarly, it is possible to extend the range of integrators and introduce new ones rather seamlessly, as done in cviode, an implementation of the integrators introduced in (Vermeeren, Bravetti, & Seri, 2019).
One further strength of this library, comes from its native OCaml component, which can be compiled to JavaScript and used for interactive simulations in the browser, as demoed during the OCaml Workshop at ICFP 2019 in Berlin.The demo and the usage instructions are freely available at owlde-demo-icfp2019.

Conclusion
When it comes to scientific programming, fast prototyping and ease of use have long been considered the province of dynamically-typed languages like python.However, our experience developing Owl and OwlDE, and the feedback from users who primarily use these tools for research, suggests otherwise.In fact, the OCaml type system often ensures correctness and speeds up computations without increasing verbosity, or hindering usability and readability.In many cases, we discovered that porting python code to OCaml code via Owl was nearly trivial and the resulting OCaml code was often comparable in length, but with the added benefits of fewer runtime errors and improved performance.We look forward to developing OwlDE and Owl further with inputs from the OCaml community.