This monograph is an exposition of the Owl library in OCaml for building applications that make essential use of numerical algorithms. These numerical algorithms are the basis of most engineering applications--mechanical, electrical, and electronic systems grounded in physics. Numerical algorithms are also the foundation of neural networks, which are the basis of artificial intelligence (AI) applications whose widespread use we are currently witnessing.

This book should be read as a tutorial on the facilities of the Owl library. The approach followed by the book is to introduce a topic using OCaml snippets illustrating simple examples. These snippets are self-contained and can be easily typed in by the reader, or, for convenience, the authors have published all the snippets in GitHub to enable copy-paste of the code itself.

The topics and chapters are arranged in order of complexity, with later topics building upon the earlier ones. Each topic is self-contained and the text illustrates how to use the functions from the Owl library to address the topic. For example, the very first topic covered is interpolation, which forms the basis of other topics covered in the book. This chapter introduces the concepts of polynomial interpolation and rational interpolation. It introduces the basics of algorithms that perform interpolation--the Neville algorithm for polynomial interpolation and the Bulirsch–Stoer algorithm for rational interpolation. It gives sufficient intuition of when to choose different methods and an idea of how they can be implemented in OCaml. Each chapter also has appropriate references to the original algorithms implemented in the Owl library.

This initial chapter gives a taste of how the rest of the book is organized--with just enough details of the algorithms to keep the reader engaged and code snippets to solve a particular problem to encourage actually writing and executing the code in the system. The code snippets in many cases are simplified versions of the actual algorithm, and the reader will benefit from closely reviewing the algorithms in order to understand them--perhaps taking a detour by reviewing the original publication--and at the same time gain some experience using the Owl library. The topics covered include a broad spectrum of numerical computation: statistics, image processing, approximation, optimization, and leading up to machine learning.

My favorite chapter is the one on automatic differentiation (AD). This family of algorithms is the foundation for precise and efficient numerical algorithms and are used extensively for building neural networks. The two different algorithms for AD are explained quite nicely, and a simple (but fully functional) implementation is developed in OCaml--it is quite an uplifting experience to follow the text step by step and end up with a program that can perform some very sophisticated computations.

One word about the OCaml system itself is worth making at this point. The Owl library can be downloaded and installed, and it works best in a Linux system. The library is configured and built using the Dune build system, which allows launching an interactive read–eval–print loop (REPL) interface using the UTop target for the build system. OCaml has its own peculiarities, from something as simple as the syntax for floating point numbers to the module system and syntax for accessing functions from modules. The book assumes that the reader is already familiar with the OCaml programming language and its development environment.

It is also worth mentioning what this book is not: it is not an exposition of the design criteria for building a wide-ranging numerical computing library--there is very little discussion of the design principles for building a numerical library in OCaml. For example, the library makes very extensive use of imperative features of OCaml: references, side effects, imperative for-loops, and so on. There is no discussion of the pragmatic choices made by Owl, which interfaces with external libraries such as basic linear algebra subprograms (BLAS) and Sundials, and no effort to reinvent these algorithms in a “pure” functional setting. There is some discussion, in passing, of the utility of the OCaml module system and the polymorphic type system to simplify programming--the library is parameterized on different datatypes (singles, doubles, complex) and different matrix representations (dense and sparse). However, the exposition in the book does not really discuss the tradeoffs that the authors of Owl have made between usability, expressiveness, and programming convenience.

What I found missing in the book are exercises for students to practice programming using OCaml and the Owl library, reinforcing the material they have learnt. I feel that each topic can potentially have some exercises that build upon the snippets that are presented in the text, and which would help build up skill in using the Owl library. Exercises can also help guide different directions of exploration for a student: exploring different algorithms in the literature, exploring different applications of the algorithms presented in the text, and also exploring ideas for projects.

*OCaml scientific computing* serves as a valuable resource for computer science students embarking on their initial exploration of numerical algorithms. Whether you are diving into numerical methods for the first time or you are experienced with numerical algorithms and want to understand how to use OCaml for this purpose, this book provides practical guidance and bridges theory with hands-on implementation. By leveraging the Owl library, readers can gain insights into algorithmic concepts while building a solid foundation for further study.