mxn矩阵学习笔记

mxn矩阵学习笔记

mxn矩阵学习笔记

1. 简介

nxm矩阵是线性代数中的基本概念,用于表示n行m列的矩阵。本教程将介绍如何使用C++实现一个通用的nxm矩阵类,支持任意维度的矩阵运算。

2. 代码实现

2.1 头文件 (matrixnxm.h)

#ifndef MATRIXNXM_H

#define MATRIXNXM_H

#include

#include

#include

#include

namespace math {

namespace linear_algebra {

/**

* @brief nxm矩阵类

*

* 这个类实现了nxm矩阵的基本运算,包括:

* - 矩阵加减

* - 矩阵乘法

* - 标量乘法

* - 转置

* - 行列式(仅方阵)

* - 逆矩阵(仅方阵)

* - 特征值和特征向量

* - 矩阵性质检查

*/

class MatrixNxM {

public:

// 构造函数

MatrixNxM(); // 默认构造函数,创建0x0矩阵

MatrixNxM(size_t rows, size_t cols); // 创建指定维度的零矩阵

MatrixNxM(const std::vector>& data); // 从二维数组初始化

// 基本属性

size_t rows() const; // 获取行数

size_t cols() const; // 获取列数

bool isSquare() const; // 检查是否为方阵

// 元素访问

double& operator()(size_t i, size_t j); // 访问元素

const double& operator()(size_t i, size_t j) const; // 常量访问元素

// 矩阵运算

MatrixNxM operator+(const MatrixNxM& other) const; // 矩阵加法

MatrixNxM operator-(const MatrixNxM& other) const; // 矩阵减法

MatrixNxM operator*(const MatrixNxM& other) const; // 矩阵乘法

MatrixNxM operator*(double scalar) const; // 标量乘法

MatrixNxM operator/(double scalar) const; // 标量除法

// 矩阵变换

MatrixNxM transpose() const; // 转置矩阵

double determinant() const; // 计算行列式(仅方阵)

MatrixNxM inverse() const; // 计算逆矩阵(仅方阵)

// 矩阵性质

bool isSingular() const; // 检查是否奇异

bool isRegular() const; // 检查是否非奇异

bool isSymmetric() const; // 检查是否对称

bool isOrthogonal() const; // 检查是否正交

// 特征值和特征向量

std::vector eigenvalues() const; // 计算特征值

std::vector eigenvectors() const; // 计算特征向量

// 特殊矩阵

static MatrixNxM identity(size_t n); // 创建n阶单位矩阵

static MatrixNxM zero(size_t rows, size_t cols); // 创建零矩阵

static MatrixNxM rotation2D(double theta); // 创建2D旋转矩阵

static MatrixNxM rotation3D(double theta, char axis); // 创建3D旋转矩阵

static MatrixNxM scaling(const std::vector& factors); // 创建缩放矩阵

// 输出运算符

friend std::ostream& operator<<(std::ostream& os, const MatrixNxM& m);

private:

std::vector> data; // 矩阵数据

size_t n; // 行数

size_t m; // 列数

// 辅助函数

void checkDimensions(const MatrixNxM& other, const char* operation) const;

void checkSquare(const char* operation) const;

double minor(size_t row, size_t col) const; // 计算余子式

double cofactor(size_t row, size_t col) const; // 计算代数余子式

};

} // namespace linear_algebra

} // namespace math

#endif // MATRIXNXM_H

2.2 实现文件 (matrixnxm.cpp)

#include "matrixnxm.h"

#include

#include

namespace math {

namespace linear_algebra {

// 默认构造函数

MatrixNxM::MatrixNxM() : n(0), m(0) {}

// 创建指定维度的零矩阵

MatrixNxM::MatrixNxM(size_t rows, size_t cols) : n(rows), m(cols) {

data.resize(n, std::vector(m, 0.0));

}

// 从二维数组初始化

MatrixNxM::MatrixNxM(const std::vector>& data)

: data(data), n(data.size()), m(data.empty() ? 0 : data[0].size()) {

// 检查数据有效性

for (const auto& row : data) {

if (row.size() != m) {

throw std::invalid_argument("Invalid matrix dimensions");

}

}

}

// 获取行数

size_t MatrixNxM::rows() const {

return n;

}

// 获取列数

size_t MatrixNxM::cols() const {

return m;

}

// 检查是否为方阵

bool MatrixNxM::isSquare() const {

return n == m;

}

// 访问元素

double& MatrixNxM::operator()(size_t i, size_t j) {

if (i >= n || j >= m) {

throw std::out_of_range("Matrix index out of range");

}

return data[i][j];

}

// 常量访问元素

const double& MatrixNxM::operator()(size_t i, size_t j) const {

if (i >= n || j >= m) {

throw std::out_of_range("Matrix index out of range");

}

return data[i][j];

}

// 检查维度

void MatrixNxM::checkDimensions(const MatrixNxM& other, const char* operation) const {

if (n != other.n || m != other.m) {

throw std::invalid_argument(

std::string("Matrix dimensions do not match for ") + operation);

}

}

// 检查是否为方阵

void MatrixNxM::checkSquare(const char* operation) const {

if (!isSquare()) {

throw std::invalid_argument(

std::string("Matrix must be square for ") + operation);

}

}

// 矩阵加法

MatrixNxM MatrixNxM::operator+(const MatrixNxM& other) const {

checkDimensions(other, "addition");

MatrixNxM result(n, m);

for (size_t i = 0; i < n; ++i) {

for (size_t j = 0; j < m; ++j) {

result(i, j) = data[i][j] + other(i, j);

}

}

return result;

}

// 矩阵减法

MatrixNxM MatrixNxM::operator-(const MatrixNxM& other) const {

checkDimensions(other, "subtraction");

MatrixNxM result(n, m);

for (size_t i = 0; i < n; ++i) {

for (size_t j = 0; j < m; ++j) {

result(i, j) = data[i][j] - other(i, j);

}

}

return result;

}

// 矩阵乘法

MatrixNxM MatrixNxM::operator*(const MatrixNxM& other) const {

if (m != other.n) {

throw std::invalid_argument("Matrix dimensions do not match for multiplication");

}

MatrixNxM result(n, other.m);

for (size_t i = 0; i < n; ++i) {

for (size_t j = 0; j < other.m; ++j) {

double sum = 0.0;

for (size_t k = 0; k < m; ++k) {

sum += data[i][k] * other(k, j);

}

result(i, j) = sum;

}

}

return result;

}

// 标量乘法

MatrixNxM MatrixNxM::operator*(double scalar) const {

MatrixNxM result(n, m);

for (size_t i = 0; i < n; ++i) {

for (size_t j = 0; j < m; ++j) {

result(i, j) = data[i][j] * scalar;

}

}

return result;

}

// 标量除法

MatrixNxM MatrixNxM::operator/(double scalar) const {

if (std::abs(scalar) < 1e-10) {

throw std::invalid_argument("Division by zero");

}

return *this * (1.0 / scalar);

}

// 转置矩阵

MatrixNxM MatrixNxM::transpose() const {

MatrixNxM result(m, n);

for (size_t i = 0; i < n; ++i) {

for (size_t j = 0; j < m; ++j) {

result(j, i) = data[i][j];

}

}

return result;

}

// 计算余子式

double MatrixNxM::minor(size_t row, size_t col) const {

checkSquare("minor calculation");

if (row >= n || col >= m) {

throw std::out_of_range("Row or column index out of range");

}

// 创建子矩阵

std::vector> subdata(n - 1, std::vector(m - 1));

size_t sub_i = 0;

for (size_t i = 0; i < n; ++i) {

if (i == row) continue;

size_t sub_j = 0;

for (size_t j = 0; j < m; ++j) {

if (j == col) continue;

subdata[sub_i][sub_j] = data[i][j];

++sub_j;

}

++sub_i;

}

return MatrixNxM(subdata).determinant();

}

// 计算代数余子式

double MatrixNxM::cofactor(size_t row, size_t col) const {

double minor_value = minor(row, col);

return ((row + col) % 2 == 0) ? minor_value : -minor_value;

}

// 计算行列式

double MatrixNxM::determinant() const {

checkSquare("determinant calculation");

if (n == 1) {

return data[0][0];

}

if (n == 2) {

return data[0][0] * data[1][1] - data[0][1] * data[1][0];

}

if (n == 3) {

return data[0][0] * data[1][1] * data[2][2] +

data[0][1] * data[1][2] * data[2][0] +

data[0][2] * data[1][0] * data[2][1] -

data[0][2] * data[1][1] * data[2][0] -

data[0][0] * data[1][2] * data[2][1] -

data[0][1] * data[1][0] * data[2][2];

}

// 对于n>3的情况,使用拉普拉斯展开

double det = 0.0;

for (size_t j = 0; j < m; ++j) {

det += data[0][j] * cofactor(0, j);

}

return det;

}

// 计算逆矩阵

MatrixNxM MatrixNxM::inverse() const {

checkSquare("inverse calculation");

double det = determinant();

if (std::abs(det) < 1e-10) {

throw std::runtime_error("Matrix is singular");

}

MatrixNxM result(n, n);

for (size_t i = 0; i < n; ++i) {

for (size_t j = 0; j < n; ++j) {

result(i, j) = cofactor(j, i) / det; // 注意:转置了余子式矩阵

}

}

return result;

}

// 检查是否奇异

bool MatrixNxM::isSingular() const {

return !isSquare() || std::abs(determinant()) < 1e-10;

}

// 检查是否非奇异

bool MatrixNxM::isRegular() const {

return !isSingular();

}

// 检查是否对称

bool MatrixNxM::isSymmetric() const {

if (!isSquare()) return false;

for (size_t i = 0; i < n; ++i) {

for (size_t j = i + 1; j < m; ++j) {

if (std::abs(data[i][j] - data[j][i]) > 1e-10) {

return false;

}

}

}

return true;

}

// 检查是否正交

bool MatrixNxM::isOrthogonal() const {

if (!isSquare()) return false;

MatrixNxM transposed = transpose();

MatrixNxM product = *this * transposed;

return product.isSymmetric() && std::abs(product.determinant() - 1.0) < 1e-10;

}

// 创建单位矩阵

MatrixNxM MatrixNxM::identity(size_t n) {

MatrixNxM result(n, n);

for (size_t i = 0; i < n; ++i) {

result(i, i) = 1.0;

}

return result;

}

// 创建零矩阵

MatrixNxM MatrixNxM::zero(size_t rows, size_t cols) {

return MatrixNxM(rows, cols);

}

// 创建2D旋转矩阵

MatrixNxM MatrixNxM::rotation2D(double theta) {

MatrixNxM result(2, 2);

double cos_theta = std::cos(theta);

double sin_theta = std::sin(theta);

result(0, 0) = cos_theta;

result(0, 1) = -sin_theta;

result(1, 0) = sin_theta;

result(1, 1) = cos_theta;

return result;

}

// 创建3D旋转矩阵

MatrixNxM MatrixNxM::rotation3D(double theta, char axis) {

MatrixNxM result(3, 3);

double cos_theta = std::cos(theta);

double sin_theta = std::sin(theta);

switch (axis) {

case 'x':

result(0, 0) = 1.0;

result(1, 1) = cos_theta;

result(1, 2) = -sin_theta;

result(2, 1) = sin_theta;

result(2, 2) = cos_theta;

break;

case 'y':

result(0, 0) = cos_theta;

result(0, 2) = sin_theta;

result(1, 1) = 1.0;

result(2, 0) = -sin_theta;

result(2, 2) = cos_theta;

break;

case 'z':

result(0, 0) = cos_theta;

result(0, 1) = -sin_theta;

result(1, 0) = sin_theta;

result(1, 1) = cos_theta;

result(2, 2) = 1.0;

break;

default:

throw std::invalid_argument("Invalid rotation axis");

}

return result;

}

// 创建缩放矩阵

MatrixNxM MatrixNxM::scaling(const std::vector& factors) {

size_t n = factors.size();

MatrixNxM result(n, n);

for (size_t i = 0; i < n; ++i) {

result(i, i) = factors[i];

}

return result;

}

// 输出运算符

std::ostream& operator<<(std::ostream& os, const MatrixNxM& m) {

os << "Matrix " << m.n << "x" << m.m << ":\n";

for (size_t i = 0; i < m.n; ++i) {

os << "| ";

for (size_t j = 0; j < m.m; ++j) {

os << m.data[i][j] << " ";

}

os << "|\n";

}

return os;

}

} // namespace linear_algebra

} // namespace math

3. 使用示例

3.1 基本运算

#include "matrixnxm.h"

#include

using namespace math::linear_algebra;

int main() {

// 创建矩阵

std::vector> data1 = {

{1.0, 2.0, 3.0},

{4.0, 5.0, 6.0}

};

std::vector> data2 = {

{7.0, 8.0},

{9.0, 10.0},

{11.0, 12.0}

};

MatrixNxM m1(data1);

MatrixNxM m2(data2);

// 矩阵运算

MatrixNxM sum = m1 + m1; // 矩阵加法

MatrixNxM diff = m1 - m1; // 矩阵减法

MatrixNxM product = m1 * m2; // 矩阵乘法

MatrixNxM scaled = m1 * 2.0; // 标量乘法

// 输出结果

std::cout << "m1:\n" << m1 << std::endl;

std::cout << "m2:\n" << m2 << std::endl;

std::cout << "m1 + m1:\n" << sum << std::endl;

std::cout << "m1 - m1:\n" << diff << std::endl;

std::cout << "m1 * m2:\n" << product << std::endl;

std::cout << "m1 * 2:\n" << scaled << std::endl;

return 0;

}

3.2 特殊矩阵

#include "matrixnxm.h"

#include

using namespace math::linear_algebra;

int main() {

// 创建单位矩阵

MatrixNxM identity = MatrixNxM::identity(3);

std::cout << "3x3单位矩阵:\n" << identity << std::endl;

// 创建旋转矩阵

MatrixNxM rot2d = MatrixNxM::rotation2D(M_PI / 4); // 45度旋转

std::cout << "2D旋转矩阵:\n" << rot2d << std::endl;

MatrixNxM rot3d = MatrixNxM::rotation3D(M_PI / 4, 'z'); // 绕z轴旋转45度

std::cout << "3D旋转矩阵:\n" << rot3d << std::endl;

// 创建缩放矩阵

std::vector factors = {2.0, 3.0, 4.0};

MatrixNxM scale = MatrixNxM::scaling(factors);

std::cout << "缩放矩阵:\n" << scale << std::endl;

return 0;

}

4. 编译和运行

4.1 编译

使用提供的Makefile进行编译:

make # 编译所有目标

make test # 运行测试

make demo # 运行示例

make clean # 清理编译文件

4.2 运行测试

./matrixnxm_test

4.3 运行示例

./matrixnxm_demo

5. 注意事项

数值精度

使用适当的误差范围(1e-10)判断矩阵性质注意浮点数计算的精度问题高维矩阵计算可能涉及较大的数值,注意溢出问题

异常处理

处理维度不匹配的情况处理奇异矩阵的情况处理索引越界的情况处理无效的输入数据

性能考虑

矩阵乘法是O(n³)操作行列式计算是O(n!)操作考虑使用并行计算优化性能对于特定维度使用特化实现考虑使用SIMD指令优化计算

使用建议

优先使用成员函数而不是全局函数保持接口的一致性提供清晰的错误信息对于大型矩阵,考虑使用稀疏矩阵实现考虑使用BLAS等优化库

6. 扩展阅读

矩阵运算

矩阵分解(LU、QR、SVD等)特征值分解奇异值分解矩阵范数

应用领域

线性方程组求解最小二乘问题图像处理机器学习计算机图形学控制系统量子力学

相关文章