.. Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht

   Distributed under the terms of the BSD 3-Clause License.

   The full license is in the file LICENSE, distributed with this software.

.. raw:: html

   <style>
   h2 {
        display: none;
   }
   </style>

Related projects
================

xtensor-python
--------------

.. image:: xtensor-python.svg
   :alt: xtensor-python

The xtensor-python_ project provides the implementation of container types compatible with ``xtensor``'s expression
system, ``pyarray`` and ``pytensor`` which effectively wrap numpy arrays, allowing operating on numpy arrays inplace.

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

**C++ code**

.. 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                // numpy C api loading
    #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 any value
        return std::accumulate(sines.cbegin(), sines.cend(), 0.0);
    }

    PYBIND11_PLUGIN(xtensor_python_test)
    {
        xt::import_numpy();
        pybind11::module m("xtensor_python_test", "Test module for xtensor python bindings");

        m.def("sum_of_sines", sum_of_sines,
            "Sum the sines of the input values");

        return m.ptr();
    }

**Python code**

.. code::

    Python Code

    import numpy as np
    import xtensor_python_test as xt

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

**Outputs**

.. code::

    1.2853996391883833


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

**C++ code**

.. 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_PLUGIN(xtensor_python_test)
    {
        xt::import_numpy();
        py::module m("xtensor_python_test", "Test module for xtensor python bindings");

        m.def("vectorized_func", xt::pyvectorize(scalar_func), "");

        return m.ptr();
    }

**Python code**

.. 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**

.. code::

    [[-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]]

xtensor-python-cookiecutter
---------------------------

.. image:: xtensor-cookiecutter.png
   :alt: xtensor-python-cookiecutter

The xtensor-python-cookiecutter_ project helps extension authors create Python extension modules making use of `xtensor`.

It takes care of the initial work of generating a project skeleton with

- A complete setup.py compiling the extension module

A few examples included in the resulting project including

- A universal function defined from C++
- A function making use of an algorithm from the STL on a numpy array
- Unit tests
- The generation of the HTML documentation with sphinx

xtensor-julia
-------------

.. image:: xtensor-julia.svg
   :alt: xtensor-julia

The xtensor-julia_ project provides the implementation of container types compatible with ``xtensor``'s expression system, ``jlarray`` and ``jltensor`` which effectively wrap Julia arrays, allowing operating on Julia arrays inplace.

Example 1: Use an algorithm of the C++ library with a Julia array
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**C++ code**

.. code::

    #include <numeric>                        // Standard library import for std::accumulate
    #include <cxx_wrap.hpp>                   // CxxWrap import to define Julia bindings
    #include "xtensor-julia/jltensor.hpp"     // Import the jltensor container definition
    #include "xtensor/xmath.hpp"              // xtensor import for the C++ universal functions

    double sum_of_sines(xt::jltensor<double, 2> m)
    {
        auto sines = xt::sin(m);  // sines does not actually hold values.
        return std::accumulate(sines.cbegin(), sines.cend(), 0.0);
    }

    JULIA_CPP_MODULE_BEGIN(registry)
        cxx_wrap::Module mod = registry.create_module("xtensor_julia_test");
        mod.method("sum_of_sines", sum_of_sines);
    JULIA_CPP_MODULE_END

**Julia code**

.. code::

    using xtensor_julia_test

    arr = [[1.0 2.0]
           [3.0 4.0]]

    s = sum_of_sines(arr)
    s

**Outputs**

.. code::

   1.2853996391883833

Example 2: Create a numpy-style universal function from a C++ scalar function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**C++ code**

.. code::

    #include <cxx_wrap.hpp>
    #include "xtensor-julia/jlvectorize.hpp"

    double scalar_func(double i, double j)
    {
        return std::sin(i) - std::cos(j);
    }

    JULIA_CPP_MODULE_BEGIN(registry)
        cxx_wrap::Module mod = registry.create_module("xtensor_julia_test");
        mod.method("vectorized_func", xt::jlvectorize(scalar_func));
    JULIA_CPP_MODULE_END

**Julia code**

.. code::

    using xtensor_julia_test

    x = [[ 0.0  1.0  2.0  3.0  4.0]
         [ 5.0  6.0  7.0  8.0  9.0]
         [10.0 11.0 12.0 13.0 14.0]]
    y = [1.0, 2.0, 3.0, 4.0, 5.0]
    z = xt.vectorized_func(x, y)
    z

**Outputs**

.. code::

    [[-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]]

xtensor-julia-cookiecutter
--------------------------

.. image:: xtensor-cookiecutter.png
   :alt: xtensor-julia-cookiecutter

The xtensor-julia-cookiecutter_ project helps extension authors create Julia extension modules making use of `xtensor`.

It takes care of the initial work of generating a project skeleton with

- A complete read-to-use Julia package 

A few examples included in the resulting project including

- A numpy-style universal function defined from C++
- A function making use of an algorithm from the STL on a numpy array
- Unit tests
- The generation of the HTML documentation with sphinx

xtensor-r
---------

.. image:: xtensor-r.svg
   :alt: xtensor-r

The xtensor-r_ project provides the implementation of container types compatible with ``xtensor``'s expression system, ``rarray`` and ``rtensor`` which effectively wrap R arrays, allowing operating on R arrays inplace.

xtensor-blas
------------

.. image:: xtensor-blas.svg
   :alt: xtensor-blas

The xtensor-blas_ project is an extension to the xtensor library, offering bindings to BLAS and LAPACK libraries through cxxblas and cxxlapack from the FLENS project. ``xtensor-blas`` powers the ``xt::linalg`` functionalities, which are the counterpart to numpy's ``linalg`` module.

.. _xtensor-python: https://github.com/QuantStack/xtensor-python
.. _xtensor-python-cookiecutter: https://github.com/QuantStack/xtensor-python-cookiecutter
.. _xtensor-julia: https://github.com/QuantStack/xtensor-julia
.. _xtensor-julia-cookiecutter: https://github.com/QuantStack/xtensor-julia-cookiecutter
.. _xtensor-r: https://github.com/QuantStack/xtensor-r
.. _xtensor-blas: https://github.com/QuantStack/xtensor-blas
