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;

しかし、最初にすべての要素を 1D 配列 (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

1 次元配列として使用します。実際には、そのようなものには 1 次元配列を使用する方が一般的にはるかに簡単であることに気付くでしょう。

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

また、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 に答える