Skip to content
This repository has been archived by the owner on Oct 25, 2019. It is now read-only.

Commit

Permalink
Allowed const templated for cppmat::tiny, cppmat::tensor2, cppmat::te…
Browse files Browse the repository at this point in the history
…nsor3
  • Loading branch information
tdegeus committed Mar 25, 2018
1 parent 3fed08d commit 4f8c60b
Show file tree
Hide file tree
Showing 13 changed files with 182 additions and 53 deletions.
8 changes: 4 additions & 4 deletions docs/compile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ Compiling
Introduction
============

This module is header only. So one just has to ``#include <cppmat/cppmat.h>`` somewhere in the source code, and to tell the compiler where the header-files are. For the latter, several ways are described below.
This module is header only. So one just has to ``#include <cppmat/cppmat.h>`` somewhere in the source code, and to tell the compiler where the header files are. For the latter, several ways are described below.

Before proceeding, a words about optimization. Of course one should use optimization when compiling the release of the code (``-O2`` or ``-O3``). But it is also a good idea to switch off the assertions in the code (mostly checks on size) that facilitate easy debugging, but do cost time. Therefore, include the flag ``-DNDEBUG``. Note that this is all C++ standard. I.e. it should be no surprise, and it always a good idea to do.
Before proceeding, a word about optimization. Of course one should use optimization when compiling the release of the code (``-O2`` or ``-O3``). But it is also a good idea to switch off the assertions in the code (mostly checks on size) that facilitate easy debugging, but do cost time. Therefore, include the flag ``-DNDEBUG``. Note that this is all C++ standard. I.e. it should be no surprise, and it is always a good idea to do.

Manual compiler flags
=====================
Expand Down Expand Up @@ -46,7 +46,7 @@ Install

To enable (semi-)automatic build, one should 'install' ``cppmat`` somewhere.

Install system-wide (root)
Install systemwide (root)
^^^^^^^^^^^^^^^^^^^^^^^^^^

1. Proceed to a (temporary) build directory. For example
Expand Down Expand Up @@ -91,7 +91,7 @@ Install in custom location (user)
.. note:: **(Not recommended)**

If you do not wish to use ``CMake`` for the installation, or you want to do something custom. You can of course. Follow these steps:
If you do not wish to use ``CMake`` for the installation, or you want to do something custom. You can, of course. Follow these steps:

1. Copy the file ``src/cppmat.pc.in`` to ``cppmat.pc`` to some location that can be found by ``pkg_config`` (for example by adding ``export PKG_CONFIG_PATH=/path/to/cppmat.pc:$PKG_CONFIG_PATH`` to the ``.bashrc``).

Expand Down
10 changes: 5 additions & 5 deletions docs/cppmat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ cppmat::matrix

See `matrix.h <https://github.com/tdegeus/cppmat/blob/master/src/cppmat/matrix.h>`_ and `matrix.cpp <https://github.com/tdegeus/cppmat/blob/master/src/cppmat/matrix.cpp>`_

Header-only module that provides a C++ class for n-d matrices. For example a rank 3 matrix is allocated as follows:
Header-only module that provides a C++ class for n-d matrices. For example, a rank 3 matrix is allocated as follows:

.. code-block:: cpp
Expand All @@ -33,7 +33,7 @@ Header-only module that provides a C++ class for n-d matrices. For example a ran
.. note:: **Tip**

If you know that you will work exclusively with a 2-dimensional matrix, please consider using :ref:`matrix2` instead of :ref:`matrix`. This is generally more efficient. If, on top of that, you want to use only a very small matrix, please the fixed sized :ref:`tiny_matrix2`. The latter doesn't need dynamic memory allocation, and can therefore be considerably faster. For the sake of generality there exist also the classes :ref:`vector` and :ref:`tiny_vector`, but generally one can just just the standard C++ ``std::vector``.
If you know that you will work exclusively with a 2-dimensional matrix, please consider using :ref:`matrix2` instead of :ref:`matrix`. This is generally more efficient. If, on top of that, you want to use only a very small matrix, please the fixed sized :ref:`tiny_matrix2`. The latter doesn't need dynamic memory allocation, and can therefore be considerably faster. For the sake of generality there exist also the classes :ref:`vector` and :ref:`tiny_vector`, but generally one can just use the standard C++ ``std::vector``.

Methods
-------
Expand Down Expand Up @@ -85,12 +85,12 @@ In principle the number of indices should match the dimensions of the matrix (i.
is perfectly acceptable. Note that higher-dimensions can only be trailing ones, using for example ``A(0,5,5)`` is not acceptable, nor is of course ``A(5,5,1)``.

Similarly to refer to the beginning of a block (e.g. a row) one can omit the zero arguments. For example to the beginning of the second row of the above matrix one can use ``&A(1)``.
Similarly to refer to the beginning of a block (e.g. a row) one can omit the zero arguments. For example, to the beginning of the second row of the above matrix one can use ``&A(1)``.

View
----

To print, use the common C++ ``std::cout << A << std::endl;``. To customize formating use the more classic C syntax ``A.printf("%16.8e");``
To print, use the common C++ ``std::cout << A << std::endl;``. To customize formatting use the more classic C syntax ``A.printf("%16.8e");``

.. _matrix2:

Expand Down Expand Up @@ -154,5 +154,5 @@ Class for 1-d matrices (a.k.a. vectors). For example:

.. note::

Compared to `std::vector` this class is not so much different, with the exception that it provides indexing also with round brackets, and and automated printing of entries.
Compared to `std::vector` this class is not so much different, with the exception that it provides indexing also with round brackets, and automated printing of entries.

2 changes: 1 addition & 1 deletion docs/cppmat_periodic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
cppmat::periodic
****************

The class below are identical to those under :ref:`cppmat`, with the exception that periodic indices can be used. For example ``-1`` will refer to the last index along that dimension (i.e. ``-1 -> N-1``, with ``N = A.shape(i)``), while ``N`` will refer the the first index (``N -> 0``).
The classes below are identical to those under :ref:`cppmat`, with the exception that periodic indices can be used. For example ``-1`` will refer to the last index along that dimension (i.e. ``-1 -> N-1``, with ``N = A.shape(i)``), while ``N`` will refer to the first index (``N -> 0``).

.. _periodic_matrix:

Expand Down
16 changes: 8 additions & 8 deletions docs/cppmat_tensor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ cppmat::cartesian

See `tensor.h <https://github.com/tdegeus/cppmat/blob/master/src/cppmat/tensor.h>`_ and `tensor.cpp <https://github.com/tdegeus/cppmat/blob/master/src/cppmat/tensor.cpp>`_

Provides classes for 4th- and 2nd order tensors and vectors (the latter essentially coincide with ``std::vector``, but with special methods). For example a fourth order identity tensor in 3-D is obtained as follows:
Provides classes for 4th- and 2nd order tensors and vectors (the latter essentially coincide with ``std::vector``, but with special methods). For example, a fourth order identity tensor in 3-D is obtained as follows:

.. code-block:: cpp
Expand All @@ -26,11 +26,11 @@ Provides classes for 4th- and 2nd order tensors and vectors (the latter essentia
.. note:: **Tip**

To print, use the common C++ ``std::cout << A << std::endl;``. To customize formating use the more classic C syntax ``A.printf("%16.8e");``
To print, use the common C++ ``std::cout << A << std::endl;``. To customize formatting use the more classic C syntax ``A.printf("%16.8e");``

.. note:: **Tip**

If you know that you will work exclusively in 2 or 3 dimensions, please consider using :ref:`tensor2` or :ref:`tensor3` instead of :ref:`tensor`. This is generally more efficient as it can take advantage of the knowledge that the arrays are fixed-size and relatively small. Also several loops are unrolled.
If you know that you will work exclusively in 2 or 3 dimensions, please consider using :ref:`cartesian2` or :ref:`cartesian3` instead of :ref:`cartesian`. This is generally more efficient as it can take advantage of the knowledge that the arrays are fixed size and relatively small. Also several loops are unrolled.

.. note:: **Tip**

Expand Down Expand Up @@ -142,7 +142,7 @@ Vector (rank 1 tensor) of arbitrary dimension. For example:
.. note::

Because of the flexibility of C++ it is easy to switch between these specialized class and the more general ``cppmat::cartesian::tensor2`` class. For example, the following will work:
Because of the flexibility of C++ it is easy to switch between these specialized classes and the more general ``cppmat::cartesian::tensor2`` classes. For example, the following will work:

.. code-block:: cpp
Expand All @@ -168,7 +168,7 @@ Vector (rank 1 tensor) of arbitrary dimension. For example:

.. note::

The easy automatic conversion described above is not possible from a class to another where more assumptions on the structure are made (e.g. from ``cppmat::cartesian::tensor2`` to ``cppmat::cartesian::tensor2d``) because information is (potentially) lost. To still move forward with the conversion the following manual conversion can be used:
The easy automatic conversion described above is not possible from a class to another where more assumptions on the structure are made (e.g. from ``cppmat::cartesian::tensor2`` to ``cppmat::cartesian::tensor2d``) because information is (potentially) lost. To still move forward with the conversion, the following manual conversion can be used:

.. code-block:: cpp
Expand Down Expand Up @@ -222,11 +222,11 @@ For each class the index operator ``(...)``, the arithmetic operators ``*=``, ``

- ``cppmat::cartesian::tensor4<X> C = A.LT()``

Left-transposition :math:`C_{jikl} = A_{ijkl}`
Left transposition :math:`C_{jikl} = A_{ijkl}`

- ``cppmat::cartesian::tensor4<X> C = A.RT()``

Right-transposition :math:`C_{ijlk} = A_{ijkl}`
Right transposition :math:`C_{ijlk} = A_{ijkl}`

* ``cppmat::cartesian::tensor2<X>``:

Expand Down Expand Up @@ -287,5 +287,5 @@ For each class the index operator ``(...)``, the arithmetic operators ``*=``, ``

.. note::

One can also call the methods as functions using ``cppmmat::ddot( A , B )``, ``cppmmat::dot( A , B )``, ``cppmmat::dyadic( A , B )``, ``cppmmat::cross( A , B )``, ``cppmmat::transpose( A )``, ``cppmmat::transposeR( A )``, ``cppmmat::transposeL( A )``, ``cppmmat::inv( A )``, ``cppmmat::det( A )``, and ``cppmmat::trace( A )``, These methods are just a front-end for the class-methods described above.
One can also call the methods as functions using ``cppmmat::ddot( A , B )``, ``cppmmat::dot( A , B )``, ``cppmmat::dyadic( A , B )``, ``cppmmat::cross( A , B )``, ``cppmmat::transpose( A )``, ``cppmmat::transposeR( A )``, ``cppmmat::transposeL( A )``, ``cppmmat::inv( A )``, ``cppmmat::det( A )``, and ``cppmmat::trace( A )``, These methods are just a front end for the class methods described above.

37 changes: 36 additions & 1 deletion docs/cppmat_tensor2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ cppmat::cartesian2

See `tensor2.h <https://github.com/tdegeus/cppmat/blob/master/src/cppmat/tensor2.h>`_ and `tensor2.cpp <https://github.com/tdegeus/cppmat/blob/master/src/cppmat/tensor.cpp>`_

A specialization of :ref:`cartesian`, that takes advantage of the knowledge that the arrays are fixed-size and small. Also several loops are unrolled. All the functionality and names of :ref:`cartesian` are transferable to :ref:`cartesian2` and :ref:`cartesian3`.
A specialization of :ref:`cartesian`, that takes advantage of the knowledge that the arrays are fixed size and small. Also several loops are unrolled. All the functionality and names of :ref:`cartesian` are transferable to :ref:`cartesian2` and :ref:`cartesian3`.

Compared to :ref:`cartesian` the dimension argument must be omitted everywhere.

Expand Down Expand Up @@ -129,6 +129,41 @@ Like in :ref:`tiny`, the classes under :ref:`cartesian2` can be used to 'view' a
}
}
.. note::

The situation can occur that you want to map a ``const`` pointer, for example when you are designing a function that reads from a matrix that is marked ``const`` (because you want to use the matrix 'read-only'). In that case the ``cppmat::cartesian2d`` tensor that you use to map the larger object should be templated using ``const`` (e.g. ``const double``, ``const size_t``, etc.). The ``cppmat::cartesian2d`` tensor can then only be used 'read-only'.

This case is illustrated in this example:

.. code-block:: cpp
#include "cppmat.h"
void view(const cppmat::matrix<double> &matrix)
{
cppmat::cartesian2d::tensor2s<const double> view;
for ( auto i = 0 ; i < matrix.shape(0) ; ++i )
{
view.map(&matrix(i));
std::cout << view << std::endl;
}
}
int main()
{
cppmat::matrix<double> A({2,3});
A(0,0) = 1.0; A(1,0) = 101.0;
A(0,1) = 2.0; A(1,1) = 102.0;
A(0,2) = 3.0; A(1,2) = 103.0;
view(A);
return 0;
}
.. _cartesian3:

******************
Expand Down
37 changes: 36 additions & 1 deletion docs/cppmat_tiny.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ This class can be used to 'view' and external pointer. This can be useful to ref

.. code-block:: cpp
#include <cppmat/cppmat.h>
int main()
Expand All @@ -63,6 +62,42 @@ This class can be used to 'view' and external pointer. This can be useful to ref
}
}
.. note::

The situation can occur that you want to map a ``const`` pointer, for example when you are designing a function that reads from a matrix that is marked ``const`` (because you want to use the matrix 'read-only'). In that case the ``cppmat::tiny`` matrix (or vector) that you use to map the larger object should be templated using ``const`` (e.g. ``const double``, ``const size_t``, etc.). The ``cppmat::tiny`` matrix can then only be used 'read-only'.

This case is illustrated in this example:

.. code-block:: cpp
#include "cppmat.h"
void view(const cppmat::matrix<size_t> &matrix)
{
cppmat::tiny::matrix2<const size_t,2,2> view;
for ( auto i = 0 ; i < matrix.shape(0) ; ++i )
{
view.map(&matrix(i));
std::cout << view << std::endl;
}
}
int main()
{
cppmat::matrix<size_t> A({2,2,2});
A(0,0,0) = 1; A(1,0,0) = 101;
A(0,0,1) = 2; A(1,0,1) = 102;
A(0,1,0) = 11; A(1,1,0) = 111;
A(0,1,1) = 12; A(1,1,1) = 112;
view(A);
return 0;
}
.. _tiny_vector:

cppmat::tiny::vector
Expand Down
37 changes: 34 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,42 @@
cppmat
******

.. image:: https://img.shields.io/badge/license-MIT-brightgreen.svg
:target: https://github.com/tdegeus/cppmat/blob/master/LICENSE
:alt: MIT license

.. image:: https://img.shields.io/badge/warranty-no-red.svg
:target: https://github.com/tdegeus/cppmat/blob/master/LICENSE
:alt: MIT license

.. image:: https://img.shields.io/badge/download-.zip-lightgray.svg
:target: https://github.com/tdegeus/cppmat/zipball/master
:alt: Download as .zip

.. image:: https://img.shields.io/badge/download-.tar.gz-lightgray.svg
:target: https://github.com/tdegeus/cppmat/tarball/master
:alt: Download as .tar.gz

.. image:: https://img.shields.io/badge/contact-tom@geus.me-blue.svg
:target: mailto:tom@geus.me
:alt: Contact tom@geus.me

.. image:: https://img.shields.io/badge/contact-cppmat.geus.me-blue.svg
:target: http://cppmat.geus.me
:alt: Website cppmat.geus.me

.. image:: https://img.shields.io/badge/contact-www.geus.me-blue.svg
:target: http://www.geus.me
:alt: Website www.geus.me

.. image:: https://img.shields.io/badge/GitHub-tdegeus/cppmat-blue.svg
:target: https://github.com/tdegeus/cppmat
:alt: Github tdegeus/cppmat


.. note::

This document should be considered as a quick-start guide. A lot effort has been spend on the readability of the code itself. One is highly encouraged to answer more advanced questions that rise from this guide directly using the code.
This document should be considered as a quick-start guide. A lot effort has been spent on the readability of the code itself. One is highly encouraged to answer more advanced questions that arise from this guide directly using the code.

This header-only module provides C++ classes and several accompanying methods to work with n-d matrices and/or tensors. It's usage, programmatically and from a compilation perspective, is really simple. One just has to ``#include <cppmat/cppmat.h>`` and tell your compiler where cppmat is located (and to the C++14 or younger standard). Really, that's it!

Expand Down Expand Up @@ -84,8 +117,6 @@ For example:

This library is free to use under the `MIT license <https://github.com/tdegeus/cppmat/blob/master/LICENSE>`_. Any additions are very much appreciated, in terms of suggested functionality, code, documentation, testimonials, word of mouth advertisement, .... Bug reports or feature requests can be filed on `GitHub <http://github.com/tdegeus/cppmat>`_. As always, the code comes with no guarantee. None of the developers can be held responsible for possible mistakes.

Download: `.zip file <https://github.com/tdegeus/cppmat/zipball/master>`_ | `.tar.gz file <https://github.com/tdegeus/cppmat/tarball/master>`_.

(c - `MIT <https://github.com/tdegeus/cppmat/blob/master/LICENSE>`_) T.W.J. de Geus (Tom) | tom@geus.me | `www.geus.me <http://www.geus.me>`_ | `github.com/tdegeus/cppmat <http://github.com/tdegeus/cppmat>`_

Contents
Expand Down
2 changes: 1 addition & 1 deletion docs/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ This library includes provides an interface to `pybind11 <https://github.com/pyb

.. note:: **Warning**

On the Python side all 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::cartesian::tensor2s`` as argument, the upper-diagonal part is read; while when it has an argument ``cppmat::cartesian::tensor2d`` only the diagonal is considered.
On the Python side all 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::cartesian::tensor2s`` as argument, the upper-diagonal part is read; while when it has an argument ``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!**

Expand Down
2 changes: 1 addition & 1 deletion src/cppmat/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#define CPPMAT_WORLD_VERSION 0
#define CPPMAT_MAJOR_VERSION 3
#define CPPMAT_MINOR_VERSION 8
#define CPPMAT_MINOR_VERSION 9

#define CPPMAT_VERSION_AT_LEAST(x,y,z) \
(CPPMAT_WORLD_VERSION>x || (CPPMAT_WORLD_VERSION>=x && \
Expand Down
33 changes: 22 additions & 11 deletions src/cppmat/tensor2.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ class tensor4
{
private:

X m_container[16]; // data container
X *m_data; // pointer to container (may point outside)
// data container
typename std::remove_const<X>::type m_container[16];
// pointer to container (may point outside)
X *m_data;

public:

Expand Down Expand Up @@ -117,8 +119,10 @@ class tensor2
{
private:

X m_container[4]; // data container
X *m_data; // pointer to container (may point outside)
// data container
typename std::remove_const<X>::type m_container[4];
// pointer to container (may point outside)
X *m_data;

public:

Expand Down Expand Up @@ -227,8 +231,10 @@ class tensor2s
{
private:

X m_container[3]; // data container
X *m_data; // pointer to container (may point outside)
// data container
typename std::remove_const<X>::type m_container[3];
// pointer to container (may point outside)
X *m_data;

public:

Expand Down Expand Up @@ -335,9 +341,12 @@ class tensor2d
{
private:

X m_container[2]; // data container
X *m_data; // pointer to container (may point outside)
X m_zero[1]; // dummy parameter, used to return "0" for any off-diagonal entry
// data container
typename std::remove_const<X>::type m_container[2];
// pointer to container (may point outside)
X *m_data;
// dummy parameter, used to return "0" for any off-diagonal entry
X m_zero[1];

public:

Expand Down Expand Up @@ -442,8 +451,10 @@ class vector
{
private:

X m_container[2]; // data container
X *m_data; // pointer to container (may point outside)
// data container
typename std::remove_const<X>::type m_container[2];
// pointer to container (may point outside)
X *m_data;

public:

Expand Down

0 comments on commit 4f8c60b

Please sign in to comment.