Boost.Numeric.Bindings.Traits

###  | # Boost.Numeric.Bindings.Traits

Back to Bindings Library Synopsis

## Contents

1. Generic Storage Layout Information

1. Rationale
2. Using Traits Classes
3. Vector Traits

1. Description
2. Definition
3. Associated Types
4. Expression Semantics
5. Implementation

4. Matrix Traits

1. Description
2. Definition
3. Associated Types
4. Expression Semantics
5. Implementation

5. Sparse Matrix Traits

1. Description
2. Definition
3. Associated Types
4. Static Constants
5. Expression Semantics
6. Implementation

6. Free functions

2. Calling Conventions
3. Type Mapping

## 1. Generic Storage Layout Information

### 1.1 Rationale

The Traits Library provides the mappings from the interfaces of various vector and matrix C++ libraries to the storage layout format required by the original API's of different external numeric libraries.

These mappings are implemented by means of traits classes and their specialisations. One advantage of this approach is that the traits idiom is non-intrusive: no changes or additions to vector and matrix classes are needed. Another advantage is the extensibility since traits classes can be specialised for many different vector or matrix libraries. Furthermore, the traits idiom is a compile-time mechanism and thus adds no run-time overhead.

### 1.2 Using Traits Classes

To use particular vector or matrix class in bindings to some external library, proper traits specialisation must be included. Specialisations for following vector and matrix classes are currently available:

- vector classes:
  - uBLAS:
    - `ublas::vector<>`, `ublas::c_vector<>` and vector proxies -- in `ublas_vector.hpp`
    - `ublas::matrix_row<>` and `ublas::matrix_column<>` -- in `ublas_matrix.hpp`
  - `std::valarray<>` -- in `std_valarray.hpp`
  - `std::vector<>` -- in `std_vector.hpp`
  - `boost::array<>` -- in `boost_array.hpp`
  - C array -- in `c_array.hpp`
  - TNT 1D arrays -- in `tnt.hpp`
- matrix classes:
  - uBLAS:
    - `ublas::matrix<>`, `ublas::c_matrix<>` and matrix proxies -- in `ublas_matrix.hpp`
    - `ublas::symmetric_matrix<>` and `ublas::symmetric_adaptor<>` -- in `ublas_symmetric.hpp`
    - `ublas::hermitian_matrix<>` and `ublas::hermitian_adaptor<>` -- in `ublas_hermitian.hpp`
    - `ublas::vector<>` and `ublas::c_vector<>` (matrices with one column and one row) -- in `ublas_vector2.hpp`
  - TNT 2D arrays -- in `tnt.hpp`
- sparse matrix classes:
  - uBLAS:
    - `ublas::compressed_matrix<>` and `ublas::coordinate_matrix<>` -- in `ublas_sparse.hpp`

All mentioned files are in the directory `boost/numeric/bindings/traits`.

If you are using any of these vector or matrix classes, this is in fact all you need to know about traits classes and their specialisations.

Example. Simple initialisation and dot product of vectors `v` (represented by `std::vector<>`) and `w` (represented by `plain' C array) using ATLAS bindings:

      #include <iostream>
      #include <boost/numeric/bindings/traits/std_vector.hpp>
      #include <boost/numeric/bindings/traits/c_array.hpp>
      #include <boost/numeric/bindings/atlas/cblas1.hpp>

      namespace atlas = boost::numeric::bindings::atlas;

      int main() {
        std::vector v(10);
        double w[10];
        atlas::set (0.1, v);  // v = [ 0.1  0.1  ...  0.1 ]^T
        atlas::set (0.2, w);  // w = [ 0.2  0.2  ...  0.2 ]^T
        std::cout << atlas::dot (v, w) << std::endl;
      }

### 1.3 Vector Traits

#### 1.3.1.Description

Generic bindings functions which manipulate vectors are written in terms of types (subsection 1.3.3) and static functions (subsection 1.3.4) defined in the `vector_traits<>` class. This class was designed taking into account requirements of the interfaces of BLAS levels 1 and 2 functions.

#### 1.3.2.Definition

Generic class `vector_traits<>` is defined in the header `boost/numeric/bindings/traits/vector_traits.hpp`.

Specialisations are defined in:

Header | Vector class(es)
--- | ---
`boost_array.hpp` | `boost::array<>`
`c_array.hpp` | C array: `T[N]`
`std_valarray.hpp` | `std::valarray<>`
`std_vector.hpp` | `std::vector<>`
`tnt.hpp` | `TNT::Array1D<>`, `TNT::Fortran_Array1D<>`
`ublas_matrix.hpp` | `ublas::matrix_row<>`, `ublas::matrix_column<>`
`ublas_vector.hpp` | `ublas::vector<>`, `ublas::c_vector<>`, `ublas::vector_range<>`, `ublas::vector_slice<>`

All headers are in `boost/numeric/bindings/traits/`.

#### 1.3.3 Associated Types

Value type | `value_type` | The type of the objects contained in the vector
Pointer type | `pointer` | Data type used to point to any entry of the vector in memory

#### 1.3.4 Expression Semantics

Name | Expression | Semantics
--- | --- | ---
Beginning of storage | `storage(v)` | Returns a pointer to the beginning of the storage of vector `v`
Size of vector | `size(v)` | Returns the size of vector `v`
Stride | `stride(v)` | Returns the distance between pointers pointing to consecutive entries in `v`

#### 1.3.5 Implementation

Class `vector_traits<>` is implemented in three steps (see `vector_traits.hpp`):

1. definition of class `default_vector_traits<>`,
2. definition of class `vector_detail_traits<>`,
3. definition of class `vector_traits<>`.

1. Class `default_vector_traits<>` defines default functionality:

      template <typename V, typename T = typename V::value_type>
      struct default_vector_traits {
        typedef T value_type;
        typedef typename detail::generate_const<V,T>::type* pointer;
        static pointer storage (V& v) { return v.begin(); }
        static std::ptrdiff_t size (V& v) { return v.size(); }
        static std::ptrdiff_t stride (V& v) { return 1; }
      };

Metafunction `generate_const<>` `copies' `const`, if present, from `V` to `T`, that is, if vector type `V` is non-`const`, `pointer` will be `T*`, and if `V` is `const`, `pointer` will be `T const*`.

As can be seen from the implementation of function `storage()`, the assumption is that `V` provides function `begin()` and that `V::iterator` (or `V::const_iterator`, if `V` is `const`) is pointer, as e.g. uBLAS storage classes (`unbounded_array<>`, `bounded_array<>` and `array_adaptor<>`) and `boost::array<>`. Also, it is assumed that `V` provides function `size()` and that stride is 1. If this is not the case with your vector class, you must write specialisation.

2. Class `vector_detail_traits<>` was introduced having the writing of specialisations in mind. It has two template parameters: `VIdentifier` and `VType`. `VIdentifier` is used to identify the (written) implementation and `VType` is the actual type for which the specialisation is needed in the code which uses traits -- `VIdentifier` is always non-`const` (e.g. `ublas::vector<>`), while `VType` can be `const` (e.g. `ublas::vector<>` or `ublas::vector<> const`).

Generic/default implementation is:

      template <typename VIdentifier, typename VType>
      struct vector_detail_traits : default_vector_traits<VType> {};

3. Class `vector_traits<>` is derived from `vector_detail_traits<>`. It deduces `VIdentifier` from its template parameter `VType` by removing `const`, if present:

      template <typename VType>
      struct vector_traits : vector_detail_traits<typename boost::remove_const<VType>::type, VType> {};

Specialisations. Class `vector_detail_traits<>` can be specialised if default implementation is not appropriate for particular vector type. All specialisations must provide types defined in subsection 1.3.3 and static member functions defined in subsection 1.3.4.

Example. Specialisation for built-in C array (see `c_array.hpp`):

      template <typename T, std::size_t N, typename VType>
      struct vector_detail_traits<T[N],VType> {
        typedef T value_type;
        typedef typename detail::generate_const<VType,T>::type* pointer;
        static pointer storage (VType& a) { return a; }
        static std::ptrdiff_t size (VType&) { return N; }
        static std::ptrdiff_t stride (VType&) { return 1; }
      };

Example. Specialisation for `std::vector<>` (see `std_vector.hpp`):

      template <typename T, typename Alloc, typename VType>
      struct vector_traits<std::vector<T, Alloc>, VType> : default_vector_traits<V,T> {
        typedef typename default_vector_traits<VType,T>::pointer pointer;
        static pointer storage (VType& v) { return &v.front(); }
      };

Type `value_type` and functions `size()` and `stride()` are inherited from `default_vector_traits<>`.

### 1.4 Matrix Traits

#### 1.4.1 Description

Generic bindings functions which manipulate matrices are written in terms of types (subsection 1.4.3) and static functions (subsection 1.4.4) defined in the `matrix_traits<>` class. This class was designed taking into account requirements of the interfaces of BLAS (levels 2 and 3) and LAPACK functions.

#### 1.4.2 Definition

Generic class `matrix_traits<>` is defined in header `boost/numeric/bindings/traits/matrix_traits.hpp`.

Specialisations are defined in:

Header | Matrix classes
--- | ---
`tnt.hpp` | `TNT::Array2D<>`, `TNT::Fortran_Array2D<>`
`ublas_hermitian.hpp` | `ublas::hermitian_matrix<>`, `ublas::hermitian_adaptor<>`
`ublas_matrix.hpp` | `ublas::matrix<>`, `ublas::c_matrix<>`, `ublas::matrix_range<>`, `ublas::matrix_slice<>`
`ublas_symmetric.hpp` | `ublas::symmetric_matrix<>`, `ublas::symmetric_adaptor<>`
`ublas_vector2.hpp` | `ublas::vector<>` (as n-by-1 matrix), `ublas::c_vector<>` (as 1-by-n matrix)

All headers are in `boost/numeric/bindings/traits/`.

#### 1.4.3 Associated Types

Value type | `value_type` | The type of the objects contained in the matrix
Pointer type | `pointer` | Data type used to point to any entry of the matrix in memory
Matrix structure | `matrix_structure` | Describes the pattern of nonzero and zero elements and the storage layout [1]
Ordering type | `ordering_type` | Row or column major [2]
Upper/lower type | `uplo_type` | For triangular, symmetric and hermitian matrices: indicates whether upper or lower triangular part is referenced or stored [3]

[1] `matrix_structure` is a tag which can be:

- `general_t`
- `symmetric_t`
- `symmetric_packed_t`
- `hermitian_t`
- `hermitian_packed_t`
- `unknown_structure_t`

[2] `ordering_type` can be:

- `row_major_t`
- `column_major_t`

[3] Upper/lower tag must be defined only for triangular (full and packed), symmetric (full and packed) and hermitian (full and packed) matrices. For packed types it indicates whether upper or lower triangular part is stored, and for full matrices it denotes part that is referenced. `uplo_type` can be:

- `upper_t`
- `lower_t`

#### 1.4.4 Expression Semantics

Name | Expression | Semantics
--- | --- | ---
Beginning of storage | `storage(m)` | Returns a pointer to the beginning of the storage of matrix `m`
Number of rows | `num_rows(m)` | Returns the number of rows of matrix `m`
Number of columns | `num_columns(m)` | Returns the number of columns matrix `m`
Leading dimension | `leading_dimension(m)` | Returns the distance between pointers to the first element in consecutive rows/columns in case of row-major/column-major matrices [1]

[1] Not needed for all matrix types (e.g. not needed for triangular, symmetric and hermitian packed matrices).

#### 1.4.5 Implementation

Implementation of `matrix_traits<>` is similar to the `vector_traits<>`'s implementation (subsection 1.3.5); only, first step is omitted because there is no reasonable default -- different matrix libraries provide different interfaces (for example, functions that return number of rows and columns are named `num_rows()`, `num_columns()` in uBLAS, `dim1()`, `dim2()` in TNT, and `nrows()`, `ncols()` in MTL). Definitions in `matrix_traits.hpp` are:

      template <typename MIdentifier, typename MType>
      struct matrix_detail_traits {};

      template <typename MType>
      struct matrix_traits : matrix_detail_traits<typename boost::remove_const::type, MType> {};

Specialisations of `matrix_detail_traits<>` must provide types defined in subsection 1.4.3 and static member functions defined in subsection 1.4.4.

Example. Specialisation of `matrix_detail_traits<>` for `ublas::matrix<>` (see `ublas_matrix.hpp`):

      template <typename T, typename F, typename ArrT, typename MType>
      struct matrix_detail_traits<boost::numeric::ublas::matrix<T,F,ArrT>, Mtype> {

        typedef general_t matrix_structure;
        typedef typename detail::ublas_ordering<typename F::orientation_category>::type ordering_type;

        typedef T value_type;
        typedef typename detail::generate_const<MType,T>::type* pointer;

        static pointer storage (MType& m) {
          typedef typename detail::generate_const<MType,ArrT>::type array_type;
          return vector_traits<array_type>::storage (m.data());
        }
        static std::ptrdiff_t num_rows (MType& m) { return m.size1(); }
        static std::ptrdiff_t num_columns (MType& m) { return m.size2(); }
        static std::ptrdiff_t leading_dimension (MType& m) { return F::size2 (m.size1(), m.size2()); }

        static std::ptrdiff_t stride1 (MType& m) { return F::one1 (m.size1(), m.size2()); }
        static std::ptrdiff_t stride2 (MType& m) { return F::one2 (m.size1(), m.size2()); }
      };

Notes:

[1] As `ublas::matrix<>` is general matrix, `uplo_type` is not defined.

[2] Metafunction `detail::ublas_ordering<>` (defined in `detail/ublas_ordering.hpp`) maps `orientation_category`, as defined in uBLAS, to corresponding ordering type.

[3] Note that the `storage()` function uses `vector_traits::storage<>()`.

[4] This specialisation also defines functions `stride1()` and `stride2()` because they are needed in specialisations of `vector_traits<>` for `ublas::matrix_row<>` and `ublas::matrix_column<>`.

Example. Specialisation of `matrix_detail_traits<>` for `ublas::symmetric_matrix<>` (see `ublas_symmetric.hpp`):

      template <typename T, typename F1, typename F2, typename A, typename MType>
      struct matrix_detail_traits<boost::numeric::ublas::symmetric_matrix<T, F1, F2, A>, Mtype> {

        typedef symmetric_packed_t matrix_structure;
        typedef typename detail::ublas_ordering<typename F2::orientation_category>::type ordering_type;
        typedef typename detail::ublas_uplo<typename F1::packed_category>::type uplo_type;

        typedef T value_type;
        typedef typename detail::generate_const<MType,T>::type* pointer;

        static pointer storage (MType& sm) {
          typedef typename detail::generate_const<MType,A>::type array_type ;
          return vector_traits<array_type>::storage (sm.data());
        }
        static std::ptrdiff_t num_rows (MType& sm) { return sm.size1(); }
        static std::ptrdiff_t num_columns (MType& sm) { return sm.size2(); }
      };

This specialisation defines `uplo_type`, but `leading_dimension()` makes no sense for packed matrix storage types.

### 1.5 Sparse Matrix Traits

#### 1.5.1 Description

Generic bindings functions which manipulate sparse matrices are written in terms of types (subsection 1.5.3), static constants (subsection 1.5.4) and static functions (subsection 1.5.5) defined in the `sparse_matrix_traits<>` class.

#### 1.5.2 Definition

Generic class `sparse_matrix_traits<>` is defined in header `boost/numeric/bindings/traits/sparse_traits.hpp`.

Specialisations are defined in:

Header | Matrix classes
--- | ---
`ublas_sparse.hpp` | `ublas::compressed_matrix<>`, `ublas::coordinate_matrix<>`

All headers are in `boost/numeric/bindings/traits/`.

#### 1.5.3 Associated Types

Value type | `value_type` | The type of the objects contained in the matrix
Value pointer type | `value_pointer` | Data type used to point to (nonzero) matrix elements
Index pointer type | `index_pointer` | Data type used to point to row and column indices
Matrix structure | `matrix_structure` | Describes the pattern of nonzero and zero elements and the storage layout [1]
Ordering type | `ordering_type` | Row or column major [2]
Storage format | `storage_format` | Data structure used to store the matrix [3]

[1] `matrix_structure` is a tag which can be:

- `general_t`

[2] `ordering_type` can be:

- `row_major_t`
- `column_major_t`

[3] `storage_format` can be:

- `compressed_t`
- `coordinate_t`

#### 1.5.4 Static Constants

    BOOST_STATIC_CONSTANT (std::size_t, index_base);

#### 1.5.5 Expression Semantics

Name | Expression | Semantics
--- | --- | ---
Major index | `index1_storage(m)` | Depends on `storage_format` and `ordering_type` [1]
Minor index | `index2_storage(m)` | Depends on `storage_format` and `ordering_type` [2]
Element storage | `storage(m)` | Returns a pointer to the beginning of the storage of matrix entries [3]
Number of rows | `num_rows(m)` | Returns the number of rows of matrix `m`
Number of columns | `num_columns(m)` | Returns the number of columns matrix `m`
Number of entries | `num_nonzeros(m)` | Returns the number of matrix entries [3]

[1] Returned value is a pointer to the beginning of:

|  | the array of column start locations |  | for compressed column format;
|  | the array of row start locations |  | for compressed row format;
|  | the array of column indices |  | for column major coordinate format;
|  | the array of row indices |  | for row major coordinate format.

[2] Returned value is a pointer to the beginning of:

|  | the array of row indices |  | for compressed column format;
|  | the array of column indices |  | for compressed row format;
|  | the array of row indices |  | for column major coordinate format;
|  | the array of column indices |  | for row major coordinate format.

[3] All nonzeros are entries, but an entry may be numerically zero.

#### 1.5.6 Implementation

Implementation of `sparse_matrix_traits<>` is similar to the `matrix_traits<>`'s implementation (subsection 1.4.5).

Specialisations of `sparse_matrix_detail_traits<>` must provide types defined in subsection 1.5.3, static constants defined in subsection 1.5.4 and static member functions defined in subsection 1.5.5.

### 1.6 Free functions

There are also free functions available to obtain storage layout information:

- in `vector_traits.hpp`:

  Expression | Semantics
  --- | ---
  `vector_storage(v)` | Returns a pointer to the beginning of the storage of vector `v`
  `vector_size(v)` | Returns the size of vector `v`
  `vector_stride(v)` | Returns the distance between pointers pointing to consecutive entries in `v`

- in `matrix_traits.hpp`:

  Expression | Semantics
  --- | ---
  `matrix_storage(m)` | Returns a pointer to the beginning of the storage of matrix `m`
  `matrix_num_rows(m)` | Returns the number of rows of matrix `m`
  `matrix_num_columns(m)` | Returns the number of columns matrix `m`
  `leading_dimension(m)` | Returns the leading dimension of matrix `m`

The syntax of these is slightly simpler than that of the traits class; e.g. instead of

      traits::vector_traits<some_vector_type const>::storage (v)

one can write

      traits::vector_storage (v)

Although these free functions generally rely on the traits classes, they can also implement an alternative strategy on compilers that are unable to handle the traits idiom (see `vector_raw.hpp` and `matrix_raw.hpp`).

## 2. Calling conventions

To facilitate generic bindings for libraries of which the API is defined in Fortran, the Traits Library provides a multi-platform mapping between C and Fortran calling conventions: some Fortran compilers add a trailing underscore to all defined symbols, some generate symbols in uppercase only.

When including the `traits/fortran.h` header, one of following symbols will be defined:

- `BIND_FORTRAN_LOWERCASE_UNDERSCORE`
- `BIND_FORTRAN_LOWERCASE`

Function names are generated using the `FORTRAN_ID` macro:

          #if defined(BIND_FORTRAN_LOWERCASE_UNDERSCORE)
          #define FORTRAN_ID( id ) id##_
          #elif defined(BIND_FORTRAN_LOWERCASE)
          #define FORTRAN_ID( id ) id
          #endif

Here's more information on how to call Fortran routines from C and C++.

## 3. Type mapping

See type.h for mapping of Fortran types to C.

See type.hpp for mapping of Fortran types to C++

See value_traits.hpp for value_type inside complex types.