This repository aims to provide named, reusable numeric algorithms for C++.
It is in the very early stages, work in progress and contributions are very welcome.
The goal is to provide generic building blocks for numeric calculations. It should help following the no raw loops principle when writing numerics oriented code. As such it aims to provide named, reusable algorithms and not complete solvers or methods for specific problems. So an implementation of Kahan summation would be a good candidate for inclusion, and a finite element solver would be out of scope.
The library currently provides constrained versions of the following STL algorithms.
The algorithms should generally behave very similarly to the standard versions.
The n-th (raw) moment
The order of summation is arbitraty, e.g. it behaves like reduce
and not like accumulate
. If the sample is empty,
the moments are undefined.
Example Usage
auto const snd = nrng::moment<2>(std::array{1, 2, 3, 4, 5});
The mean is the 1st (raw) moment.
auto const mean = nrng::mean(std::array{3., 1., 4., 1., 5., 9.});
The n-th (raw) central moment
where
The order of summation is arbitraty, e.g. it behaves like reduce
and not like accumulate
. If the sample is empty,
the moments are undefined.
Example Usage
auto const snd = nrng::central_moment<2>(std::array{1, 2, 3, 4, 5});
The variance is the 2nd (raw) central_moment.
auto const mean = nrng::variance(std::array{3., 1., 4., 1., 5., 9.});
The standard deviation is the square root of the variance.
auto const mean = nrng::standard_deviation(std::array{3., 1., 4., 1., 5., 9.});
Single addition step of the Kahan summation, which can yield lower numerical errors. Note that this does return a struct
containing the running sum and a compensation term. Which can
then be used as the left argument for the next step. This can be
used as a drop-in for std::plus
in situations where the summation order is fixed (e.g. for accumulate
but not reduce
).
Compensated accumulation of a range in order with the kahan_plus operator. This is a drop-in replacement for accumulate(rng, init)
with error compensation.
The library is header only and has no dependencies, except a C++20 compatible compiler with concept and
ranges support. It can be consumed via cmake by adding it as a subdirectory, in which case the target
nrng::nrng
will be available, or by copying the files under include
to a place where they are found.
Installing the library is currently not supported.
├── CMakeLists.txt
├── external
│ └── nrng
└── src
└── main.cpp
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.15)
project(example LANGUAGES CXX)
add_subdirectory("external/nrng")
add_executable(example "src/main.cpp")
target_link_libraries(example PRIVATE nrng::nrng)
main.cpp
:
#include <nrng/moment.hpp>
#include <array>
int main() {
return nrng::mean(std::array{1, 2, 3, 4, 5});
}
-
A C++ compiler that supports C++20. See cppreference.com to see which features are supported by each compiler.
-
Install Command
-
Debian/Ubuntu:
sudo apt-get install cmake
-
Windows:
choco install cmake -y
-
MacOS:
brew install cmake
-
Those are not required to use the library.
-
Install Command
-
Debian/Ubuntu:
sudo apt-get install ccache
-
Windows:
choco install ccache -y
-
MacOS:
brew install ccache
-
-
Install Command
Follow instructions here: https://github.com/include-what-you-use/include-what-you-use#how-to-install
Instruction for building the tests.
Make a build directory:
mkdir build
By default, (if you don't set environment variables CC
and CXX
), the system default compiler will be used. If the default compiler does not
support C++20 it may be necessary to install a newer compiler and explicitly configure cmake to use it.
Commands for setting the compilers
-
Debian/Ubuntu/MacOS:
Set your desired compiler (
clang
,gcc
, etc):-
Temporarily (only for the current shell)
Run one of the followings in the terminal:
-
clang
CC=clang CXX=clang++
-
gcc
CC=gcc CXX=g++
-
-
Permanent:
Open
~/.bashrc
using your text editor:gedit ~/.bashrc
Add
CC
andCXX
to point to the compilers:export CC=clang export CXX=clang++
Save and close the file.
-
-
Windows:
-
Permanent:
Run one of the followings in PowerShell:
-
Visual Studio generator and compiler (cl)
[Environment]::SetEnvironmentVariable("CC", "cl.exe", "User") [Environment]::SetEnvironmentVariable("CXX", "cl.exe", "User") refreshenv
Set the architecture using vsvarsall:
vsvarsall.bat x64
-
clang
[Environment]::SetEnvironmentVariable("CC", "clang.exe", "User") [Environment]::SetEnvironmentVariable("CXX", "clang++.exe", "User") refreshenv
-
gcc
[Environment]::SetEnvironmentVariable("CC", "gcc.exe", "User") [Environment]::SetEnvironmentVariable("CXX", "g++.exe", "User") refreshenv
-
-
Temporarily (only for the current shell):
$Env:CC="clang.exe" $Env:CXX="clang++.exe"
-
To configure the project and write makefiles, you could use cmake
with a bunch of command line options.
The easier option is to run cmake interactively:
with the Cmake Curses Dialog Command Line tool:
ccmake -S . -B ./build
Once ccmake
has finished setting up, press 'c' to configure the project, press 'g' to generate, and 'q' to quit.
Once you have selected all the options you would like to use, you can build the project (all targets):
cmake --build ./build
For Visual Studio, give the build configuration (Release, RelWithDeb, Debug, etc) like the following:
cmake --build ./build -- /p:configuration=Release
ctest -C Release