Library development – Integraal⌗
An experiment masqueraded as a numerical integration crate – GitHub – Doc
I could yap some more about what the project features are, but I already did for the Scientific Computing in Rust Monthly newsletter. Instead, I’ll just take what I wrote there and containerize the yapping to the second section of this entry.
The project⌗
The crate features a main structure, Integraal
, that acts as the entrypoint for your numerical integration.
You can specify the domain and the function of the integral, as well as the numerical integration method using
methods of the structure. It follows a builder-like pattern.
Domains and functions are described using struct enums for the sake of flexibility. The repository contains usage examples for both analytical expression and sampled values integration. The following numerical integration methods are implemented:
- Riemann summation (both left rule and right rule)
- Trapezoid rule
- Simpson’s rule (different variants depending on the domain & function)
- Boole’s rule
- Romberg’s rule
- Monte Carlo method
Different methods have different requirements and dependencies. All of this is detailed in the documentation.
In the future, the computation kernel may support different execution backends. This would align with the initial motivation behind this crate, that is being an experiment over flexible API designs for HPC.
The vision⌗
If it doesn’t bother you to contemplate some of my ramblings for a few more minutes, you may keep this tab open and continue reading.
This project was initially an experiment, where I could mess around with the builder pattern in Rust. After a discussion with my best friend, I decided to push the experiment a little further: What would a flexible, numerical integration library look like in Rust?
Themes and technologies involved in this strongly overlapped with one of my previous project, a proof of concept for an implementation of the Kokkos programming model in Rust. HPC applications, highly parallelizable –if not embarrassingly parallel– code, flexible and unified API, etc., etc., you get it (or not, doesn’t matter, don’t worry).
You may think that going through with an experiment that has that much in common with a previous one is a waste of time. I agree, but I am a very productive person, and therefore have a lot of time to waste… That’s a lie, and so is the fact that going through with this is a waste of time.
Truth is, I omitted two significant points before:
-
My proof of concept focused on traits, and their usage in relation to portability.
-
The HPC ecosystem in Rust is still very much evolving.
Integraal has neither the same trajectory, nor the same starting point as my proof of concept. For its first release, i.e. the one implementing the most basic features, I based my API around algebraic data types rather than traits. This does not mean that I avoided, or will avoid any form of genericity in the future.
In particular, some of my future plans may require genericity in the form of traits; but I’ll be prepared. As stated in the first part, I consider implementing some form of control over execution backend. This one probably won’t require genericity; if it does, it would most likely be for an internal mechanism, not an exposed item of the API. Another thing that would require significant abstraction and design work is the implementation of N-dimensional integral computations.
This implementation is way down the line though.
For now, this vision will remain, stuck in time, forever bound to the early development stage of this side-project.