All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
View Operations

Table of Contents

Previous: View Types     Next: Addition


Setup of Rows


A reference to a dense or sparse row can very conveniently be created via the row() function. This reference can be treated as any other row vector, i.e. it can be assigned to, it can be copied from, and it can be used in arithmetic operations. The reference can also be used on both sides of an assignment: The row can be either used as an alias to grant write access to a specific row of a matrix primitive on the left-hand side of an assignment or to grant read-access to a specific row of a matrix primitive or expression on the right-hand side of an assignment. The following two examples demonstrate this for dense and sparse matrices:

typedef blaze::DynamicMatrix<double,rowMajor> DenseMatrixType;
DenseVectorType x;
SparseVectorType y;
DenseMatrixType A, B;
SparseMatrixType C, D;
// ... Resizing and initialization
// Setting the 2nd row of matrix A to x
row2 = x;
// Setting the 3rd row of matrix B to y
row( B, 3UL ) = y;
// Setting x to the 4th row of the result of the matrix multiplication
x = row( A * B, 4UL );
// Setting y to the 2nd row of the result of the sparse matrix multiplication
y = row( C * D, 2UL );


Setup of Columns


Similar to the setup of a row, a reference to a dense or sparse column can very conveniently be created via the column() function. This reference can be treated as any other column vector, i.e. it can be assigned to, copied from, and be used in arithmetic operations. The column can be either used as an alias to grant write access to a specific column of a matrix primitive on the left-hand side of an assignment or to grant read-access to a specific column of a matrix primitive or expression on the right-hand side of an assignment. The following two examples demonstrate this for dense and sparse matrices:

DenseVectorType x;
SparseVectorType y;
DenseMatrixType A, B;
SparseMatrixType C, D;
// ... Resizing and initialization
// Setting the 1st column of matrix A to x
col1 = x;
// Setting the 4th column of matrix B to y
column( B, 4UL ) = y;
// Setting x to the 2nd column of the result of the matrix multiplication
x = column( A * B, 2UL );
// Setting y to the 2nd column of the result of the sparse matrix multiplication
y = column( C * D, 2UL );


Common Operations


A row view can be used like any other row vector and a column view can be used like any other column vector. For instance, the current number of elements can be obtained via the size() function, the current capacity via the capacity() function, and the number of non-zero elements via the nonZeros() function. However, since rows and columns are references to specific rows and columns of a matrix, several operations are not possible on views, such as resizing and swapping. The following example shows this by means of a row view:

MatrixType A( 42UL, 42UL );
// ... Resizing and initialization
// Creating a reference to the 2nd row of matrix A
RowType row2 = row( A, 2UL );
row2.size(); // Returns the number of elements in the row
row2.capacity(); // Returns the capacity of the row
row2.nonZeros(); // Returns the number of non-zero elements contained in the row
row2.resize( 84UL ); // Compilation error: Cannot resize a single row of a matrix
RowType row3 = row( A, 3UL );
swap( row2, row3 ); // Compilation error: Swap operation not allowed


Element Access


The elements of the row and column can be directly accessed with the subscript operator. The numbering of the row/column elements is

\[\left(\begin{array}{*{5}{c}} 0 & 1 & 2 & \cdots & N-1 \\ \end{array}\right),\]

where N is the number of columns/rows of the referenced matrix. Alternatively, the elements of a row or column can be traversed via iterators. Just as with vectors, in case of non-const rows or columns, begin() and end() return an Iterator, which allows a manipulation of the non-zero value, in case of a constant rows or columns a ConstIterator is returned:

MatrixType A( 128UL, 256UL );
// ... Resizing and initialization
// Creating a reference to the 31st row of matrix A
RowType row31 = row( A, 31UL );
for( RowType::Iterator it=row31.begin(); it!=row31.end(); ++it ) {
*it = ...; // OK; Write access to the dense row value
... = *it; // OK: Read access to the dense row value.
}
for( RowType::ConstIterator it=row31.begin(); it!=row31.end(); ++it ) {
*it = ...; // Compilation error: Assignment to the value via a ConstIterator is invalid.
... = *it; // OK: Read access to the dense row value.
}
MatrixType A( 128UL, 256UL );
// ... Resizing and initialization
// Creating a reference to the 31st column of matrix A
ColumnType col31 = column( A, 31UL );
for( ColumnType::Iterator it=col31.begin(); it!=col31.end(); ++it ) {
it->value() = ...; // OK: Write access to the value of the non-zero element.
... = it->value(); // OK: Read access to the value of the non-zero element.
it->index() = ...; // Compilation error: The index of a non-zero element cannot be changed.
... = it->index(); // OK: Read access to the index of the sparse element.
}
for( ColumnType::Iterator it=col31.begin(); it!=col31.end(); ++it ) {
it->value() = ...; // Compilation error: Assignment to the value via a ConstIterator is invalid.
... = it->value(); // OK: Read access to the value of the non-zero element.
it->index() = ...; // Compilation error: The index of a non-zero element cannot be changed.
... = it->index(); // OK: Read access to the index of the sparse element.
}


Views on Matrices with Non-Fitting Storage Order


Especially noteworthy is that row and column views can be created for both row-major and column-major matrices. Whereas the interface of a row-major matrix only allows to traverse a row directly and the interface of a column-major matrix only allows to traverse a column, via views it is possible to traverse a row of a column-major matrix or a column of a row-major matrix. For instance:

MatrixType A( 64UL, 32UL );
// ... Resizing and initialization
// Creating a reference to the 31st row of a column-major matrix A
RowType row1 = row( A, 1UL );
for( RowType::Iterator it=row1.begin(); it!=row1.end(); ++it ) {
// ...
}

However, please note that creating a row view on a matrix stored in a column-major fashion or a column-view on a row-major matrix can result in a considerable performance decrease in comparison to a view on a matrix with a fitting storage orientation. This is due to the non-contiguous storage of the matrix elements. Therefore care has to be taken in the choice of the most suitable storage order:

// Setup of two column-major matrices
CompressedMatrix<double,columnMajor> A( 128UL, 128UL );
CompressedMatrix<double,columnMajor> B( 128UL, 128UL );
// ... Resizing and initialization
// The computation of the 15th row of the multiplication between A and B ...
CompressedVector<double,rowVector> x = row( A * B, 15UL );
// ... is essentially the same as the following computation, which multiplies
// the 15th row of the column-major matrix A with B.
CompressedVector<double,rowVector> x = row( A, 15UL ) * B;

Although Blaze performs the resulting vector/matrix multiplication as efficiently as possible using a row-major storage order for matrix A would result in a more efficient evaluation.

Previous: View Types     Next: Addition