C++矩阵类

ano*_*non 25 c++ matrix

在C中,如果我想创建一个矩阵结构,我会使用:

struct matrix {
  int col, row;
  double data[1]; // I want the matrix entries stored
                  // right after this struct
}
Run Code Online (Sandbox Code Playgroud)

然后我可以分配它

matrix* allocate_matrix(int row, int col) {
  matrix* m = malloc(sizeof(matrix) + sizeof(double) * (row * col - 1));
  m->row = row; m->col = col;
  return m;
}
Run Code Online (Sandbox Code Playgroud)

现在我在C++中做等效吗?

编辑:

我想知道在C++中实现矩阵类的方法.

Pot*_*ter 38

nota bene.

这个答案现在有20个赞成,但它并不打算作为背书std::valarray.

根据我的经验,安装和学习使用像Eigen这样的完整数学库的时间更长.Valarray比竞争对手的功能更少,但它不是更有效或更易于使用.

如果你只需要一点线性代数,并且你没有在你的工具链中添加任何东西,那么可能valarray会适合.但是,被困无法表达对你的问题的数学上正确的解决方案是一个非常糟糕的位置.数学是无情和无情的.使用正确的工具完成工作.


标准库提供std::valarray<double>.std::vector<>这里的其他几个人建议,它是作为物品的通用容器.valarray,鲜为人知,因为它更专业(不使用"专业"作为C++术语),有几个优点:

  • 它没有分配额外的空间.A vector在分配时向上舍入为最接近的2的幂,因此您可以在不重新分配的情况下调整其大小.(你仍然可以调整大小valarray;它仍然和它一样昂贵realloc().)
  • 您可以将其切片以轻松访问行和列.
  • 算术运算符按预期工作.

当然,使用C的优势在于您不需要管理内存.尺寸可以驻留在堆栈上,也可以位于切片对象中.

std::valarray<double> matrix( row * col ); // no more, no less, than a matrix
matrix[ std::slice( 2, col, row ) ] = pi; // set third column to pi
matrix[ std::slice( 3*row, row, 1 ) ] = e; // set fourth row to e
Run Code Online (Sandbox Code Playgroud)

  • 哎呀,这将迎来10个赞成票.`std :: valarray`相当难以使​​用,仅支持基本的成员代数,并且它不是很受欢迎.试试[Eigen Library](http://eigen.tuxfamily.org/),它非常易于使用,功能强大且受欢迎. (2认同)

jam*_*lin 20

C++主要是C的超集.你可以继续做你正在做的事情.

也就是说,在C++中,你应该做的是定义一个管理自己内存的正确的Matrix类.例如,它可以由内部支持std::vector,您可以适当地覆盖operator[]operator()索引向量(例如,请参阅:如何为Matrix类创建下标运算符?)来自C++ FAQ.

为了帮助您入门:

class Matrix
{
public:
    Matrix(size_t rows, size_t cols);
    double& operator()(size_t i, size_t j);
    double operator()(size_t i, size_t j) const;

private:
    size_t mRows;
    size_t mCols;
    std::vector<double> mData;
};

Matrix::Matrix(size_t rows, size_t cols)
: mRows(rows),
  mCols(cols),
  mData(rows * cols)
{
}

double& Matrix::operator()(size_t i, size_t j)
{
    return mData[i * mCols + j];
}

double Matrix::operator()(size_t i, size_t j) const
{
    return mData[i * mCols + j];
}
Run Code Online (Sandbox Code Playgroud)

(注意,上面没有做任何边界检查,我把它作为练习来模板化,以便它适用于除了以外的东西double.)


GMa*_*ckG 5

可以那样做。唯一的区别是您需要将结果从malloc.

相反,您可以使用vector, 作为具有计算索引的一维数组或嵌入向量。(前者更符合您的代码。)

例如:

template <typename T> // often, they are templates
struct matrix
{
    // should probably be hidden away, and the class would
    // provide `at` and `operator()` for access
    int col, row;
    std::vector<T> data;

    matrix(int columns, int rows) :
    col(columns), row(rows), 
    data(col * row)
    {}

}

matrix m(4, 4);
m.data[1 + 1 * 4] = /* ... */;
Run Code Online (Sandbox Code Playgroud)

或者:

template <typename T>
struct matrix
{
    int col, row;
    std::vector<std::vector<T> > data;

    matrix(int columns, int rows) :
    col(columns), row(rows), 
    data(col, std::vector(row))
    {}
}

matrix m(4, 4);
m.data[1][1] = /* ... */;
Run Code Online (Sandbox Code Playgroud)

但这些只是例子。你想要制作一个成熟的课程;如果您需要更多建议,请编辑您的问题并澄清您想知道实现矩阵类的规范方法。

有预先存在的矩阵类。我最喜欢的是来自 boost、UBLAS 的


Mic*_*son 5

设置高效且高质量的矩阵类有很多微妙之处。值得庆幸的是,有几个很好的实现。

仔细考虑您是想要固定大小的矩阵类还是可变大小的矩阵类。即你能做到这一点:

// These tend to be fast and allocated on the stack.
matrix<3,3> M; 
Run Code Online (Sandbox Code Playgroud)

或者你需要能够做到这一点

// These tend to be slower but more flexible and partially allocated on the heap 
matrix M(3,3); 
Run Code Online (Sandbox Code Playgroud)

有很好的库支持这两种风格,也有一些支持这两种风格。它们具有不同的分配模式和不同的性能。

如果你想自己编码,那么模板版本需要一些模板知识(废话)。如果在紧密循环中使用动态分配,则需要一些技巧来绕过许多小分配。


小智 -5

在 C++ 中你可以这样使用:

matrix *p = new matrix;
Run Code Online (Sandbox Code Playgroud)

在那之后,

delete p; 
Run Code Online (Sandbox Code Playgroud)