First, define a vector<int> which is as large as the number of rows, and populate it with the values 0...r-1. You can use Boost.Assign to do this, or just use a loop.
Next, define a comparator something like this:
Code:
struct CompareColumn
{
const matrix *mat;
int colnum;
CompareColumn(const matrix &m, int keycol)
: mat(&m), colnum(keycol)
{}
bool operator()(const int &lhs, const int &rhs) const
{ return (*mat)[lhs][colnum] < (*mat)[rhs][colnum]; }
};
If you're using one of the newest generation of compilers, you could write this as a lambda expression instead.
Third, use std::sort() with this comparator to sort the index vector.
Fourth, use the index vector to rearrange the rows in the matrix (this may require copying values to a second matrix).
Well, here's a simple example using strings....you can generalize it to your case.
Code:
string s = "Hello, world!";// 13 characters, indexes 0..12 are valid
vector<int> inds = boost::list_of(0,2,4,6,8,10,12,1,3,5,7,9,11};
string s2(s.size());
for (unsigned i = 0; i < inds.size(); i++)
s2[i] = s[inds[i]];
cout << s2;// Output will be "Hlo ol!el,wrd"
EDIT: The above is moving in the right direction. If the interface allows it, you'll find it much more efficient to copy entire rows at a time (assuming the matrix is stored row-contiguous).
There might be a safer way. The uBLAS documentation isn't too specific on the type returned by begin1() and end1(). If that type is a proxy object for a row, and if it's assignable, then you could use boost:ermutation_iterator to do it:
Code:
matrix<double> srcmat(4,7), dstmat(4, 7);
vector<int> indicies;// fill + sort this as described
typedef boost::permutation_iterator< matrix<double>::iterator1, std::vector<int>::iterator > permutation_type;
permutation_type it = make_permutation_iterator( srcmat.begin1(), indices.begin() );
permutation_type it_end = make_permutation_iterator( srcmat.begin1(), indices.end() );
std::copy(it, it_end, dstmat.begin1());
Bookmarks