.. toctree::
:hidden:
./quick_ref.rst
Installation
===============================================
Remora is hosted on `Github `_ under the LGPL-3 license.
Remora is header-only and depends only on header-only boost c++ libraries.
Just download and copy the contents of the include/ folder into its
target location. Currently the project can only be downloaded from github:
.. code-block:: none
git clone https://github.com/Shark-ML/Remora
Summary
=======
Remora is a general purpose linear algebra library written in C++11.
It features:
* dense and sparse matrix and vector operations
* a basic set of optimized routines for matrix products, solving linear systems of equations, etc.
* bindings to highly optimized routines of BLAS packages
* a powerful expression template syntax which features algebraic optimizations of operations
* Remora is header only, just plug and play!
The goal of Remora is to allow writing of formulas in C++ code as close to mathematical syntax as possible
without penalties in runtime or numerical precision. Currently it relies on bindings for good performance.
Remora is designed for rapid prototyping, especially involving big matrices. It uses
built-in rules deciding whether a set of operations can be exchanged by a set of
more efficient operations. A simple example is a formula like :math:`B = A + A^T`.
In general, this formula can be evaluated without a temporary by computing :math:`B_{ij} = A_{ij} + A_{ji}`.
However, for big matrices this is very inefficient as we have to traverse the matrix along the rows
and along the columns simultaneously, resulting in sub-optimal memory throughput. A more efficient
order of computations is :math:`B=A` followed by :math:`B+=A^T`. Remora does this simple
transformation (and many more) automatically, allowing you to write concise equations which are as
close to formulas as possible.
Quickstart
============================
The power of Remora can be seen in the following lines. We use here linear regression as an example.
Remora gets included via::
#include
using namespace remora;
We first generate the data and label matrices for linear regression::
std::size_t num_data_points = 100;
std::size_t num_dims = 50;
matrix X(num_data_points, num_dims);
vector y(num_data_points);
We skip the step of data generation, but `X(i,j) = value;` and `y(i) = value;` do the trick.
The formula for linear regression with bias is :math:`w = ((X|1)^T(X|1))^{-1}(X|1)^T y`. Here,
(X|1) stands for the matrix X where a column of ones is added to the end. In a typical
implementation we have to be careful since the matrix may not have full rank,
and use a pseudo-inverse instead::
vector w = inv(trans(X|1) % (X|1), symm_semi_pos_def()) % trans(X|1) % y;
Operator ``%`` performs matrix-multiplication, ``trans(A)`` is matrix transposition,
and ``inv(A,tag)`` performs matrix inversion where we have to supply information
about how to invert that matrix. Note that no actual matrix inversion is taking place.
The system automatically detects that the matrix inverse is multiplied with another
matrix and instead instructs to solve
a system of equations with multiple right hand sides :math:`(X|1)^T`.
Likewise it detects that the result is then multiplied with a vector from the right.
This allows the transformation :math:`((X|1)^T(X|1)) w = (X|1)^Ty` where we solve for :math:`w`.
Finally, we compute goodness of fit using the formula :math:`E(w)=\frac 1 {2N} \sum_{i=1}^N ((x_i|1)^Tw -y)^2`::
double error = 0.5 * sum(sqr((X|1) % w - y)) / num_data_points;
where ``sqr(x)`` is element-wise squaring of the entries and ``sum(x)`` sums
all entries of the vector. We can check whether the solution found is actually correct
by verifying that it is a minimizer, i.e., that is the derivative of the error measure
above is close to 0::
vector derE = trans(X|1) % ((X|1) % w - y) / num_data_points;
double error_derivative = norm_inf(derE);
norm_inf is the infinity norm, which returns the maximum element (in absolute value) of the vector.
Tutorials and Quick Reference
=========================================
An overview of the operations supported by Remora is given in the :doc:`./quick_ref`
Compile Flags
=============================================
When using Remora, the following defines can be supplied at compile time
* REMORA_USE_SIMD if defined, Remora uses the compilers' auto vectorizing capabilities
to speed up its computational routines. Requires G++ or clang
* REMORA_USE_CBLAS if defined, Remora binds to a cblas library.
On MacOsX, this flag is interpreted as using the accelerate framework.
Make sure to add the appropriate compile and linker flags for the library.
* REMORA_USE_GPU if defined, Remora is enabling gpu support via the boost/compute
library. Highly experimental.
Remora depends strogly on the optimization level of the compiler. In Debug, many costly index checks
are performed to ensure correctness of the code, while in release high level of optimization should be applied.