NABLA  Nabla Ain't Basic Linear Algebra
List of all members
matrix_expression< value_t, expr_t, tag > Struct Template Reference

Matrix expression template class. More...

Inheritance diagram for matrix_expression< value_t, expr_t, tag >:
Inheritance graph

Related Functions

(Note that these are not member functions.)

Miscellaneous
template<typename value_t , typename expr_t , typename tag >
expr_t & get_matrix (matrix_expression< value_t, expr_t, tag > &a)
 Returns underlying matrix expression.
template<typename value_t , typename expr_t , typename tag >
const expr_t & get_matrix (const matrix_expression< value_t, expr_t, tag > &a)
 Returns underlying matrix expression.
template<typename value_t , typename expr_t >
void swap (matrix_expression< value_t, expr_t, tag::storage > &a, matrix_expression< value_t, expr_t, tag::storage > &b)
 Swaps contents of two matrices.
template<typename target_shape , typename value_t , typename expr_t , typename tag >
util::reshape_return
< matrix_expression< value_t,
expr_t, tag >, target_shape >
::type 
reshape (const matrix_expression< value_t, expr_t, tag > &a)
 Reshapes a matrix expression.
Matrix operations
template<typename value_t , typename expr_t , typename tag >
const unary< matrix_expression
< value_t, expr_t, tag >
, op::plus
operator+ (const matrix_expression< value_t, expr_t, tag > &a)
 Unary plus operator.
template<typename value_t , typename expr_t , typename tag >
const unary< matrix_expression
< value_t, expr_t, tag >
, op::minus
operator- (const matrix_expression< value_t, expr_t, tag > &a)
 Unary minus operator.
template<typename value_t , typename expr_t , typename tag >
const unary< matrix_expression
< value_t, expr_t, tag >
, op::conj
conj (const matrix_expression< value_t, expr_t, tag > &a)
 Returns conjugated matrix.
template<typename value_t , typename expr_t , typename tag >
const transposed
< matrix_expression< value_t,
expr_t, tag > > 
transpose (const matrix_expression< value_t, expr_t, tag > &a)
 Returns transposed matrix.
template<typename value_t , typename expr_t , typename tag >
const scaled
< matrix_expression< value_t,
expr_t, tag > > 
operator* (const matrix_expression< value_t, expr_t, tag > &a, const typename expr_t::value_type &s)
 Binary multiplication operator.
template<typename value_t , typename expr_t , typename tag >
const scaled
< matrix_expression< value_t,
expr_t, tag > > 
operator* (const typename expr_t::value_type &s, const matrix_expression< value_t, expr_t, tag > &a)
 Binary multiplication operator.
template<typename value_t , typename expr1 , typename tag1 , typename expr2 , typename tag2 >
const binary
< matrix_expression< value_t,
expr1, tag1 >
, matrix_expression< value_t,
expr2, tag2 >, op::add
operator+ (const matrix_expression< value_t, expr1, tag1 > &left, const matrix_expression< value_t, expr2, tag2 > &right)
 Binary addition operator.
template<typename value_t , typename expr1 , typename tag1 , typename expr2 , typename tag2 >
const binary
< matrix_expression< value_t,
expr1, tag1 >
, matrix_expression< value_t,
expr2, tag2 >, op::sub
operator- (const matrix_expression< value_t, expr1, tag1 > &left, const matrix_expression< value_t, expr2, tag2 > &right)
 Binary subtraction operator.
template<typename value_t , typename expr1 , typename tag1 , typename expr2 , typename tag2 >
const binary
< matrix_expression< value_t,
expr1, tag1 >
, matrix_expression< value_t,
expr2, tag2 >, op::mul
mul (const matrix_expression< value_t, expr1, tag1 > &left, const matrix_expression< value_t, expr2, tag2 > &right)
 Binary element-wise multiplication operation.
template<typename value_t , typename expr1 , typename tag1 , typename expr2 , typename tag2 >
const binary
< matrix_expression< value_t,
expr1, tag1 >
, matrix_expression< value_t,
expr2, tag2 >, op::div
div (const matrix_expression< value_t, expr1, tag1 > &left, const matrix_expression< value_t, expr2, tag2 > &right)
 Binary element-wise multiplication operation.
template<typename value_t , typename expr1 , typename tag1 , typename expr2 , typename tag2 >
product< matrix_expression
< value_t, expr1, tag1 >
, matrix_expression< value_t,
expr2, tag2 > > 
operator* (const matrix_expression< value_t, expr1, tag1 > &left, const matrix_expression< value_t, expr2, tag2 > &right)
 Binary matrix multiplication operator.
template<typename value_t , typename expr1 , typename expr2 , typename tag2 >
expr1 & operator+= (matrix_expression< value_t, expr1, tag::storage > &left, const matrix_expression< value_t, expr2, tag2 > &right)
 Matrix addition assignment operator.
template<typename value_t , typename expr1 , typename expr2 , typename tag2 >
expr1 & operator-= (matrix_expression< value_t, expr1, tag::storage > &left, const matrix_expression< value_t, expr2, tag2 > &right)
 Matrix subtraction assignment operator.
template<typename value_t , typename expr_t >
expr_t & operator*= (matrix_expression< value_t, expr_t, tag::storage > &left, const value_t &right)
 Matrix multiplication assignment operator.
template<typename value_t , typename expr1 , typename expr2 , typename tag2 >
expr1 & operator*= (matrix_expression< value_t, expr1, tag::storage > &left, const matrix_expression< value_t, expr2, tag2 > &right)
 Matrix multiplication assignment operator.

Detailed Description

template<typename value_t, typename expr_t, typename tag>
struct nabla::matrix_expression< value_t, expr_t, tag >

Matrix expression template class.

This class is the base class for all matrix expressions including class matrix .

The first template parameter value_t is the type of elements manipulated by subclasses. There is a limitation on using classes with different element types because standard C++ has no feature to determine the type of result of a particular operation. For example it is not possible to define a type that is the result type of an operation
some_type + some_other_type even if an operator taking these types is defined, for example

some_type operator+(const some_type&, const some_other_type&);

The second template parameter expr_t is the actual type of the underlying expression. This class must be used as a base class for a matrix expression class. Additionally the class which inherits matrix_expression must supply its type as the second parameter. This way a reference can be obtained not only to the base class but also to the underlying subclass. For more information see Curiously Recurring Template Pattern.

The third template parameter tag determines the kind of expression in the sense of its behavior. For details see Expression Tags.

Defining Matrix Expressions

To define a matrix expression one needs to "subclass" matrix_expression. Quotation marks tell that this is not an ordinary subclassing but a trick called CRTP (which stands for Curiously Recurring Template Pattern). A typical definition of a type, which "is-a" matrix expression, may look like

template<typename type>
class my_matrix :
public matrix_expression<type, //element type
my_matrix<type>, //actual type
tag::storage //tag
>
{
//rest of definition
};

In this case a set of members must conform to storage tag requirements to make my_matrix seamlessly integrated into the library (see Storage Concept Description). For more information see Expression Tags.

Using Matrix Expressions

Once you've done it you can write template functions taking not a concrete type but an expression. For example this function takes by reference only actual storage types (e.g. my_matrix defined above):

template<typename value_t, typename expr_t>
void foo(matrix_expression<value_t, expr_t, tag::storage> &e)
{
expr_t &m = get_matrix(e); //get underlying object
//modifying 'm'
return;
}

Being too verbose is the price for flexibility. A function can take arguments as expressions of any type or one specific type (like in the case above). This feature is heavily exploited throughout this library.

It almost trivially expands to cases with several arguments. Let's consider two argument case. I hope the following code is self explanatory

template<typename value_t, typename expr1, typename tag1, typename expr2, typename tag2>
value_t bar(const matrix_expression<value_t, expr1, tag1> &e1,
const matrix_expression<value_t, expr2, tag2> &e2
)
{
const expr1 &a = get_matrix(e1); //get underlying objects
const expr2 &b = get_matrix(e2);
value_t answer;
//doing calculations
return answer;
}

Enforcing the design this function only handles expressions with the same element types since both arguments have the same value_t argument.

Extending Matrix Expressions

Once you got the idea of how this whole kludge works you can extend this system by defining a template class for your specific expressions. shaped_expression is such an extension.

Note
Actually this extension is a workaround. To this date (beginning of 2010) no compilers fully support idiom like this:
template<typename expr_t, typename tag, typename shape = rectangular>
struct matrix_expression; //this is a declaration
template<typename expr_t, typename tag>
struct matrix_expression<expr_t, tag, rectangular> //root of hierarchy
{};
template<typename expr_t, typename tag>
struct matrix_expression<expr_t, tag, symmetric> :
public matrix_expression<expr_t, read_only_ref<tag>::tag, rectangular>
{};
//etc.
To support symmetric and other shapes this pattern has to be split into distinct types rather than distinct template instances so that any given hierarchy contains only one instance of a template class. Hence the type shaped_expression.

For example let's define a specific_expression. In order to define it we have to make some decisions:

template<typename value_t, typename expr_t, typename tag>
struct specific_expression :
public matrix_expression<value_t, expr_t, tag>
{};

Well, that's all. Now if you want a specific operation act specifically you overload it for the defined expression type. You can do it like this:

template<typename value_t, typename expr_t>
void foo(specific_expression<value_t, expr_t, tag::storage> &e)
{
expr_t &m = get_matrix(e); //get underlying object
//modifying 'm' in a specific way
return;
}
Note
Actually I copied&pasted the definition of foo() from a section above and modified it a bit. This way (through secret copy&paste technology) most of the operations in this library are defined.

Why are we doing all this? Imagine you are able to implement extremely useful method for a specific type which will do the magic. But the library is not aware of it and will not use it. Then you define your specific expression and state (in its documentation) that every type belonging to this concept must supply this method. Overloaded operations aware of this wonderful method will definitely use it. And other (not overloaded) operations will use supplied expressions as if they were ordinary matrix expressions.

See Also
shaped_expression, vector_expression, matrix

Definition at line 1195 of file matrix.h.

Friends And Related Function Documentation

const unary< matrix_expression< value_t, expr_t, tag >, op::conj > conj ( const matrix_expression< value_t, expr_t, tag > &  a)
related

Returns conjugated matrix.

This function returns an expression which represents conjugated matrix, i.e. a matrix with conjugated corresponding elements.

For real valued matrices it just returns a constant reference to the argument, i.e. it actually does nothing.

For some important details check out Using complex types.

Complexity:
conj(m): algorithmic complexity of this operation is constant (i.e. O(1)).

By convention the resulting expression has complexity of its subexpression.

Definition at line 3921 of file matrix.h.

const binary< matrix_expression< value_t, expr1, tag1 >, matrix_expression< value_t, expr2, tag2 >, op::div > div ( const matrix_expression< value_t, expr1, tag1 > &  left,
const matrix_expression< value_t, expr2, tag2 > &  right 
)
related

Binary element-wise multiplication operation.

This operation produces a matrix containing quotients of corresponding elements of argument matrices:
m(i, j) = left(i, j)/right(i, j) for each i and j.

Sizes of argument matrices must be equal. Otherwise an exception (size_error) is thrown.

Complexity:
mul(m, m): algorithmic complexity of this operation is square (i.e. O(n2)).

Definition at line 4295 of file matrix.h.

expr_t & get_matrix ( matrix_expression< value_t, expr_t, tag > &  a)
related

Returns underlying matrix expression.

This template function deduces the actual type of the underlying matrix expression and returns a reference to it. This scheme is called Curiously Recurring Template Pattern.

Definition at line 1498 of file matrix.h.

const expr_t & get_matrix ( const matrix_expression< value_t, expr_t, tag > &  a)
related

Returns underlying matrix expression.

This template function deduces the actual type of the underlying matrix expression and returns a reference to it. This scheme is called Curiously Recurring Template Pattern.

Definition at line 1506 of file matrix.h.

const binary< matrix_expression< value_t, expr1, tag1 >, matrix_expression< value_t, expr2, tag2 >, op::mul > mul ( const matrix_expression< value_t, expr1, tag1 > &  left,
const matrix_expression< value_t, expr2, tag2 > &  right 
)
related

Binary element-wise multiplication operation.

This operation produces a matrix containing products of corresponding elements of argument matrices:
m(i, j) = left(i, j)*right(i, j) for each i and j.

Sizes of argument matrices must be equal. Otherwise an exception (size_error) is thrown.

Complexity:
mul(m, m): algorithmic complexity of this operation is square (i.e. O(n2)).

Definition at line 4265 of file matrix.h.

const scaled< matrix_expression< value_t, expr_t, tag > > operator* ( const matrix_expression< value_t, expr_t, tag > &  a,
const typename expr_t::value_type &  s 
)
related

Binary multiplication operator.

Complexity:
m*s: algorithmic complexity of this operation is square (i.e.

O(n2)).

Definition at line 4081 of file matrix.h.

const scaled< matrix_expression< value_t, expr_t, tag > > operator* ( const typename expr_t::value_type &  s,
const matrix_expression< value_t, expr_t, tag > &  a 
)
related

Binary multiplication operator.

Complexity:
s*m: algorithmic complexity of this operation is square (i.e.

O(n2)).

Definition at line 4098 of file matrix.h.

product< matrix_expression< value_t, expr1, tag1 >, matrix_expression< value_t, expr2, tag2 > > operator* ( const matrix_expression< value_t, expr1, tag1 > &  left,
const matrix_expression< value_t, expr2, tag2 > &  right 
)
related

Binary matrix multiplication operator.

Number of columns of the first matrix left and number of rows of the second matrix right must be equal. Otherwise an exception (size_error) is thrown.

Complexity:
m*m: algorithmic complexity of this operation is cubic (i.e. O(n3)).

Definition at line 4833 of file matrix.h.

expr_t & operator*= ( matrix_expression< value_t, expr_t, tag::storage > &  left,
const value_t &  right 
)
related

Matrix multiplication assignment operator.

Complexity:
m *= s: algorithmic complexity of this operation is square (i.e.

O(n2)).

Definition at line 5048 of file matrix.h.

expr1 & operator*= ( matrix_expression< value_t, expr1, tag::storage > &  left,
const matrix_expression< value_t, expr2, tag2 > &  right 
)
related

Matrix multiplication assignment operator.

Number of columns of the first matrix and number of rows of the second matrix must be equal. Otherwise an exception is thrown.

Complexity:
m *= m: algorithmic complexity of this operation is cubic (i.e. O(n3)).

Definition at line 5082 of file matrix.h.

const unary< matrix_expression< value_t, expr_t, tag >, op::plus > operator+ ( const matrix_expression< value_t, expr_t, tag > &  a)
related

Unary plus operator.

Complexity:
+m: algorithmic complexity of this operation is constant (i.e.

O(1)).

By convention the resulting expression has complexity of its subexpression.

Definition at line 3876 of file matrix.h.

const binary< matrix_expression< value_t, expr1, tag1 >, matrix_expression< value_t, expr2, tag2 >, op::add > operator+ ( const matrix_expression< value_t, expr1, tag1 > &  left,
const matrix_expression< value_t, expr2, tag2 > &  right 
)
related

Binary addition operator.

Sizes of argument matrices must be equal. Otherwise an exception (size_error) is thrown.

Complexity:
m + m: algorithmic complexity of this operation is square (i.e. O(n2)).

Definition at line 4209 of file matrix.h.

expr1 & operator+= ( matrix_expression< value_t, expr1, tag::storage > &  left,
const matrix_expression< value_t, expr2, tag2 > &  right 
)
related

Matrix addition assignment operator.

Sizes of argument matrices must be equal. Otherwise an exception is thrown.

Complexity:
m += m: algorithmic complexity of this operation is square (i.e. O(n2)).

Definition at line 4989 of file matrix.h.

const unary< matrix_expression< value_t, expr_t, tag >, op::minus > operator- ( const matrix_expression< value_t, expr_t, tag > &  a)
related

Unary minus operator.

Complexity:
-m: algorithmic complexity of this operation is constant (i.e.

O(1)).

By convention the resulting expression has complexity of its subexpression.

Definition at line 3895 of file matrix.h.

const binary< matrix_expression< value_t, expr1, tag1 >, matrix_expression< value_t, expr2, tag2 >, op::sub > operator- ( const matrix_expression< value_t, expr1, tag1 > &  left,
const matrix_expression< value_t, expr2, tag2 > &  right 
)
related

Binary subtraction operator.

Sizes of argument matrices must be equal. Otherwise an exception (size_error) is thrown.

Complexity:
m - m: algorithmic complexity of this operation is square (i.e. O(n2)).

Definition at line 4235 of file matrix.h.

expr1 & operator-= ( matrix_expression< value_t, expr1, tag::storage > &  left,
const matrix_expression< value_t, expr2, tag2 > &  right 
)
related

Matrix subtraction assignment operator.

Sizes of argument matrices must be equal. Otherwise an exception is thrown.

Complexity:
m -= m: algorithmic complexity of this operation is square (i.e. O(n2)).

Definition at line 5019 of file matrix.h.

util::reshape_return< matrix_expression< value_t, expr_t, tag >, target_shape >::type reshape ( const matrix_expression< value_t, expr_t, tag > &  a)
related

Reshapes a matrix expression.

This function returns an expression (of type reshaped) with specified shape. The returned expression refers to a the way if it were an expression of specified shape.

Like standard C++ dynamic_cast this cast operation performs runtime check (see documentation for reshape_constraint) and, if requirements of the target shape are not met, raises an exception (of type reshape_error).

Initially reshape makes sense only for predefined (by the library) shapes. To make it work with user shapes one need to specialize reshaped template class.

reshape<rectangular>(a) does not reshape an expression, it has the same effect as

For target shapes other than rectangular the upper triangle (super diagonal) part is taken into account by default. This means that if you reshape a matrix to, say, a symmetric matrix, then resulting matrix consists of mirrored upper triangle part of the original matrix.

While the default is to use upper triangle part of the matrix, one may want to use the counter part. You can choose what side of the original matrix to use in resulting matrix using reshape<shape, side>() form. For example:

//L contains sub diagonal elements of 'm'
L = reshape<lower_tr, lower_tr>(m);
//U contains super diagonal elements of 'm'
U = reshape<upper_tr, upper_tr>(m);
Complexity:
reshape<shape_id>(m): algorithmic complexity of this operation is constant (i.e. O(1)).
See Also
reshaped

Definition at line 3718 of file matrix.h.

void swap ( matrix_expression< value_t, expr_t, tag::storage > &  a,
matrix_expression< value_t, expr_t, tag::storage > &  b 
)
related

Swaps contents of two matrices.

This template function handles all matrix expressions with storage tag. Such expressions are meant to be storage types and by definition provide efficient swap operation.

The actual effect of this function is

get_matrix(a).swap(get_matrix(b));

This function is not meant to throw any exceptions.

Definition at line 3263 of file matrix.h.

const transposed< matrix_expression< value_t, expr_t, tag > > transpose ( const matrix_expression< value_t, expr_t, tag > &  a)
related

Returns transposed matrix.

Complexity:
transpose(m): algorithmic complexity of this operation is constant (i.e.

O(1)).

By convention the resulting expression has complexity of its subexpression.

Definition at line 3982 of file matrix.h.


The documentation for this struct was generated from the following file: