C++ implementation of the Python Numpy library

NumCpp: A Templatized Header Only C++ Implementation of the Python NumPy Library
Author: David Pilger
Version: 
License 
Testing
Compilers: Visual Studio: 2022 GNU: 13.3, 14.2, 15.2 Clang: 18, 19, 20
Boost Versions: 1.73+
Documentation
GitHub
Installation
Building
Release Notes
From NumPy To NumCpp โ A Quick Start Guide
This quick start guide is meant as a very brief overview of some of the things that can be done with NumCpp. For a full breakdown of everything available in the NumCpp library please visit the Full Documentation.
CONTAINERS
The main data structure in NumCpp is the NdArray. It is inherently a 2D array class, with 1D arrays being implemented as 1xN arrays. There is also a DataCube class that is provided as a convenience container for storing an array of 2D NdArrays, but it has limited usefulness past a simple container.
| NumPy | NumCpp | | :------------------------------------------: | :---------------------------------------------------: | |
= np.array([[1, 2], [3, 4], [5, 6]]) | ::NdArray<int> a = { {1, 2}, {3, 4}, {5, 6} } | | .reshape([2, 3]) | .reshape(2, 3) | | .astype(np.double) | .astype<double>() |
INITIALIZERS
Many initializer functions are provided that return NdArrays for common needs.
| NumPy | NumCpp | | :-------------------------: | :----------------------------------------------------: | |
.linspace(1, 10, 5) | ::linspace<dtype>(1, 10, 5) | | .arange(3, 7) | ::arange<dtype>(3, 7) | | .eye(4) | ::eye<dtype>(4) | | .zeros([3, 4]) | ::zeros<dtype>(3, 4) | | | ::NdArray<dtype>(3, 4) a = 0 | | .ones([3, 4]) | ::ones<dtype>(3, 4) | | | ::NdArray<dtype>(3, 4) a = 1 | | .nans([3, 4]) | ::nans(3, 4) | | | ::NdArray<double>(3, 4) a = nc::constants::nan | | .empty([3, 4]) | ::empty<dtype>(3, 4) | | | ::NdArray<dtype>(3, 4) a |
SLICING/BROADCASTING
NumCpp offers NumPy style slicing and broadcasting.
| NumPy | NumCpp | | :----------------: | :---------------------------------------: | |
[2, 3] | (2, 3) | | [2:5, 5:8] | (nc::Slice(2, 5), nc::Slice(5, 8)) | | | ({2, 5}, {5, 8}) | | [:, 7] | (a.rSlice(), 7) | | [a > 5] | [a > 5] | | [a > 5] = 0 | .putMask(a > 5, 0) |
RANDOM
The random module provides simple ways to create random arrays.
| NumPy | NumCpp | | :------------------------------------: | :----------------------------------------------------: | |
.random.seed(666) | ::random::seed(666) | | .random.randn(3, 4) | ::random::randN<double>(nc::Shape(3, 4)) | | | ::random::randN<double>({3, 4}) | | .random.randint(0, 10, [3, 4]) | ::random::randInt<int>(nc::Shape(3, 4), 0, 10) | | | ::random::randInt<int>({3, 4}, 0, 10) | | .random.rand(3, 4) | ::random::rand<double>(nc::Shape(3,4)) | | | ::random::rand<double>({3, 4}) | | .random.choice(a, 3) | ::random::choice(a, 3) |
CONCATENATION
Many ways to concatenate NdArray are available.
| NumPy | NumCpp | | :-------------------------------: | :---------------------------------------: | |
.stack([a, b, c], axis=0) | ::stack({a, b, c}, nc::Axis::ROW) | | .vstack([a, b, c]) | ::vstack({a, b, c}) | | .hstack([a, b, c]) | ::hstack({a, b, c}) | | .append(a, b, axis=1) | ::append(a, b, nc::Axis::COL) |
DIAGONAL, TRIANGULAR, AND FLIP
The following return new NdArrays.
| NumPy | NumCpp | | :----------------------: | :------------------------------: | |
.diagonal(a) | ::diagonal(a) | | .triu(a) | ::triu(a) | | .tril(a) | ::tril(a) | | .flip(a, axis=0) | ::flip(a, nc::Axis::ROW) | | .flipud(a) | ::flipud(a) | | .fliplr(a) | ::fliplr(a) |
ITERATION
NumCpp follows the idioms of the C++ STL providing iterator pairs to iterate on arrays in different fashions.
| NumPy | NumCpp | | :------------------: | :------------------------------------------------: | |
value in a | (auto it = a.begin(); it < a.end(); ++it) | | | (auto& value : a) |
LOGICAL
Logical FUNCTIONS in NumCpp behave the same as NumPy.
| NumPy | NumCpp | | :-------------------------: | :--------------------------: | |
.where(a > 5, a, b) | ::where(a > 5, a, b) | | .any(a) | ::any(a) | | .all(a) | ::all(a) | | .logicaland(a, b) | ::logicaland(a, b) | | .logicalor(a, b) | ::logicalor(a, b) | | .isclose(a, b) | ::isclose(a, b) | | .allclose(a, b) | ::allclose(a, b) |
COMPARISONS
| NumPy | NumCpp | | :------------------------------: | :--------------------------------------: | |
.equal(a, b) | ::equal(a, b) | | | == b | | .notequal(a, b) | ::notequal(a, b) | | | != b | | , cols = np.nonzero(a) | [rows, cols] = nc::nonzero(a) |
MINIMUM, MAXIMUM, SORTING
| NumPy | NumCpp | | :-------------------------: | :---------------------------------: | |
.min(a) | ::min(a) | | .max(a) | ::max(a) | | .argmin(a) | ::argmin(a) | | .argmax(a) | ::argmax(a) | | .sort(a, axis=0) | ::sort(a, nc::Axis::ROW) | | .argsort(a, axis=1) | ::argsort(a, nc::Axis::COL) | | .unique(a) | ::unique(a) | | .setdiff1d(a, b) | ::setdiff1d(a, b) | | .diff(a) | ::diff(a) |
REDUCERS
Reducers accumulate values of NdArrays along specified axes. When no axis is specified, values are accumulated along all axes.
| NumPy | NumCpp | | :-------------------------------: | :---------------------------------------: | |
.sum(a) | ::sum(a) | | .sum(a, axis=0) | ::sum(a, nc::Axis::ROW) | | .prod(a) | ::prod(a) | | .prod(a, axis=0) | ::prod(a, nc::Axis::ROW) | | .mean(a) | ::mean(a) | | .mean(a, axis=0) | ::mean(a, nc::Axis::ROW) | | .countnonzero(a) | ::countnonzero(a) | | .countnonzero(a, axis=0) | ::countnonzero(a, nc::Axis::ROW) |
I/O
Print and file output methods. All NumCpp classes support a print() method and << stream operators.
| NumPy | NumCpp | | :-----------------------------------: | :---------------------------------------: | |
(a) | .print() | | | ::cout << a | | .tofile(filename, sep=โ\nโ) | .tofile(filename, '\n') | | .fromfile(filename, sep=โ\nโ) | ::fromfile<dtype>(filename, '\n') | | .dump(a, filename) | ::dump(a, filename) | | .load(filename) | ::load<dtype>(filename) |
MATHEMATICAL FUNCTIONS
NumCpp universal functions are provided for a large set number of mathematical functions.
BASIC FUNCTIONS
| NumPy | NumCpp | | :------------------------: | :-------------------------: | |
.abs(a) | ::abs(a) | | .sign(a) | ::sign(a) | | .remainder(a, b) | ::remainder(a, b) | | .clip(a, 3, 8) | ::clip(a, 3, 8) | | .interp(x, xp, fp) | ::interp(x, xp, fp) |
EXPONENTIAL FUNCTIONS
| NumPy | NumCpp | | :---------------: | :----------------: | |
.exp(a) | ::exp(a) | | .expm1(a) | ::expm1(a) | | .log(a) | ::log(a) | | .log1p(a) | ::log1p(a) |
POWER FUNCTIONS
| NumPy | NumCpp | | :------------------: | :-------------------: | |
.power(a, 4) | ::power(a, 4) | | .sqrt(a) | ::sqrt(a) | | .square(a) | ::square(a) | | .cbrt(a) | ::cbrt(a) |
TRIGONOMETRIC FUNCTIONS
| NumPy | NumCpp | | :-------------: | :--------------: | |
.sin(a) | ::sin(a) | | .cos(a) | ::cos(a) | | .tan(a) | ::tan(a) |
HYPERBOLIC FUNCTIONS
| NumPy | NumCpp | | :--------------: | :---------------: | |
.sinh(a) | ::sinh(a) | | .cosh(a) | ::cosh(a) | | .tanh(a) | ::tanh(a) |
CLASSIFICATION FUNCTIONS
| NumPy | NumCpp | | :---------------: | :----------------: | |
.isnan(a) | ::isnan(a) | | .isinf(a) | ::isinf(a) |
LINEAR ALGEBRA
| NumPy | NumCpp | | :--------------------------------: | :------------------------------------: | |
.linalg.norm(a) | ::norm(a) | | .dot(a, b) | ::dot(a, b) | | .linalg.det(a) | ::linalg::det(a) | | .linalg.inv(a) | ::linalg::inv(a) | | .linalg.lstsq(a, b) | ::linalg::lstsq(a, b) | | .linalg.matrixpower(a, 3) | ::linalg::matrixpower(a, 3) | | .linalg.multidot(a, b, c) | ::linalg::multidot({a, b, c}) | | .linalg.svd(a) | ::linalg::svd(a) |