当前位置: 首页 > news >正文

mxn矩阵学习笔记

mxn矩阵学习笔记

1. 简介

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

2. 代码实现

2.1 头文件 (matrixnxm.h)

#ifndef MATRIXNXM_H
#define MATRIXNXM_H#include <vector>
#include <stdexcept>
#include <iostream>
#include <cmath>namespace math {
namespace linear_algebra {/*** @brief nxm矩阵类* * 这个类实现了nxm矩阵的基本运算,包括:* - 矩阵加减* - 矩阵乘法* - 标量乘法* - 转置* - 行列式(仅方阵)* - 逆矩阵(仅方阵)* - 特征值和特征向量* - 矩阵性质检查*/
class MatrixNxM {
public:// 构造函数MatrixNxM();  // 默认构造函数,创建0x0矩阵MatrixNxM(size_t rows, size_t cols);  // 创建指定维度的零矩阵MatrixNxM(const std::vector<std::vector<double>>& 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<double> eigenvalues() const;  // 计算特征值std::vector<MatrixNxM> 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<double>& factors);  // 创建缩放矩阵// 输出运算符friend std::ostream& operator<<(std::ostream& os, const MatrixNxM& m);private:std::vector<std::vector<double>> 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 <algorithm>
#include <numeric>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<double>(m, 0.0));
}// 从二维数组初始化
MatrixNxM::MatrixNxM(const std::vector<std::vector<double>>& 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<std::vector<double>> subdata(n - 1, std::vector<double>(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<double>& 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 <iostream>using namespace math::linear_algebra;int main() {// 创建矩阵std::vector<std::vector<double>> data1 = {{1.0, 2.0, 3.0},{4.0, 5.0, 6.0}};std::vector<std::vector<double>> 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 <iostream>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<double> 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. 注意事项

  1. 数值精度

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

    • 处理维度不匹配的情况
    • 处理奇异矩阵的情况
    • 处理索引越界的情况
    • 处理无效的输入数据
  3. 性能考虑

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

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

6. 扩展阅读

  1. 矩阵运算

    • 矩阵分解(LU、QR、SVD等)
    • 特征值分解
    • 奇异值分解
    • 矩阵范数
  2. 应用领域

    • 线性方程组求解
    • 最小二乘问题
    • 图像处理
    • 机器学习
    • 计算机图形学
    • 控制系统
    • 量子力学
http://www.dtcms.com/a/302546.html

相关文章:

  • 使用Python制造扫雷游戏
  • Marc 非线性仿真复杂,企业如何保障许可证公平与高效使用?
  • (AC)储值购物
  • Android中主线程、ActivityThread、ApplicationThread的区别
  • 【氮化镓】GaN同质外延p-i-n二极管中星形与三角形扩展表面缺陷的电子特性
  • Python 实现服务器自动故障处理工具:从监控到自愈的完整方案
  • 日志分析-windows日志分析base--笔记ing
  • lesson26-2:使用Tkinter打造简易画图软件优化版
  • 深入解析MIPI C-PHY (五) MIPI C-PHY 与 A-PHY 的对比分析
  • 重生之我在暑假学习微服务第三天《Docker-上篇》
  • 【Unity笔记】Unity Camera.cullingMask 使用指南:Layer 精准控制、XR 多视图与性能提升
  • ERC20 和 XCM Precompile|详解背后技术逻辑
  • 学习Python中Selenium模块的基本用法(2:下载浏览器驱动)
  • js的学习2
  • JavaScript:数组常用操作方法的总结表格
  • Webhook技术深度解析:从原理到实现全指南
  • Item17:以独立语句将newed对象置入智能指针
  • MDM五十万台设备高并发场景解决方案【后台管理】
  • Taro 位置相关 API 介绍
  • C# 状态机以及状态机编程模式
  • Java设计模式-通俗举例
  • 【智慧物联网平台】编译jar环境 Linux 系统Maven 安装——仙盟创梦IDE
  • Leaflet 综合案例-聚类图层控制
  • django ManyToManyField 如何添加数据
  • Django缓存机制详解:从配置到实战应用
  • MGRE 实验
  • Django 视图详解(View):处理请求与返回响应的核心
  • Linux IPC实战:管道与命名管道的进程对话术
  • 语音识别数据增强
  • llama系列