Python interface

This library includes provides an interface to pybind11 such that an interface to NumPy arrays is automatically provided when including a function with any of the cppmat classes:

cppmat class Rank of NumPy-array
cppmat::array n
cppmat::matrix 2
cppmat::vector 1
cppmat::tiny::array 2
cppmat::tiny::matrix 2
cppmat::tiny::vector 1
cppmat::cartesian::tensor4 4
cppmat::cartesian::tensor2 2
cppmat::cartesian::tensor2s 2
cppmat::cartesian::tensor2d 2
cppmat::cartesian::vector 1
cppmat::tiny::cartesian::tensor4 4
cppmat::tiny::cartesian::tensor2 2
cppmat::tiny::cartesian::tensor2s 2
cppmat::tiny::cartesian::tensor2d 2
cppmat::tiny::cartesian::vector 1

Warning

On the Python side all the matrices (cppmat::matrix, cppmat::symmetric::matrix, and cppmat::diagonal::matrix) and 2nd-order tensors (cppmat::cartesian::tensor2, cppmat::cartesian::tensor2s, and cppmat::cartesian::tensor2d) are all square matrices (rank 2 NumPy arrays). This means that when a function that has cppmat::symmetric::matrix or cppmat::cartesian::tensor2s as argument, the upper-diagonal part is read; while when it has an argument cppmat::diagonal::matrix or cppmat::cartesian::tensor2d only the diagonal is considered.

This requires extra attention as information might be lost. To optimize for speed and flexibility no checks are performed in the release libraries derived from cppmat!

You can ask cppmat to check for this, by omitting the -DNDEBUG compiler flag (this enables several assertions, so it may cost you some efficiency).

(The same holds for the classes under cppmat::tiny::.)

To use this feature one has to:

#include <cppmat/pybind11.h>

Building

[tensorlib.zip]

Building is demonstrated based on the ‘tensorlib’ example.

CMake

[CMakeLists.txt]

cmake_minimum_required(VERSION 2.8.12)
project(tensorlib)

# set optimization level
# - aggressive optimization
#   compiler: ... -O3
set(CMAKE_BUILD_TYPE Release)
# - switch off assertions (more risky but faster)
#   compiler: ... -DNDEBUG
add_definitions(-DNDEBUG)

# set C++ standard
# - compiler: ... -std=c++14
set(CMAKE_CXX_STANDARD 14)

# find cppmat
# - compiler: ... -I${CPPMAT_INCLUDE_DIRS}
find_package(PkgConfig)
pkg_check_modules(CPPMAT REQUIRED cppmat)
include_directories(${CPPMAT_INCLUDE_DIRS})

# find pybind11
find_package(pybind11 REQUIRED)
pybind11_add_module(tensorlib tensorlib.cpp)

Build using

cd /path/to/tempdir
cmake /path/to/tensorlib
make

For this to work, pybind11 must be ‘installed’ on the system.

Tip

Alternatively you can include pybind11 as a sub-folder (for example using git submodule add https://github.com/pybind/pybind11.git). In that case, replace find_package(pybind11 REQUIRED) by add_subdirectory(pybind11) in CMakeLists.txt.

Tip

To link to external libraries, include at the end of your CMakeLists.txt

target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_LIBS})

setup.py

[setup.py]

from setuptools import setup, Extension

import sys
import setuptools
import pybind11
import cppmat

__version__ = '0.0.1'

ext_modules = [
  Extension(
    'tensorlib',
    ['tensorlib.cpp'],
    include_dirs=[
      pybind11.get_include(False),
      pybind11.get_include(True ),
      cppmat  .get_include(False),
      cppmat  .get_include(True )
    ],
    language='c++'
  ),
]

setup(
  name               = 'tensorlib',
  description        = 'Tensorlib',
  long_description   = 'This is an example module, it no real use!',
  keywords           = 'Example, C++, C++11, Python bindings, pybind11',
  version            = __version__,
  license            = 'MIT',
  author             = 'Tom de Geus',
  author_email       = 'tom@geus.me',
  url                = 'https://github.com/tdegeus/cppmat/docs/examples/tensorlib',
  ext_modules        = ext_modules,
  extra_compile_args = ["-DNDEBUG"], # switch off assertions
  install_requires   = ['pybind11>=2.1.0','cppmat>=0.2.1'],
  cmdclass           = {'build_ext': cppmat.BuildExt},
  zip_safe           = False,
)

As shown in this example building using the setup.py can be simplified using some routines in the cppmat python module. These routines have been taken from pybind, most notably from Sylvain Corlay and Dean Moldovan. They are merely attached to this module to simplify your life.

Build using

python3 setup.py build
python3 setup.py install

Tip

Replace the executable with your favorite Python version, e.g. with python.

CMake & setup.py

CMake can be called from the setup.py to take advantage of both. In that case the setup.py would be simply

import setuptools, cppmat

setuptools.setup(
  name             = 'tensorlib',
  version          = '0.0.1',
  author           = 'Tom de Geus',
  author_email     = 'email@address.com',
  description      = 'Description',
  long_description = '',
  ext_modules      = [cppmat.CMakeExtension('tensorlib')],
  cmdclass         = dict(build_ext=cppmat.CMakeBuild),
  zip_safe         = False,
)