numpy-in-cpp

imitate NumPy in C++

Stars
1

NumPy in C++

This is an attempt to imitate NumPy in C++.

This project provides not only an API for Python/NumPy-like array programming but also the py++ tool, which enables you to see execution outcomes in a pretty Python-interpreter-like fashion, as shown below.

For example, let us suppose you have this code.

// test/example.cpp

#include <numpy/numpy.hpp>
using namespace python;
namespace np = numpy;

int main() {
  
  // Array Creation
  auto x = np::array(range(12)).reshape({3, 4});
  auto y = np::array(range(12)).reshape(3, 4); // equivalent to the above
  print(x); // some of Python's built-in functions, including `print()`, are supported
  print(y);

  // Array's Attribute Accessors
  print(x.shape());
  print(x.T());
  print(np::may_share_memory(x, x.T())); // transposition is just a new "view"
  
  // Indexing & Slicing
  print(x[-1]);
  print(x(-1)); // equivalent to the above
  print(x("1:3","2::")); // slice is also available
  print(x(1,"::-1")); // you can't do `x[1,"::-1"]` due to the C++ language specification
  // indexing is done without copying
  print(np::may_share_memory(x, x[-1])); // -> True
  print(np::may_share_memory(x, x("1:3","2::"))); // -> True
  print(np::may_share_memory(x, x(1,"::-1"))); // -> True

  // Broadcasting & Ufuncs
  auto a = np::array(range(4)).reshape(4, 1);
  auto b = np::array(range(3)).reshape(1, 3);
  print(a);
  print(b);

  // `a` and `b` have different shapes, but arithmetic operations between them are possible.
  print(a + b); // `a` & `b` is broadcasted to the common shape (4, 3) in the internal of `np::add()`
  print(np::add(a, b)); // equivalent to the above

  auto out = np::empty<np::int32>({4, 3}); // `out` parameter is also available, just as the original NumPy!
  np::add(a, b, out);
  print(out);

  // Handling Overlapping Memories
  x = np::array(range(9)).reshape(3, 3);
  print(x);
  print(x.T());
  print(x.T() + x); // just fine!

  // Copy & Move Assignment
  print(np::may_share_memory(a, b)); // -> False
  b = a; // this calls the copy assignment operator, but it does not copy the contents of the array.
  // Just as in Python, `b` now refers to the same location of memory as `a`.
  print(np::may_share_memory(a, b)); // -> True
  a = a + b; // this calls the move assignment operator
  print(a);
  
}

All you have to do is just type the following command.

$ ./py++ example

py++ will auto-generate some codes, compile it, and then show you something like this:

Of course, you can compile that code with a C++ compiler as usual:

g++ -std=c++17 -O3 -Wall -I .  -o test/example test/example.cpp

or

make test/example

Note that C++17 or later is required.