如何在C ++中分配矩阵?

时间:2013-11-01 11:40:34

标签: c++ class memory allocation

对于C ++中的向量,我有

class Vec 
{
public:
  int len;
  double * vdata;
  Vec();
  Vec(Vec const & v) 
  {
    cout<<"Vec copy constructor\n";
    len = v.len;
    vdata=new double[len];
    for (int i=0;i<len;i++) vdata[i]=v.vdata[i];
  };

如果你能帮助我编写一个矩阵的类似代码,我将不胜感激。我在想这样的事情:

class Mat
{
public:

  int nrows;
  int ncols;
  double * mdata;
  Mat();
  Mat(Mat const & m) 
  {
    cout<<"Mat copy constructor\n";
    nrows = m.nrows;
    ncols = m.ncols;

但我不知道如何编码矩阵的内存分配使用的思想首先我们将所有元素放入一维数组(row1 row2 ... rown)然后我们将数组切成行然后剁每行成列。特别是,您能否帮助我将这个想法转化为类似于以下内容的C ++语言:

 vdata=new double[len];
 for (int i=0;i<len;i++) vdata[i]=v.vdata[i];
  };   

我在考虑这样的事情:

double *data=new double[nrows*ncols];
for (int i=0;i<nrows;i++) 
{
   for (int j=0;j<ncols,j++){data(i,j)=m.mdata[i][j]};
};

但我不确定这一部分:

data(i,j)=m.mdata[i][j]

另外,我应该使用纯虚拟元素索引方法:Mat对象m的(i,j)元素将由m(i,j)检索。我必须提供这个索引运算符的const和非const版本。&lt; - 你能告诉我如何做到这一点吗?

非常感谢。

2 个答案:

答案 0 :(得分:4)

用作一维数组。你会注意到在实践中,使用1d数组通常要简单得多。

class Matrix
{
public:
    Matrix(unsigned int rows, unsigned int cols)
        : _rows(rows)
        , _cols(cols)
        , _size(_rows*_cols)
        , _components(new double[_size])
    {
        for(unsigned int i = 0; i < _size; ++i)
        {
            _components[i] = 0;
        }
    }

    ~Matrix()
    {
        delete[] _components;
    }

    double& operator()(unsigned int row, unsigned int col)
    {
         unsigned int index = row * _cols + col;
         return _components[index];
    }

private:
    unsigned int _rows;
    unsigned int _cols;
    unsigned int _size;
    double* _components;    
};

但是,如果你想实际使用矩阵和向量,而不是仅仅实现它们来学习,我真的建议你使用Eigen库。它是免费的开源软件,具有易于使用的矢量和矩阵类。

虽然Eigen非常适合使用,但如果你想查看现有实现的源代码,对于新程序员来说可能会非常混乱 - 它非常通用并且包含很多优化。在vmmlib中可以找到基本矩阵和向量类的不太复杂的实现。

答案 1 :(得分:1)

此外,您可以使用一个标准向量来实现矩阵,但向量大小将为nrows * ncols:

#include <vector>
class Mat {
  public:
    Mat(int rows, int cols): 
      nrows(rows), 
      ncols(cols), 
      elems(rows*cols,0) 
    {}

    Mat(const Mat &m): 
      nrows(m.nrows), 
      ncols(m.ncols), 
      elems(m.elems.begin(), m.elems.end()) 
    {}

    double celem(int i,int j) const {
      return elems[ncols*i + nrows*j];
    }

    double *pelem(int i,int j) {
      return &elems[ncols*i + nrows*j];
    }

  private:
    int nrows;
    int ncols;
    vector<double> elems;
};