moldovean
moldovean

Reputation: 3261

Extract column from matrix in C++

I would like to extract a column from a matrix class which has variable A implemented as a <vector<vector<T> > like this my_matrix(,2) and that should extract my second column. Also I don't want a function name get_col because I already used operator() overloading to extract rows. I tried:

template<class T>
vector<T> & operator()(void, const int& col){
    vector<T> Result(rows,0);
    for(int i=0;i<rows;++i)
        Result[i]=this->A[i][col];
    return Result;
}

any suggestions?

The class consists of:

template <class T> class QMatrix{
public:
    int rows; 
    int cols;
    vector<vector<T> > A;

Upvotes: 3

Views: 5264

Answers (3)

vsoftco
vsoftco

Reputation: 56547

One way to do this fast (may work for not-to-large matrices) is to store in memory 2 layouts: one for the matrix and one for its transpose. In this way, you have sequential access, and the accessing will be pretty darn fast (i.e., accessing the k-th row will be equivalent to a pointer *row access from k*col_num to (k+1)*col_num, whereas accessing the k-th column will be accessing the other pointer *col from k*row_num to (k+1)*row_num.

You lose in storage space (i.e., need to duplicate the elements), but gain in access time. If you deal with relatively small matrices, but frequent readouts, this may be a way to go.

Otherwise, you can just store your matrix as a 1-D vector, and access it via 2-D indexes, like M[i][j] = vec[i*col_num + j].

Just do some benchmarking and see what works best for your usage case.

Upvotes: 1

Otomo
Otomo

Reputation: 880

Traversing arrays columns is very expensive compared to line accessing because of the layout of the array in the memory. That makes it good that it is ugly to access arrays column by column in C++.

Defining member functions or overloading operators just hides the only way to accomplish it: Go to every row and go to the column you want to access.

You could how ever define a function that returns a vector which holds pointers or references (you will need to use a wrapper like std::reference_wrapper for that) to the elements of a specific column. To create that vector you again need to access every subvector and get the reference/ptr to the n-th element.

Upvotes: 0

zmbq
zmbq

Reputation: 39013

func(,2) is not legal in C++, there's no way to accomplish that.

You could use operator() to access a cell in the matrix, and have one row function that retrieves an entire row, and one col function that retrieves a column.

Or you can overload operator[] for getting a column, but I suspect this will confuse your users quite a bit. I suspect overloading operator() to get a single row will also confuse your users, it's not very C++-y.

Upvotes: 3

Related Questions