how to delete a column of a matrix efficiently?


william
08-31-2009, 10:34 PM
Hi, I want to delete a column of a matrix by a function.But I don't know how to do it efficiently.
Here is my code.


void comp_kill(int comp){
MatDoub temp(A.nrows(),A.ncols()-1);

for (int i=0;i<A.nrows();i++)
{
for (int j=0;j<comp;j++) temp[i][j]=A[i][j];
for (int j=comp;j<A.ncols()-1;j++) temp[i][j]=A[i][j+1];
}

A.resize(A.nrows(),A.ncols()-1);

for (int i=0;i<A.nrows();i++)
{
for (int j=0;j<A.ncols()-1;j++) A[i][j]=temp[i][j];
}
}
A is the matrix and a member of a struct. comp_kill is a member function. I want to delete a column(whose index is comp) of A by comp_kill. comp is the input.

I think it is not quite efficient because a medium matrix 'temp' must be built. I am wonderring is there any other way out?

Thanks in advance

gjm
09-08-2009, 08:15 AM
How about this? (Warning: untested code.)

void comp_kill(int comp)
{
int nr = A.nrows();
int nc = A.ncols();
for (int i=0; i<nr; ++i)
{
for (int j=comp; j+1<nr; ++j)
{
A[i][j] = A[i][j+1];
}
}
A.resize(nr,nc-1);
}

There's still lots of copying here. If you're doing a lot of column-deleting, an alternative would be to make your own class that uses an extra layer of indirection so that when you do a column-deletion you just need to reshuffle a few pointers. But that will make everything *else* you do with your matrix slower, and I'd have thought it's very unlikely to be a win overall.

davekw7x
09-08-2009, 08:24 AM
How about this...resize() does not preserve contents.

Regards,

Dave

gjm
09-11-2009, 12:52 PM
Owww! Oh well, then scratch that suggestion. My apologies to William for suggesting something that would have broken his code.

Another option for William to consider (which might turn out to be either impossible or terribly space-inefficient, depending again on his application): don't bother actually deleting the columns you don't want, just move them to the end of the matrix as in the code above and leave them there, and keep track somewhere of how many columns of the matrix are actually valid.