Armadillo stores data column-by-column (for compatibility with LAPACK), so extracting columns via .colptr() is the preferred approach. You can refactor your code so that your data is stored column-by-column instead of row-by-row. One brute-force approach to accomplish this is to transpose the matrix.
Armadillo - how to extract rows?
Question
I'm using Armadillo C++ library for matrices.
I would like to copy some of the rows to an external array (I need to copy them to the gpu). Is there a fast way to do this?
If I use .rows
, it gives me a subview with no access to data pointers, so I must iterate on the values and copy them one by one. This is very slow.
Is there another option?
Thanks.
Solution
OTHER TIPS
A possible way to copy some of the rows to an external array is to use the .rows function and assign the result subview as a matrix. Then you can easily access the raw data of this matrix. You can also transpose this matrix if you want row-major data.
The quickest way to get to the matrix data in array format is to use the memptr()
method. It returns a pointer to a C-style array that contains the matrix data. So if you have a Mat<double>
of size n by n, that method gives you a pointer to an array of double
of length n*n.
int n=10;
Mat<double> M(n,n,fill::rand);
double* arr = M.memptr();
if you then loop through arr
you will get the elements in column-major ordering, as mtall pointed out.
Conversely you can very efficiently use an already existing array of data to initialize a matrix, or even just use the matrix object as an interface to perform some linear algebra transformation onto your array (like e.g. a Matrix-vector product). For that have a look into the advanced mat constructor.
This is especially useful for iterative methods such as Lanczos/Arnoldi or Conjugate Gradient related methods and you have an implementation of those working with C-style arrays. You can then just bind these arrays to arma objects without copying to perform transformations.