Matrix Views

A Matrix View can be defined as a rectangular section of a matrix. Currently, MOCCA only supports single rows or columns as matrix views.

Matrix Row/Column

The i-th row/column of a Matrix can be selected by calling the row(i) and col(i) methods, respectively. Like Vector, views from individual rows and columns can appear on both sides of an assignment (i.e., can be used as both a lvalue and a rvalue) and can trigger a Broadcast when mixed with another matrix. However, the content of an individual column cannot be assigned to an individual row of the same matrix, or vice-versa, due to Aliasing problems.

Considering that a Matrix are stored following the Row-Major scheme, the data of an individual row() is stored contiguously in memory and can be retrieved using SIMD instructions, while each element of an individual col() are stored separated positions in memory, and thus, they need to be loaded individually, which is significantly slower.

using namespace mocca;

Matrix<float> A = {{11, 12, 13},
                   {21, 22, 23},
                   {31, 32, 33}};

A.row(0) = 2 * A.row(2)
std::cout << A << std::endl;

// NEVER DO THIS!
// A.col(0) = A.row(1);

Output

[[  62    64    66 ]
 [  21    22    32 ]
 [  31    32    33 ]]

CSRMatrix Row

Similar to the Matrix, individual rows of a CSR Matrix can be selected through the row() method. However, they can only be part of an expression as an rvalue, do not support Broadcast operations and no other object can be assigned to it due to the sparse layout. Even with these restrictions, a row view of a CSR Matrix can provide a more efficient way to access its elements, for example,

using namespace mocca;

CSRMatrix csr(nrows, ncols, nz);
RowVector vec(ncols);

//...//

for (index_t r = 0; r < nrows; ++r)
{
   auto csr_row = csr.row(r);

   // Iterate over the nonzero elements in the row
   for (index_t j = 0; j < csr_row.size(); ++j)
   {
      // Retrieve the column and value of the j-th nonzero element in the row
      auto [col, val] = csr_row.nonzero_at(j);
      vec[col] += val;
   }
}

In this way, the content of the CSR Matrix can be accessed without having to perform any kind of binary search. Row views also provides a RandomAccessIterator instead of BidirectionalIterator when iterating over the entire CSR Matrix.