Sunday, November 6, 2011

Masking a matrix in c/c++

In numerical operations on matrices one sometimes faces an issue of reducing the original size of the matrix by removing certain columns and rows. The problem may be formulated differently when remaining elements are a subblock of the original matrix or the remaining elements are scattered. The more general function would collect the scattered elements. To fully define such a procedure we must pass a vector of elements defining which columns and rows should be keept and which to be removed (for example 1 for retaining and 0 for removing). Generating of a new matrix by masking the original one is shown schematically on the figure below. 

A representation of a matrix with columns and rows that are to be removed marked in white. All blue elements will be kept and new matrix of a reduced size will be formed after removing marked columns and rows.
For symmetric masking the matrix with respect to the columns and rows we only need to pass one vector defining columns and rows to be removed. An example of such a function is presented below.
double *sm_mat_mask(int dim, int *mask, double *data){

  // count non-zero elements in mask vector
  int num = 0;
  for(int i=0; i<dim; i++){
    if(mask[i] == 1) num++;
  }

  // number of non-screened elements 
  // (number of elements in the masked matrix)
  int nelements = num*num;

  // allocate space 
  double *masked_data = new double [nelements];
  memset(masked_data,0,nelements*sizeof(double));

  // collect elements
  int offset, idx;

  int elem = 0;
  // rows
  for(int i=0; i<dim; i++){
    // only if row is not to be screened
    if(mask[i] != 0){
      offset = i*dim;
      // columns
      for(int j=0; j<dim; j++){
        // only if column is not to be masked
        if(mask[j] != 0){
          idx = offset + j;
          
          masked_data[elem] = data[idx];

          elem++;
        }
      }
    }
  }

  // return masked matrix
  return masked_data;

}
The above function takes a vector of number representing a matrix (in a row major order), its dimension and vector of 0,1 elements of the same dimension representing columns / rows to be removed. The matrix is assumed to be symmetric and the masking will also be done in a symmetric fashion. The function returns a new matrix that is a reduction of the original matrix.

No comments:

Post a Comment