The Wayback Machine - https://web.archive.org/web/20190504144924/https://github.com/QuantStack/xtensor-python
Skip to content
Python bindings for xtensor
Branch: master
Clone or download
Latest commit 368fd65 Apr 17, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
benchmark Update deprecated macro Jan 24, 2018
cmake cmake build Feb 20, 2017
docs multiple files extension documentation improved Oct 2, 2018
include/xtensor-python Release 0.23.0 Apr 17, 2019
test Upgraded to xtensor 0.20.0 Mar 28, 2019
test_python Upgraded to xtensor 0.20.0 Mar 28, 2019
.appveyor.yml Update xtensor to 0.20.4 Apr 15, 2019
.gitignore
.travis.yml Update xtensor to 0.20.4 Apr 15, 2019
CMakeLists.txt Fixup build interfaces Jan 28, 2019
LICENSE First commit Nov 5, 2016
README.md Release 0.23.0 Apr 17, 2019
readthedocs.yml Minimal breathe documentation Nov 26, 2016
xtensor-pythonConfig.cmake.in Added include for the generated xtensor-pythonTargets.cmake. Aug 8, 2018

README.md

xtensor-python

Travis Appveyor Documentation Join 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 seemless interoperability between C++ and Python.

Installation

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

conda 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/xmath.hpp"              // xtensor import for the C++ universal functions
#define FORCE_IMPORT_ARRAY
#include "xtensor-python/pyarray.hpp"     // Numpy bindings

double sum_of_sines(xt::pyarray<double>& m)
{
    auto sines = xt::sin(m);  // sines does not actually hold values.
    return std::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

import numpy as np
import xtensor_python_test as xt

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

Outputs

1.2853996391883833

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

C++ code

#include "pybind11/pybind11.h"
#define FORCE_IMPORT_ARRAY
#include "xtensor-python/pyvectorize.hpp"
#include <numeric>
#include <cmath>

namespace py = pybind11;

double scalar_func(double i, double j)
{
    return std::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

import numpy as np
import xtensor_python_test as xt

x = np.arange(15).reshape(3, 5)
y = [1, 2, 3, 4, 5]
z = xt.vectorized_func(x, y)
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-python xtensor pybind11
master ^0.20.4 ~2.2.1
0.23.0 ^0.20.4 ~2.2.1
0.22.x ^0.19.0 ~2.2.1
0.21.x ^0.18.0 ~2.2.1
0.20.x ^0.17.0 ~2.2.1
0.19.x ^0.16.0 ~2.2.1
0.18.x ^0.16.0 ~2.1.0 or ~2.2.1
0.17.x ^0.15.1 ~2.1.0 or ~2.2.1
0.16.x ^0.14.0 ~2.1.0 or ~2.2.1
0.15.x ^0.13.1 ~2.1.0 or ~2.2.1

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.

You can’t perform that action at this time.