xtensor

Multi-dimensional arrays with broadcasting and lazy computing.

Introduction

xtensor is a C++ library meant for numerical analysis with multi-dimensional array expressions.

xtensor provides

  • an extensible expression system enabling lazy broadcasting.
  • an API following the idioms of the C++ standard library.
  • tools to manipulate array expressions and build upon xtensor.

The implementation of the containers of xtensor is inspired by NumPy, the Python array programming library. Adaptors for existing data structures to be plugged into our expression system can easily be written. In fact, xtensor can be used to process numpy data structures inplace using Python's buffer protocol.

xtensor requires a modern C++ compiler supporting C++14. The following C+ compilers are supported:

  • On Windows platforms, Visual C++ 2015 Update 2, or more recent
  • On Unix platforms, gcc 4.9 or a recent version of Clang

Usage

To run the selected code cell, hit
Shift + Enter

Initialize a 2-D array and compute the sum of one of its rows and a 1-D array

In [ ]:
#include <iostream>

#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"
#include "xtensor/xview.hpp"
In [ ]:
xt::xarray<double> arr1
  {{1.0, 2.0, 3.0},
   {2.0, 5.0, 7.0},
   {2.0, 5.0, 7.0}};

xt::xarray<double> arr2
  {5.0, 6.0, 7.0};

xt::view(arr1, 1) + arr2
In [ ]:
arr1

Initialize a 1-D array and reshape it inplace

In [ ]:
#include <iostream>
#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"
In [ ]:
xt::xarray<int> arr
  {1, 2, 3, 4, 5, 6, 7, 8, 9};

arr.reshape({3, 3});

arr

Broadcasting the xt::pow universal functions

In [ ]:
#include <iostream>
#include "xtensor/xarray.hpp"
#include "xtensor/xmath.hpp"
#include "xtensor/xio.hpp"
In [ ]:
xt::xarray<double> arr3
  {1.0, 2.0, 3.0};

xt::xarray<unsigned int> arr4
  {4, 5, 6, 7};

arr4.reshape({4, 1});

xt::pow(arr3, arr4)

Random arrays with the random module

In [ ]:
#include <iostream>
#include "xtensor/xrandom.hpp"
In [ ]:
xt::xarray<double> arr5 = xt::random::randn<double>({4, 3});
arr5
In [ ]:
xt::random::randn<double>({5, 3, 8, 10}) > 0.2

Using linspace, arange, ones, zeros

In [ ]:
#include "xtensor/xbuilder.hpp"
In [ ]:
xt::xarray<double> ar = xt::linspace<double>(0.0, 10.0, 12);
ar.reshape({4, 3});
ar
In [ ]:
xt::xarray<double> fones = xt::ones<float>({2, 2});
fones
In [ ]:
xt::arange<int>(1569325055)

Using xt::broadcast

In [ ]:
#include <vector>
#include "xtensor/xbroadcast.hpp"
In [ ]:
xt::broadcast(xt::linspace<double>(0.0, 10.0, 4),
              std::vector<std::size_t>({3, 4}))

Using standard algorithms with xexpressions

In [ ]:
#include <algorithm>
In [ ]:
xt::xarray<double> frand = xt::random::randn<double>({2, 2});

// begin() and end() provide and iterator pair iterating over the xexpression in a row-major fashion
std::cout << std::accumulate(frand.begin(), frand.end(), 0.0);

frand

Iterating over a prescribed broadcasted shape

In [ ]:
// begin(shape) and end(shape) provide and iterator pair iterating
// over the xexpression broadcasted to the prescrived shape in a row-major fashion
std::vector<std::size_t> shape = {3, 2, 2};
std::cout << std::accumulate(frand.begin(shape), frand.end(shape), 0.0);

xtensor-blas

Blas bindings for xtensor.

xtensor-blas is an extension to the xtensor library, offering bindings to BLAS and LAPACK libraries through cxxblas and cxxlapack from the FLENS project.

xtensor-blas currently provides non-broadcasting dot, norm (1- and 2-norm for vectors), inverse, solve, eig, cross, det, slogdet, matrix_rank, inv, cholesky, qr, svd in the xt::linalg namespace (check the corresponding xlinalg.hpp header for the function signatures). The functions, and signatures, are trying to be 1-to-1 equivalent to NumPy. Low-level functions to interface with BLAS or LAPACK with xtensor containers are also offered in the blas and lapack namespace.

xtensor and xtensor-blas require a modern C++ compiler supporting C++14. The following C++ compilers are supported:

  • On Windows platforms, Visual C++ 2015 Update 2, or more recent
  • On Unix platforms, gcc 4.9 or a recent version of Clang
In [ ]:
#include "xtensor-blas/xlinalg.hpp"
In [ ]:
xt::xtensor<double, 2> m = {{1.5, 0.5}, {0.7, 1.0}};
In [ ]:
std::cout << "Matrix rank: " << std::endl << xt::linalg::matrix_rank(m);
In [ ]:
std::cout << "Matrix inverse: " << std::endl << xt::linalg::inv(m);
In [ ]:
std::cout << "Eigen values: " << std::endl << xt::linalg::eigvals(m);
In [ ]:
xt::xarray<double> arg1 = xt::arange<double>(9);
xt::xarray<double> arg2 = xt::arange<double>(18);
arg1.reshape({3, 3});
arg2.reshape({2, 3, 3});
std::cout << xt::linalg::dot(arg1, arg2) << std::endl;