NABLA
Nabla Ain't Basic Linear Algebra
|
Matrix expression template class. More...
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. |
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
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.
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
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.
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):
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
Enforcing the design this function only handles expressions with the same element types since both arguments have the same value_t argument.
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.
shaped_expression
.For example let's define a specific_expression
. In order to define it we have to make some decisions:
matrix_expression
, it publicly inherits matrix_expression
;matrix_expression
are related with "is-a" relationship, this means that all specific expressions must satisfy the requirements of matrix_expression
, we pass expression tag to matrix_expression
unmodified, otherwise we have to determine the tag for the base class matrix_expression
.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:
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.
|
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.
conj(m)
: algorithmic complexity of this operation is constant (i.e. O(1)).By convention the resulting expression has complexity of its subexpression.
|
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.
mul(m, m)
: algorithmic complexity of this operation is square (i.e. O(n2)).
|
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.
|
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.
|
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.
mul(m, m)
: algorithmic complexity of this operation is square (i.e. O(n2)).
|
related |
Binary multiplication operator.
m*s
: algorithmic complexity of this operation is square (i.e.O(n2)).
|
related |
Binary multiplication operator.
s*m
: algorithmic complexity of this operation is square (i.e.O(n2)).
|
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.
m*m
: algorithmic complexity of this operation is cubic (i.e. O(n3)).
|
related |
Matrix multiplication assignment operator.
m *= s
: algorithmic complexity of this operation is square (i.e.O(n2)).
|
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.
m *= m
: algorithmic complexity of this operation is cubic (i.e. O(n3)).
|
related |
Unary plus operator.
+m
: algorithmic complexity of this operation is constant (i.e.O(1)).
By convention the resulting expression has complexity of its subexpression.
|
related |
Binary addition operator.
Sizes of argument matrices must be equal. Otherwise an exception (size_error
) is thrown.
m + m
: algorithmic complexity of this operation is square (i.e. O(n2)).
|
related |
Matrix addition assignment operator.
Sizes of argument matrices must be equal. Otherwise an exception is thrown.
m += m
: algorithmic complexity of this operation is square (i.e. O(n2)).
|
related |
Unary minus operator.
-m
: algorithmic complexity of this operation is constant (i.e.O(1)).
By convention the resulting expression has complexity of its subexpression.
|
related |
Binary subtraction operator.
Sizes of argument matrices must be equal. Otherwise an exception (size_error
) is thrown.
m - m
: algorithmic complexity of this operation is square (i.e. O(n2)).
|
related |
Matrix subtraction assignment operator.
Sizes of argument matrices must be equal. Otherwise an exception is thrown.
m -= m
: algorithmic complexity of this operation is square (i.e. O(n2)).
|
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:
reshape<shape_id>(m)
: algorithmic complexity of this operation is constant (i.e. O(1)).
|
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
This function is not meant to throw any exceptions.
|
related |
Returns transposed matrix.
transpose(m)
: algorithmic complexity of this operation is constant (i.e.O(1)).
By convention the resulting expression has complexity of its subexpression.