# C++ implementation of the Python Numpy library

##### Overview # NumCpp: A Templatized Header Only C++ Implementation of the Python NumPy Library

## Testing

Compilers:
Visual Studio: 2017, 2019
GNU: 6.5, 7.5, 8.4, 9.3, 10.1
Clang: 6, 7, 8, 9, 10

Boost Versions:
1.68+

## 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 `NdArray`s, but it has limited usefulness past a simple container.

NumPy NumCpp
`a = np.array([[1, 2], [3, 4], [5, 6]])` `nc::NdArray a = { {1, 2}, {3, 4}, {5, 6} }`
`a.reshape([2, 3])` `a.reshape(2, 3)`
`a.astype(np.double)` `a.astype()`

### INITIALIZERS

Many initializer functions are provided that return `NdArray`s for common needs.

NumPy NumCpp
`np.linspace(1, 10, 5)` `nc::linspace(1, 10, 5)`
`np.arange(3, 7)` `nc::arange(3, 7)`
`np.eye(4)` `nc::eye(4)`
`np.zeros([3, 4])` `nc::zeros(3, 4)`
`nc::NdArray(3, 4) a = 0`
`np.ones([3, 4])` `nc::ones(3, 4)`
`nc::NdArray(3, 4) a = 1`
`np.nans([3, 4])` `nc::nans(3, 4)`
`nc::NdArray(3, 4) a = nc::constants::nan`
`np.empty([3, 4])` `nc::empty(3, 4)`
`nc::NdArray(3, 4) a`

NumCpp offers NumPy style slicing and broadcasting.

NumPy NumCpp
`a[2, 3]` `a(2, 3)`
`a[2:5, 5:8]` `a(nc::Slice(2, 5), nc::Slice(5, 8))`
`a({2, 5}, {5, 8})`
`a[:, 7]` `a(a.rSlice(), 7)`
`a[a > 5]` `a[a > 50]`
`a[a > 5] = 0` `a.putMask(a > 50, 666)`

### RANDOM

The random module provides simple ways to create random arrays.

NumPy NumCpp
`np.random.seed(666)` `nc::random::seed(666)`
`np.random.randn(3, 4)` `nc::random::randN(nc::Shape(3,4))`
`nc::random::randN({3, 4})`
`np.random.randint(0, 10, [3, 4])` `nc::random::randInt(nc::Shape(3,4),0,10)`
`nc::random::randInt({3, 4},0,10)`
`np.random.rand(3, 4)` `nc::random::rand(nc::Shape(3,4))`
`nc::random::rand({3, 4})`
`np.random.choice(a, 3)` `nc::random::choice(a, 3)`

### CONCATENATION

Many ways to concatenate `NdArray` are available.

NumPy NumCpp
`np.stack([a, b, c], axis=0)` `nc::stack({a, b, c}, nc::Axis::ROW)`
`np.vstack([a, b, c])` `nc::vstack({a, b, c})`
`np.hstack([a, b, c])` `nc::hstack({a, b, c})`
`np.append(a, b, axis=1)` `nc::append(a, b, nc::Axis::COL)`

### DIAGONAL, TRIANGULAR, AND FLIP

The following return new `NdArray`s.

NumPy NumCpp
`np.diagonal(a)` `nc::diagonal(a)`
`np.triu(a)` `nc::triu(a)`
`np.tril(a)` `nc::tril(a)`
`np.flip(a, axis=0)` `nc::flip(a, nc::Axis::ROW)`
`np.flipud(a)` `nc::flipud(a)`
`np.fliplr(a)` `nc::fliplr(a)`

### ITERATION

NumCpp follows the idioms of the C++ STL providing iterator pairs to iterate on arrays in different fashions.

NumPy NumCpp
`for value in a` `for(auto it = a.begin(); it < a.end(); ++it)`
`for(auto& value : a)`

### LOGICAL

Logical FUNCTIONS in NumCpp behave the same as NumPy.

NumPy NumCpp
`np.where(a > 5, a, b)` `nc::where(a > 5, a, b)`
`np.any(a)` `nc::any(a)`
`np.all(a)` `nc::all(a)`
`np.logical_and(a, b)` `nc::logical_and(a, b)`
`np.logical_or(a, b)` `nc::logical_or(a, b)`
`np.isclose(a, b)` `nc::isclose(a, b)`
`np.allclose(a, b)` `nc::allclose(a, b)`

### COMPARISONS

NumPy NumCpp
`np.equal(a, b)` `nc::equal(a, b)`
`a == b`
`np.not_equal(a, b)` `nc::not_equal(a, b)`
`a != b`
`rows, cols = np.nonzero(a)` `auto [rows, cols] = nc::nonzero(a)`

### MINIMUM, MAXIMUM, SORTING

NumPy NumCpp
`np.min(a)` `nc::min(a)`
`np.max(a)` `nc::max(a)`
`np.argmin(a)` `nc::argmin(a)`
`np.argmax(a)` `nc::argmax(a)`
`np.sort(a, axis=0)` `nc::sort(a, nc::Axis::ROW)`
`np.argsort(a, axis=1)` `nc::argsort(a, nc::Axis::COL)`
`np.unique(a)` `nc::unique(a)`
`np.setdiff1d(a, b)` `nc::setdiff1d(a, b)`
`np.diff(a)` `nc::diff(a)`

### REDUCERS

Reducers accumulate values of `NdArray`s along specified axes. When no axis is specified, values are accumulated along all axes.

NumPy NumCpp
`np.sum(a)` `nc::sum(a)`
`np.sum(a, axis=0)` `nc::sum(a, nc::Axis::ROW)`
`np.prod(a)` `nc::prod(a)`
`np.prod(a, axis=0)` `nc::prod(a, nc::Axis::ROW)`
`np.mean(a)` `nc::mean(a)`
`np.mean(a, axis=0)` `nc::mean(a, nc::Axis::ROW)`
`np.count_nonzero(a)` `nc::count_nonzero(a)`
`np.count_nonzero(a, axis=0)` `nc::count_nonzero(a, nc::Axis::ROW)`

### I/O

Print and file output methods. All NumCpp classes support a `print()` method and `<<` stream operators.

NumPy NumCpp
`print(a)` `a.print()`
`std::cout << a`
`a.tofile(filename, sep=’\n’)` `a.tofile(filename, "\n")`
`np.fromfile(filename, sep=’\n’)` `nc::fromfile(filename, "\n")`
`np.dump(a, filename)` `nc::dump(a, filename)`
`np.load(filename)` `nc::load(filename)`

### MATHEMATICAL FUNCTIONS

NumCpp universal functions are provided for a large set number of mathematical functions.

#### BASIC FUNCTIONS

NumPy NumCpp
`np.abs(a)` `nc::abs(a)`
`np.sign(a)` `nc::sign(a)`
`np.remainder(a, b)` `nc::remainder(a, b)`
`np.clip(a, 3, 8)` `nc::clip(a, 3, 8)`
`np.interp(x, xp, fp)` `nc::interp(x, xp, fp)`

#### EXPONENTIAL FUNCTIONS

NumPy NumCpp
`np.exp(a)` `nc::exp(a)`
`np.expm1(a)` `nc::expm1(a)`
`np.log(a)` `nc::log(a)`
`np.log1p(a)` `nc::log1p(a)`

#### POWER FUNCTIONS

NumPy NumCpp
`np.power(a, 4)` `nc::power(a, 4)`
`np.sqrt(a)` `nc::sqrt(a)`
`np.square(a)` `nc::square(a)`
`np.cbrt(a)` `nc::cbrt(a)`

#### TRIGONOMETRIC FUNCTIONS

NumPy NumCpp
`np.sin(a)` `nc::sin(a)`
`np.cos(a)` `nc::cos(a)`
`np.tan(a)` `nc::tan(a)`

#### HYPERBOLIC FUNCTIONS

NumPy NumCpp
`np.sinh(a)` `nc::sinh(a)`
`np.cosh(a)` `nc::cosh(a)`
`np.tanh(a)` `nc::tanh(a)`

#### CLASSIFICATION FUNCTIONS

NumPy NumCpp
`np.isnan(a)` `nc::isnan(a)`
`np.isinf(a)` `nc::isinf(a)`

#### LINEAR ALGEBRA

NumPy NumCpp
`np.linalg.norm(a)` `nc::norm(a)`
`np.dot(a, b)` `nc::dot(a, b)`
`np.linalg.det(a)` `nc::linalg::det(a)`
`np.linalg.inv(a)` `nc::linalg::inv(a)`
`np.linalg.lstsq(a, b)` `nc::linalg::lstsq(a, b)`
`np.linalg.matrix_power(a, 3)` `nc::linalg::matrix_power(a, 3)`
`Np.linalg.multi_dot(a, b, c)` `nc::linalg::multi_dot({a, b, c})`
`np.linalg.svd(a)` `nc::linalg::svd(a)`
• #### NdArrayCore.hpp Visual Studio error

In https://github.com/dpilger26/NumCpp/blob/master/include/NumCpp/NdArray/NdArrayCore.hpp Line 4690, You've commented: // NOTE: this needs to be defined outside of the class to get rid of a compiler // error in Visual Studio

But I see it's already outside of the class, yet I get a Visual Studio compilation error:

Severity Code Description Project File Line Suppression State Error(active) E0135 class template "nc::NdArray<dtype, Allocator>" has no member "nonzero" my_lib C : \NumCpp - master\include\NumCpp\NdArray\NdArrayCore.hpp 4693

What is needed to be done in order to fix this error ?

opened by TomAvrech 8
• #### Problem for random seed

``````nc::random::seed(unsigned int(time(NULL)));
cout << nc::random::randFloat<float>(0, 1) << endl;
``````

Here is my code, but the final executable program products the same number every time it starts. However, the following code can generate different numbers each time.

``````mt19937_64 generator;
generator.seed(unsigned int(time(NULL)));
boost::random::uniform_real_distribution<float> rand(0, 1);
cout << rand(generator) << endl;
``````
question
opened by linlll 8
• #### Numpy diag in Numcpp

Hey, I was wondering if you could let me know how I can get numpy.diag in Numcpp. I could not find anything regarding that method in the documentation. There is nc:diagonal, which is different with numpy.diag. Wondering if you have already implemented numpy.diag .

enhancement
opened by Houman-HM 7
• #### Compilation error: ambiguous overload for operator

I just installed Numcpp on a new machine and tried to compile a piece of code which was working on another machine. However, on the new machine, I get compilation `error: ambiguous overload for ‘operator+’ (operand types are ‘nc::NdArray<double>’ and ‘int’).` There are errors related to the ambiguity for nearly all the operators. I was wondering if you could help me fix this issue. I am using Boost 1.7, Clang 6.0, and tried different versions of gcc, including 7 , 8.3.0, 9.2. Thanks in advance.

opened by Houman-HM 7
• #### there are some bugs when i try to build Readme

hi

best lisa shi

opened by shixinlishixinli 6
• #### can stack function change the input parameter type to list or vector?

i'm try to use `vstack` to stack a series `ndarray`,but the size of series is uncertain and the `initializer_list` can't convert from `vector` or `list`. so,can i change the implement of the stack function?

opened by novioleo 6
• #### where is install and build step in ubuntu and windows

where is install and build step in ubuntu and windows

opened by fatalfeel 5
• #### Creating NdArray from cv::Mat having double values

Hi I am trying to use NumCpp in my iOS project. I have a cv::Mat object with double values in it. But I am unable to create NdArray from this source. It is only allowing me to use nc::uint8 as type.

auto ncArray = nc::NdArray(textSource.data, textSource.rows, textSource.cols);

What can I do to have NdArray with double type from cv::Mat object ? Kindly provide some guidance on it.

question
opened by nasircsms 5
• #### How to init NdArray with 2d array?

Describe the solution you'd like When I init a NdArray with a 2d array, what should I do with code? I tried code as follows:

``````float a = {{0.0, 0.0, 0.0},
{0.0, 0.0, 1.0},
{5.0, 5.0, 5.0},
{1.0, 1.0, 1.0}};
float(*b);
b = a;
nc::NdArray<float> x = nc::NdArray<float>(a, 4, 3); // not worked
nc::NdArray<float> x = nc::NdArray<float>(b, 4, 3); // not worked
``````

My purpose is write a Python extension with C++. I chose `numcpp` for finishing some tasks which are done by `numpy` in Python, so the input of functions are lists from Python in form of 2d array such as `const int (*a)`, I need to initial `nc::NdArray<dtype>` via `a`, how can I do that? Or is there some better ways to make C++ extension for Python? What I know is using `ctypes`

question
opened by AlbertoWang 4
• #### Unable to change the value of an array slice.

Describe the bug Unable to change the value of an array slice.

To Reproduce nc::NdArray *mels = new nc::NdArray{1,2,3,4,5}; std::cout << mels << std::endl; float aaa = new float{1000, 1000}; (*mels)(0, {0, 2}) = *aaa; std::cout << (*mels)(0, {0, 2}) << std::endl; std::cout << *mels << std::endl;

Expected behavior The expected output should be [[1, 2, 3, 4, 5, ]] [[1000, 1000, ]] [[1000, 1000, 3, 4, 5, ]]

But the actual output is [[1, 2, 3, 4, 5, ]] [[1, 2, ]] [[1, 2, 3, 4, 5, ]]

I'm not sure if this is a bug or I'm using NumCpp the wrong way. Thanks for your help!

opened by MuyangDu 4
• #### Fatal Error with Boost

``````In file included from /usr/local/include/NumCpp/Polynomial.hpp:31:0,
from /usr/local/include/NumCpp.hpp:52,
from /mnt/d/Deepedge/CPPinference/foxeye-pair-match/inference.cpp:14:
/usr/local/include/NumCpp/Polynomial/chebyshev_t.hpp:36:10: fatal error: boost/math/special_functions/chebyshev.hpp: No such file or directory
#include "boost/math/special_functions/chebyshev.hpp"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
``````

When try to build the file where included "NumCpp.hpp", I get the fatal error as above. Have tried reinstall boost as well, can't figure out a solution.

opened by nefario7 1
• #### nc::linalg::lstsq very slow

Describe the bug It takes forever to do SVD::decompose()

To Reproduce Run linalg.lstsq with big NdArray, my was 8905 rows and 316 cols

Expected behavior It must be much more faster

enhancement help wanted
opened by 66Ton99 10
• #### multidimensional arrays support

Hi folks!

As I can see, currently NumCpp lacks support for multidimensional arrays (for example, 3D or 4D datacubes). We oftenly use such arrays in our numpy code, and it really stops us from starting using NumCpp in our C++ part.

Can you add multidimensonal arays some day?

enhancement
opened by Felix-neko 1
• #### maximum can't deal with different array shape like in python

` np.maximum(np.eye(2), [0.5, 2]) # broadcasting

array([[ 1. , 2. ], [ 0.5, 2. ]])`

enhancement
opened by bing1zhi2 0
• #### Benchmark against eigen, xtensor, blaze, ...

Would be nice to include some benchmarks against another matrix/linalg libraries, such as Eigen, xtensor, numpy (py version), blaze, ...

enhancement
opened by breznak 0
• #### histogramdd function

I want histogramdd function just like it in numPy

It is often used together with opencv to treat multi channel component historgram.

I hope NumCpp+opencv in C++ can easily finish most of those in numpy +opencv-python.

enhancement
opened by yinjilong 0

• #### Version_2.4.0(Jan 31, 2021)

• Compile with NO_USE_BOOST definition to remove the Boost libraries as a dependency, with reduced functionality:
• gcd with a pair of values (still available using a C++17 compliant compiler)
• gcd array
• lcm with a pair of values (still available using a C++17 compliant compiler)
• lcm array
• polynomial::chebyshev_t
• polynomial::chebyshev_u
• polynomial::hermite (still available using a C++17 compliant compiler)
• polynomial::laguerre (still available using a C++17 compliant compiler)
• polynomial::legendre_p (still available using a C++17 compliant compiler)
• polynomial::legendre_q
• polynomial::spherical_harmonic
• random::beta
• random::laplace
• random::nonCentralChiSquared
• random::triangle
• random::uniformOnSphere
• special::airy_ai
• special::airy_ai_prime
• special::airy_bi
• special::airy_bi_prime
• special::bernoulli
• special::bessel_in (still available using a C++17 compliant compiler)
• special::bessel_in_prime
• special::bessel_jn (still available using a C++17 compliant compiler)
• special::bessel_jn_prime
• special::bessel_kn (still available using a C++17 compliant compiler)
• special::bessel_kn_prime
• special::bessel_yn (still available using a C++17 compliant compiler)
• special::bessel_yn_prime
• special::beta (still available using a C++17 compliant compiler)
• special::cyclic_hankel_1
• special::cyclic_hankel_2
• special::digamma
• special::erf
• special::erf_inv
• special::erfc
• special::erfc_inv
• special::gamma
• special::gamma1pm1
• special::log_gamma
• special::polygamma
• special::prime
• special::riemann_zeta (still available using a C++17 compliant compiler)
• special::spherical_bessel_jn (still available using a C++17 compliant compiler)
• special::spherical_bessel_yn (still available using a C++17 compliant compiler)
• special::spherical_hankel_1
• special::spherical_hankel_2
• special::trigamma
• Added replace option into random::choice
• Added complete and incomplete elliptical integrals of the first, second, and third kind to special namespace (requires either Boost or C++17 compliant compiler)
• Added exponential integral to special namespace (requires either Boost or C++17 compliant compiler)
Source code(tar.gz)
Source code(zip)

• #### Version_2.0.0(Jun 20, 2020)

• Dropped support of C++11, now requires a C++14 or higher compiler
• Added support for `std::complex<T>`, closing Issue #58
• Added more `NdArray` constructors for STL containers including `std::vector<std::vector<T>>`, closing Issue #59
• Added `polyfit` routine inline with Numpy `polyfit`, closing Issue #61
• Added ability to use `NdArray` as container for generic structs
• Non-linear least squares fitting using Gauss-Newton
• Root finding routines
• Numerical integration routines
• `lu_decomposition` and `pivotLU_decomposition` added to `Linalg` namespace
• New STL iterators added to `NdArray`
• `iterator`
• `const_iterator`
• `reverse_iterator`
• `const_reverse_iterator`
• `column_iterator`
• `const_column_iterator`
• `reverse_column_iterator`
• `const_reverse_column_iterator`
• Added `rodriguesRotation` and `wahbasProblem` to `Rotations` namespace
• Various efficiency and/or bug fixes
Source code(tar.gz)
Source code(zip)
###### David Pilger ###### http://torch.ch

Development Status Torch is not in active developement. The functionality provided by the C backend of Torch, which are the TH, THNN, THC, THCUNN libr

8.6k Feb 18, 2021
###### The Universal Storage Engine

The Universal Storage Engine TileDB is a powerful engine for storing and accessing dense and sparse multi-dimensional arrays, which can help you model

1k Feb 19, 2021
###### C++ Empirical Transfer Function Estimate (ETFE) Similar to MATLAB tfestimate, pwelch, and cpsd

ETFE.hpp emulates MATLAB's tfestimate, pwelch, and cpsd functions. It calculates the experimental transfer function estimate between input x and output y txy, the power spectral densities pxx and pyy, and the cross spectral density pxy. By default, it behaves exactly as MATLAB's functions, and similarly can be provided with specified windows, overlap, and FFT sizes. The output has been tested to precisely match that of MATLAB's (see matlab\test.m).

13 Feb 18, 2021
###### C++ library for solving large sparse linear systems with algebraic multigrid method

AMGCL AMGCL is a header-only C++ library for solving large sparse linear systems with algebraic multigrid (AMG) method. AMG is one of the most effecti

386 Feb 19, 2021