Why do we need WTF?
Motivation
The standard C++ library already includes a host of FP types including:
floatdoublelong doublestd::complex<float>std::complex<double>std::complex<long double>
…and that’s before we discuss the types introduced by C++23. Conceptually, these types are all used to do the same thing: represent real (or more generally complex) numbers. In practice, the difference among these FP types is that they represent the number with different amounts of bits. Consequently, the range and precision of numbers that can be represented differs by FP type. Unfortunately, the performance of numerics is intimately tied to the FP type used.
Note
For brevity we will focus on the real FP types. Everything we say here readily generalizes to complex FP types as well. WTF fully supports complex values, we just don’t want to keep bringing it up.
A fundamental problem in the software engineering of scientific libraries is
dealing with FP types. Historically, for simplicity many scientific libraries
have assumed double as the FP type at all interfaces. If the user is
storing their data as float, they must convert it to double to call the
interface, and then convert the result back to float after the call.
Admittedly, this is why many scientific libraries provide overloads for other
FP types, but this in turn requires the developer to maintain one interface
per FP type.
C++ libraries can avoid the need to support multiple overloads by using templates. As long as the user of the library is calling the function from C++, this solution works well. However, it is becoming increasingly important to be able to interface scientific software to other languages (e.g., Python). In most cases, interfacing is done through a C-like interface, precluding the use of templates.
Problem Statement
Scientific software developers increasingly need to support multiple FP types. At the same time, they want their software to be callable from multiple languages. Unfortunately, this precludes the use of templates at user-facing interfaces.
Goals
Provide a series of abstractions that are capable of holding arbitrary FP types.
Make it easy for users of WTF to compose algorithms with these abstractions.
Ensure that the user can extend WTF to support their own custom FP types without needing to modify the WTF source.
Ensure that the abstractions can be used in a performant manner.