4

对于 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 版本。<-- 你能告诉我如何做到这一点吗?

非常感谢。

4

2 回答 2

4

用作一维数组。您会注意到,在实践中,将一维数组用于此类事情通常要简单得多。

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中可以找到基本矩阵和向量类的不太复杂的实现。

于 2013-11-01T12:17:52.413 回答
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;
};
于 2013-11-01T12:38:37.183 回答