Program Listing for File Matrix.h

Program Listing for File Matrix.h#

Return to documentation for file (src/util/support/Matrix.h)

#ifndef MATRIX_TMPL_H
#define MATRIX_TMPL_H

#include <assert.h>
#include <unistd.h>

template <class Mat, class T>
class SubMatrix {
     unsigned r,c;
     Mat& mat;
   public:
     SubMatrix(Mat& m, unsigned _r, unsigned _c) : mat(m), r(_r),c(_c) {}
     unsigned cols() const { return mat.cols()-c; }
     unsigned rows() const { return mat.rows()-r; }
     T& Entry(unsigned index1, unsigned index2) const
      { return mat.Entry(index1+r, index2+c); }
     T& Entry(unsigned index1, unsigned index2)
      { return mat.Entry(index1+r, index2+c); }
  };

template <class Mat, class T>
class RowVector {
     unsigned r,c,len;
     Mat& mat;
   public:
     RowVector(Mat& m, unsigned _r, unsigned _c, unsigned _len)
          : mat(m), r(_r),c(_c), len(_len) { assert(len >= c && len < mat.cols()); }
     unsigned size() const { return len-c; }
     void push_back( const T& e)
       { mat.Entry(r,len) = e; ++len; }
     T& Entry(unsigned index) const
      { assert(index + c < len); return mat.Entry(r, index+c); }
     T& operator [](unsigned index) const
      { return Entry(index); }
  };


template <class T>
class Matrix
{
  unsigned nr, nc, num;
  T* vec;
  unsigned GetLength() const { return num; }
 public:
  typedef T Elem;

  Matrix() { nr = nc = num = 0; vec = 0; }
  Matrix(unsigned _nr, unsigned _nc, unsigned spare = 1)
  { nr = _nr; nc = _nc;
    num = (nr+spare) * (nc+spare);
    if (num == 0)
       vec = 0;
    else
       vec = new T[num];
  }

  Matrix(const Matrix &that)
  { nr = that.nr; nc = that.nc; num = that.num;
    if (num == 0)
       vec = 0;
    else {
       vec = new T[num];
       for (size_t i = 0; i < num; ++i)
          vec[i] = that.vec[i];
    }
  }
  void operator = (const Matrix &that)
  { nr = that.nr; nc = that.nc;
    if (num < that.num) {
      delete [] vec;
      num = that.num;
      vec = new T[num];
    }
    if (that.num > 0) {
       for (int i = 0; i < num; ++i)
          vec[i] = that.vec[i];
    }
  }

  ~Matrix()
  { if (vec != 0)
      delete [] vec;
  }

  unsigned cols() const { return nc; }
  unsigned rows() const { return nr; }
  T& Entry(unsigned index1, unsigned index2) const
   { unsigned index = index1 * nc + index2;
     return vec[index];
   }

  T& operator()(unsigned index1, unsigned index2) const
   {  return Entry(index1, index2); }

  RowVector<Matrix<T>,T> operator[](int index)
      {
     // DQ (11/8/2011): Fixed to avoid function pointer comparision ("rows()" instead of "rows").
        assert(index > 0 && index < rows());
        return RowVector<Matrix<T>, T>(*this, index, 0, cols());
      }

  RowVector<const Matrix<T>,T> operator[](int index) const
      {
     // DQ (11/8/2011): Fixed to avoid function pointer comparision ("rows()" instead of "rows").
        assert(index > 0 && index < rows());
        return RowVector<const Matrix<T>, T>(*this, index, 0, cols());
      }

  void Reset(unsigned index1, unsigned index2)
  {
    unsigned num1 = index1 * index2;
    nr = index1; nc = index2;
    if (num < num1) {
      delete [] vec;
      num = num1;
      vec = new T[num];
    }
  }

  void Initialize(const T &init)
   { for (size_t i = 0; i < num; i++)
       vec[i] = init;
   }

  bool IsEmpty() const { return vec == 0; }


};

template<class Mat, class ElemOp>
bool UpdateMatrix(Mat& d1, const Mat &d2, ElemOp op)
{
  assert (d1.rows() == d2.rows() && d1.cols() == d2.cols());
  bool mod = false;
  for (int i = 0; i < d1.rows(); i++) {
    for (int j = 0; j < d1.cols(); j++) {
      typename Mat::Elem e1 = d1.Entry(i,j);
      if ( op(e1, d2.Entry(i,j))) {
        mod = true;
        d1.Entry(i,j) = e1;
      }
    }
  }
  return mod;
}


#endif