在 C++ 中实现矩阵运算
Implementing Matrix operations in C++
我正在尝试编写一个简单的仅包含 C++ 头文件的库来实现一些基本的数值算法。这是一个爱好者项目,我希望在我的个人时间做。
我创建了一个表示动态大小矩阵的 C++ MatrixX
class,即它的维度可以在 运行 时提供。比如说,我们创建一个 MatrixX
对象如下:
MatrixXd m {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
};
我的 MatrixX<scalarType>
模板 class 使用 std::vector<scalarType>
作为存储数据的容器。
目前,如果我写 m.row(i)
,它 returns 是矩阵的第 i 个行向量。我还想要的是,能够在赋值语句的左侧有 m.row(i)
。类似于:
m.row(i) = {{1, 2, 3}};
m.row(j) = m.row(j) - 2*m.row(i);
有人 hints/tips 知道如何在 C++ 中完成此任务吗?我将我的源代码、单元测试和文档包含在下面的链接中,为了简洁起见没有直接粘贴。
这种情况的一种常见方法是使用 row()
方法 return 一个代理对象来表示行而不是行本身。
然后您可以自由地实现这个 RowProxy
的行为方式,方法是让其操作检查和操作创建它的矩阵。
这是一个粗略的起点:
template<typename T>
class RowProxy {
public:
template<std::size_t N>
RowProxy& operator=(const std::array<T, N>& rhs) {
assert(N == row_index_.columns());
// ...
}
RowProxy& operator=(const RowProxy& rhs) {
assert(matrix_.columns() == rhs.matrix_.columns());
// ...
}
RowProxy& operator=(const Vector<T>& rhs) {
assert(matrix_.columns() == rhs.matrix_.columns());
// ...
}
Vector<T>& operator*(const T& scalar) const {
return ...;
}
// more operators...
private:
MatrixX<T>& matrix_;
std::size_t row_;
template<typename T>
friend class MatrixX;
RowProxy(MatrixX<T>& m, std::size_t r) : matrix_(m), row_(r) {}
};
template<typename T>
struct MatrixX {
public:
// ...
RowProxy<T> row(std::size_t index) {
return RowProxy<T>{*this, index};
}
// ...
};
template<typename T>
Vector<T>& operator*(const T& scalar, const RowProxy* rhs) const {
return rhs * scalar;
}
我正在尝试编写一个简单的仅包含 C++ 头文件的库来实现一些基本的数值算法。这是一个爱好者项目,我希望在我的个人时间做。
我创建了一个表示动态大小矩阵的 C++ MatrixX
class,即它的维度可以在 运行 时提供。比如说,我们创建一个 MatrixX
对象如下:
MatrixXd m {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
};
我的 MatrixX<scalarType>
模板 class 使用 std::vector<scalarType>
作为存储数据的容器。
目前,如果我写 m.row(i)
,它 returns 是矩阵的第 i 个行向量。我还想要的是,能够在赋值语句的左侧有 m.row(i)
。类似于:
m.row(i) = {{1, 2, 3}};
m.row(j) = m.row(j) - 2*m.row(i);
有人 hints/tips 知道如何在 C++ 中完成此任务吗?我将我的源代码、单元测试和文档包含在下面的链接中,为了简洁起见没有直接粘贴。
这种情况的一种常见方法是使用 row()
方法 return 一个代理对象来表示行而不是行本身。
然后您可以自由地实现这个 RowProxy
的行为方式,方法是让其操作检查和操作创建它的矩阵。
这是一个粗略的起点:
template<typename T>
class RowProxy {
public:
template<std::size_t N>
RowProxy& operator=(const std::array<T, N>& rhs) {
assert(N == row_index_.columns());
// ...
}
RowProxy& operator=(const RowProxy& rhs) {
assert(matrix_.columns() == rhs.matrix_.columns());
// ...
}
RowProxy& operator=(const Vector<T>& rhs) {
assert(matrix_.columns() == rhs.matrix_.columns());
// ...
}
Vector<T>& operator*(const T& scalar) const {
return ...;
}
// more operators...
private:
MatrixX<T>& matrix_;
std::size_t row_;
template<typename T>
friend class MatrixX;
RowProxy(MatrixX<T>& m, std::size_t r) : matrix_(m), row_(r) {}
};
template<typename T>
struct MatrixX {
public:
// ...
RowProxy<T> row(std::size_t index) {
return RowProxy<T>{*this, index};
}
// ...
};
template<typename T>
Vector<T>& operator*(const T& scalar, const RowProxy* rhs) const {
return rhs * scalar;
}