This project is still in its infancy and is updated regularly.
This project is a collection of code written in C89/C90 (commonly called ANSI C) for mathematicians and physicists to use on various types of projects. It started with rss_ringoccs, a suite of tools written for processing the Cassini radio science data, which is written mostly in C (but also Python), but eventually grew beyond the scope of just astronomy.
There are no dependencies other than a C compiler and the C standard library. The library is written entirely in ISO C89/C90 compliant code, and no C99/C11 or GCC extensions are used. It compiles with C99 and C11/C18 compilers, so it is more fitting to say it is written in the intersection of these standards.
Run the Makefile with (FreeBSD
users should use gmake
):
make
The Makefile is parallelizable which saves quite a bit of time, especially on emulated architectures:
make -j
Options to pass to make
:
OMP=1
Compile with
OpenMP
support. WARNING Apple's version of clang does NOT support OpenMP, and the-fopenmp
option will result in an error. Homebrew has versions of clang and gcc that do support OpenMP. This option is particularly recommended if you will be doing a lot of computations with special functions in Python using thetmpyl
library and have a CPU with a decent number of cores.
NO_INLINE=1
Do not use any inline code. This may (pending other options) result in a smaller
libtmpl.so
file, but several functions become significantly slower (not recommended). If your compiler does not supportC99
or higher, and does not support thegcc
inline
extension, enable this option.
NO_MATH=1
Do not use
libtmpl
's implementation oflibm
, the C standard library for mathematical tools, instead using your compilers implementation. This may be recommended. Tests againstglibc
,FreeBSD libc
, andMSVC
's implementation oflibm
show thatlibtmpl
can be significantly faster while achieving 1 ULP in error (all functions have benchmarks in thetests/
directory and you may see for yourself), but this has only been tested on the architectures supported by the Debian GNU/Linux operating system (amd64/x86_64
,i386
,aarch64/arm64
,armhf
,armel
,mipsel
,mips
,mips64el
,ppc64el
,powerpc
,s390x
,alpha
,riscv
,sh4
,sparc
). All architectures other thanamd64/x86_64
andaarch64/arm64
were emulated usingdebootstrap
+chroot
withQEMU
. Time-tests showlibtmpl
performs well on these architectures, but results may not be indicative of actual hardware. Users of architectures not listed may wish to use their defaultlibm
. Also, if your compiler does not support theIEEE-754
standard (most do), or does not support type-punning forunion
, the portable algorithms (algorithms that do not useIEEE-754
or type-punning) are much slower. In these instances you may wish to use the defaultlibm
.
NO_INT=1
A few functions (like
tmpl_Double_Mod_2
) can get significant performance boosts if 32-bit and 64-bit fixed width integers are available. This is not required by the C language, however, and the typesuint64_t
anduint32_t
are not required to be defined instdint.h
, even for C99 compliant compilers (but these types usually are, in practice). Theconfig.c
file will attempt to detect these integer sizes in a C89 compatible manner by examining the macros inlimits.h
. If you wish to skip all of this (not recommended), enable this option. The alternative algorithms use manipulations of the bit-fields that represent 32-bitfloat
and 64-bitdouble
, rather than type-punning 32-bit and 64-bit integers.
NO_LONGLONG=1
Skip
long long
functions. If your compiler supports C99 or higher, thelong long
type is available. In certain environments (most modern machines running GNU/Linux, FreeBSD, or macOS)long long
andlong
are identical, meaning it is somewhat wasteful to have two versions of the same function. Enable this option if you only wish to uselong
functions.
NO_IEEE=1
Disable use of the
IEEE
formats forfloat
anddouble
. Theconfig.c
file should detect if your compiler supports this, and type-punning forunion
, so you should not need to set this option manually (not recommended).
NO_ASM=1
Only applicable if
NO_MATH
is not set, and forx86_64/amd64
,i386
,arm64/aarch64
, andarmv7l
machines. Some functions, likesqrt
, can be handled efficiently in assembly code. If you wish to use only C code, set this option (not recommended).
FASM=1
Use the flat assembler instead of the assembly language used by
gcc
andclang
. You must havefasm
installed to use this. This option is ignored ifNO_ASM=1
is set. Only applicable onx86_64/amd64
machines.
CC=cc
The C compiler you use. On Debian GNU/Linux and derivatives (Ubuntu, etc.)
gcc
,clang
,tcc
, andpcc
have all been tested and work as expected. Fortcc
you MUST either pass theNO_ASM=1
option since this compiler (as of this writing) does not support assembly language, or useFASM=1
if you havefasm
installed.
EXTRA_FLAGS=
Any extra compiler flags you wish to pass. For example, with
CC=clang
you can passEXTRA_FLAGS="-Weverything -Wno-padded -Wno-float-equal"
to see iflibtmpl
builds with all flags (except-Wpadded
and-Wfloat-equal
) enabled.
ARCH=
Manually set the name of the architecture you are using. The Makefile attempts to detect your architecture via the
uname -m
unix command. This will most likely work for you. The sole exception I came across is emulating ani386
machine on anx86_64/amd64
host. The result ofuname -m
isx86_64
, even though the emulated architecture isi386
. As a result the wrong assembly code is used and the compiling fails. SetARCH=i386
to manually override this if you're in a similar situation. (Note: Emulatingaarch64
,mips
,powerpc
, etc. on anx86_64
host works fine without the need to set this option).
Afterwords, if you would like to install libtmpl in /usr/local/lib
, run:
sudo make install
You may need to update the LD_LIBRARY_PATH environment variable.
Add the following to your .bashrc
, .shrc
, or whichever shell you're using.
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
If you did not install libtmpl to /usr/local/lib
, try:
export LD_LIBRARY_PATH="/path/to/libtmpl:$LD_LIBRARY_PATH"
To remove all build and .so
files, run:
make clean
To uninstall, run:
sudo make uninstall
A bash
script is available, but results in a larger and less performant build.
By default it has nearly all compiler warnings enabled for gcc
and clang
(including -Weverything
with clang
) and is used internally as a
quick error check.
To use, run:
sudo bash make.sh
Options:
-cc=
C
compiler to be used. Tested withgcc
,clang
,tcc
, andpcc
on Debian GNU/Linux.
-std=
C
standard to use. Default is-std=c89
.
-omp
Compile with OpenMP support.
-inplace
Do not install
libtmpl
into/usr/local/lib/
and/usr/local/include/
. Use this option if you do not havesudo
privileges.
-inline
Use inline code. You must have
-std
set toc99
or higher.
-nomath
Do not use
libtmpl
's implementation oflibm
. Same asNO_MATH=1
in the Makefile.
-noieee
Do not use any type-punning code or code that takes advantage of the
IEEE-754
floating point format.
-noint
Do not use any code that uses fixed-width integers.
-longlong
Compile
long long
code. Must have-std=c99
or higher.
-monster
libtmpl
was written in a way that allows all.c
files to be#include
d into one file and then compiled. While this may seem silly, compilers lacking link-time optimization can optimize the library at compile time, resulting in a very performant build. Astronomical computations performed byrss_ringoccs
are about twice as fast this way. If your compiler has decent link-time optimization it makes only a small difference. This option creates a single.c
file that#include
s the entirety oflibtmpl
, appropriately namedmonster.c
, and then compiles this.
A very primitive batch script exists for Windows users. Run the script with:
C:\Users\ryan\source\repos\libtmpl>make.bat
This creates libtmpl.lib in the libtmpl/
directory.
It does not copy the include/
directory or the library to any system
directories. This has been tested using a Windows 10 virtual machine and it
worked as expected. It compiles with MSVC
's cl
by default. Pass the option
clang
or clang-cl
to use LLVM's clang
compiler.
Almost all mathematical functions of real or complex variables are computed via one of two methods:
- Argument reduction:
Reduce the input
x
to a small range[a, b]
and then accurately compute the function in the range using some numerical method. Ex:sin
,cos
,log
,sqrt
.
- Separate argument into windows:
Determine if the input
x
falls in one of the ranges[a_0, b_0]
, ...,[a_n, b_n]
, allowing fora_0 = -inf
andb_n = +inf
, and then compute the function in this range using some numerical method. Ex:Bessel_J0
,Bessel_I0
. Usually Taylor series for small inputs and asymptotic expansions for large.
The numerical methods are typically one of the following:
- Taylor / Maclaurin Series.
- Pade Approximants.
- Asymptotic Expansions.
- Chebyshev Polynomials.
- Remez exchange.
Inside data/
lies all of the code for computing the coefficients of these
approximations. None of the code is directly used in libtmpl
, indeed most
files are in Python
. This directory is kept in this repository for the sake
of studying algorithms. In particular, for seeing where these approximations
come from.
All functions have examples of basic usage.
All header and inline files for libtmpl
.
The source files. Mostly .c
, but a few assembly files are found for certain
architectures.
Time and accuracy tests of libtmpl
against other libraries. To run these
tests will require these libraries being available. Running these tests is
not required, and they are mostly for internal use and to verify the
algorithms implemented in libtmpl.
Language bindings, or wrappers, are provided for C++
, Python
,
and IDL
(also the Free/Open-Source implementation GDL
). All bindings require
libtmpl
being built beforehand. The source codes used to live in this
repository, but have since moved to their own for easier management. These
can be found via the following links.
libtmpl is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libtmpl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with libtmpl. If not, see <https://www.gnu.org/licenses/>.