@@ -1145,12 +1150,8 @@ The result of both examples looks as follows:
## Flexible reduction in matrix rows <a name="flexible_reduction_in_matrix_rows"></a>
### Dense matrix
Simillar operation to `forRows` is `rowsReduction` (\ref TNL::Matrices::DenseMatrix::rowsReduction) which performs given reduction in each matric row. For example, a matrix-vector product can be seen as a reduction of products of matrix elements and input vector in particular matrix rows. The first element of the result vector ios obtained as:
Flexible reduction in matrix rows is a powerful tool for many different matrix operations. It is represented by the method `rowsReduction` (\ref TNL::Matrices::DenseMatrix::rowsReduction,
\ref TNL::Matrices::SparseMatrix::rowsReduction, \ref TNL::Matrices::TridiagonalMatrix::rowsReduction, \ref TNL::Matrices::MultidiagonalMatrix::rowsReduction, \ref TNL::Matrices::LambdaMatrix::rowsReduction) and similar to the method `forRows` it iterates over particular matrix rows. However, it performs *flexible paralell reduction* in addition. For example, the matrix-vector product can be seen as a reduction of products of matrix elements with the input vector in particular matrix rows. The first element of the result vector ios obtained as:
We see that in i-th matrix row we have to compute the sum \f$\sum_{j=1}^n a_{ij}x_j\f$ which is reduction of products \f$ a_{ij}x_j\f$. Similar to *flexible parallel reduction* (\ref TNL::Algorithms::Reduction) we just need to design proper lambda functions. See the following example:
We see that in i-th matrix row we have to compute the sum \f$\sum_{j=1}^n a_{ij}x_j\f$ which is reduction of products \f$ a_{ij}x_j\f$. Similar to flexible parallel reduction (\ref TNL::Algorithms::Reduction) we just need to design proper lambda functions. There are three of them.
1.`fetch` reads and preprocesses data entering the flexible parallel reduction.
2.`reduce` performs the reduction operation.
3.`keep` stores the results from each matrix row.
#### Lambda function fetch
This lambda function has the same purpose as the lambda function `fetch` in flexible parallel reduction for arrays and vectors (see [Flexible Parallel Reduction](tutorial_ReductionAndScan.html#flexible_parallel_reduction)). It is supposed to be declared as follows:
The meaning of the particular parameters is as follows:
1.`rowIdx` is the row index of the matrix element.
2.`columnIdx` is the column index of the matrix element.
3.`value` is the value of the matrix element.
The lambda function returns a value of type `Real` based on the input data.
#### Lambda function reduce
The lambda function `reduce` expresses reduction operation (sum, product, minimum, maximum etc.) which is supposed to be done during the flexible reduction.
The meaning of the particular parameters is as follows:
1.`a` is the first operand for the reduction operation.
2.`b` is the second operand for the reduction operation.
#### Lambda function keep
The lambda function `keep` is new one compared to the flexible reduction for arrays, vectors or other linear structures. The reason is that the result consists of as many numbers as there are matrix rows. Result obtained for each matrix row is processed by this lambda function. It is declared as follows:
The meaning of the particular parameters is as follows:
1.`rowIdx` is an index of the matrix row related to given result of flexible reduction.
2.`value`is the result of the flexible reduction in given matrix row.
The method `rowsReduction` (\ref TNL::Matrices::DenseMatrix::rowsReduction, \ref TNL::Matrices::SparseMatrix::rowsReduction, \ref TNL::Matrices::TridiagonalMatrix::rowsReduction, \ref TNL::Matrices::MultidiagonalMatrix::rowsReduction, \ref TNL::Matrices::LambdaMatrix::rowsReduction) accepts the following arguments:
1.`begin` is the beginning of the matrix rows range on which the reduction will be performed.
2.`end` is the end of the matrix rows range on which the reduction will be performed. The last matrix row which is going to be processed has index `end-1`.
3.`fetch` is the lambda function for data fetching.
4.`reduce` is the the lambda function performing the reduction.
5.`keep` is the lambda function responsible for processing the results from particular matrix rows.
6.`zero` is the "zero" element of given reduction operation also known as *idempotent*.
Though the interface is the same for all matrix types, in the following part we will show several examples for different matrix types to better demonstrate possible ways of use of the flexible reduction for matrices.
### Dense matrices example <a name="dense-matrices-flexible-reduction-example"></a>
The `fetch` lambda function computes the product \f$ a_{ij}x_j\f$ where \f$ a_{ij} \f$ is represented by `value` and \f$x_j \f$ is represented by `xView[columnIdx]`. The reduction is just sum of results particular products and it is represented by by the lambda function `reduce`. Finaly, the lambda function `keep` is responsible for storing the results of reduction in each matrix row (which is represented by the variable `value`) into the output vector `y`.
The `fetch` lambda function computes the product \f$ a_{ij}x_j\f$ where \f$ a_{ij} \f$ is represented by `value` and \f$x_j \f$ is represented by `xView[columnIdx]`. The reduction is just sum of particular products and it is represented by by the lambda function `reduce`. Finally, the lambda function `keep` is responsible for storing the results of reduction in each matrix row (which is represented by the variable `value`) into the output vector `y`.
The `fetch` lambda function just returns absolute value of \f$a_{ij} \f$ which is represented again by the varibale `value`. The `reduce` lambda function returns larger of given values and the lambda fuction 'keep' stores the results to the output vectro the same way as in the previous example. Of course, if we compute the maximum of all output vector elements we get some kined of max matrix norm. The output looks as:
The `fetch` lambda function just returns absolute value of \f$a_{ij} \f$ which is represented again by the varibale `value`. The `reduce` lambda function returns larger of given values and the lambda function 'keep' stores the results to the output vector the same way as in the previous example. Of course, if we compute the maximum of all output vector elements we get some kind of maximal matrix norm. The output looks as:
### Tridiagonal matrices example <a name="tridiagonal-matrices-flexible-reduction-example"></a>
The *flexible parallel reduction* in rows for tridiagonal matrices is also simmilar as for dense and sparse matrices. It is represented by three lambda functions:
@@ -1289,7 +1337,7 @@ The method `rowsReduction` (\ref TNL::Matrices::SparseMatrix::rowsReduction) act