Skip to content

xtensor-stack/xtensor-python

Repository files navigation

xtensor-python

GHA LinuxGHA OSXGHA WindowsDocumentationJoin the Gitter Chat

Python bindings for the xtensor C++ multi-dimensional array library.

  • xtensor is a C++ library for multi-dimensional arrays enabling numpy-style broadcasting and lazy computing.

  • xtensor-python enables inplace use of numpy arrays in C++ with all the benefits from xtensor

The Python bindings for xtensor are based on the pybind11 C++ library, which enables seamless interoperability between C++ and Python.

Installation

xtensor-python is a header-only library. We provide a package for the mamba (or conda) package manager.

mamba install -c conda-forge xtensor-python

Documentation

To get started with using xtensor-python, check out the full documentation

http://xtensor-python.readthedocs.io/

Usage

xtensor-python offers two container types wrapping numpy arrays inplace to provide an xtensor semantics

  • pytensor
  • pyarray.

Both containers enable the numpy-style APIs of xtensor (see the numpy to xtensor cheat sheet).

  • On the one hand, pyarray has a dynamic number of dimensions. Just like numpy arrays, it can be reshaped with a shape of a different length (and the new shape is reflected on the python side).

  • On the other hand pytensor has a compile time number of dimensions, specified with a template parameter. Shapes of pytensor instances are stack allocated, making pytensor a significantly faster expression than pyarray.

Example 1: Use an algorithm of the C++ standard library on a numpy array inplace.

C++ code

#include<numeric>// Standard library import for std::accumulate #include<pybind11/pybind11.h>// Pybind11 import to define Python bindings #include<xtensor/core/xmath.hpp>// xtensor import for the C++ universal functions #defineFORCE_IMPORT_ARRAY #include<xtensor-python/pyarray.hpp>// Numpy bindingsdoublesum_of_sines(xt::pyarray<double>& m) { auto sines = xt::sin(m); // sines does not actually hold values.returnstd::accumulate(sines.begin(), sines.end(), 0.0); } PYBIND11_MODULE(xtensor_python_test, m) { xt::import_numpy(); m.doc() = "Test module for xtensor python bindings"; m.def("sum_of_sines", sum_of_sines, "Sum the sines of the input values"); }

Python Code

importnumpyasnpimportxtensor_python_testasxtv=np.arange(15).reshape(3, 5) s=xt.sum_of_sines(v) print(s)

Outputs

1.2853996391883833 

Working example

Get the working example here:

Example 2: Create a universal function from a C++ scalar function

C++ code

#include<pybind11/pybind11.h> #defineFORCE_IMPORT_ARRAY #include<xtensor-python/pyvectorize.hpp> #include<numeric> #include<cmath>namespacepy= pybind11; doublescalar_func(double i, double j) { returnstd::sin(i) - std::cos(j); } PYBIND11_MODULE(xtensor_python_test, m) { xt::import_numpy(); m.doc() = "Test module for xtensor python bindings"; m.def("vectorized_func", xt::pyvectorize(scalar_func), ""); }

Python Code

importnumpyasnpimportxtensor_python_testasxtx=np.arange(15).reshape(3, 5) y= [1, 2, 3, 4, 5] z=xt.vectorized_func(x, y) print(z)

Outputs

[[-0.540302, 1.257618, 1.89929 , 0.794764, -1.040465], [-1.499227, 0.136731, 1.646979, 1.643002, 0.128456], [-1.084323, -0.583843, 0.45342 , 1.073811, 0.706945]] 

Installation

We provide a package for the conda package manager.

conda install -c conda-forge xtensor-python

This will pull the dependencies to xtensor-python, that is pybind11 and xtensor.

Project cookiecutter

A template for a project making use of xtensor-python is available in the form of a cookiecutter here.

This project is meant to help library authors get started with the xtensor python bindings.

It produces a project following the best practices for the packaging and distribution of Python extensions based on xtensor-python, including a setup.py file and a conda recipe.

Building and Running the Tests

Testing xtensor-python requires pytest

py.test .

To pick up changes in xtensor-python while rebuilding, delete the build/ directory.

Building the HTML Documentation

xtensor-python's documentation is built with three tools

While doxygen must be installed separately, you can install breathe by typing

pip install breathe

Breathe can also be installed with conda

conda install -c conda-forge breathe

Finally, build the documentation with

make html

from the docs subdirectory.

Dependencies on xtensor and pybind11

xtensor-python depends on the xtensor and pybind11 libraries

xtensor-pythonxtensorpybind11
master^0.26.0>=2.6.1,<3
0.28.0^0.26.0>=2.6.1,<3
0.27.0^0.25.0>=2.6.1,<3
0.26.1^0.24.0~2.4.3
0.26.0^0.24.0~2.4.3
0.25.3^0.23.0~2.4.3
0.25.2^0.23.0~2.4.3
0.25.1^0.23.0~2.4.3
0.25.0^0.23.0~2.4.3
0.24.1^0.21.2~2.4.3
0.24.0^0.21.1~2.4.3

These dependencies are automatically resolved when using the conda package manager.

License

We use a shared copyright model that enables all contributors to maintain the copyright on their contributions.

This software is licensed under the BSD-3-Clause license. See the LICENSE file for details.

close