65.9K
CodeProject 正在变化。 阅读更多。
Home

一个具有序列化和高级输入/输出功能的矩阵类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.53/5 (15投票s)

2002年6月27日

CPOL

5分钟阅读

viewsIcon

314759

downloadIcon

3473

一个派生自CObject的矩阵类,具有序列化和运算符重载功能。

概述

矩阵,你讨厌它们吗?我讨厌,而且它们在我工作的项目中随处可见。因此,随着时间的推移,我开发了一个类 CMatrix 来处理我们所有需要的东西,以及一些我期望将来需要的东西。

数据处理方式

首先,让我们概述一下该类如何处理数据。矩阵数据分配在一个由 double 类型扁平数组中,数组末尾带有一个整数引用计数器。由于矩阵是动态的,我们使用引用计数系统来避免在将一个矩阵赋值/复制到另一个矩阵时效率下降。两个对象可以指向相同的数据,并且只有当其中一个对象改变数据时,它们才会分离,此时它会获得自己的一份数据。数据只会在最后一个引用被删除时才会被删除。这对于通过函数调用按值返回的对象以及通过 operator= 赋值的对象具有优势,因为与 new/复制操作相比,赋值指针的开销很小。

序列化

CMatrix 类直接继承自 CObject,并完全兼容序列化。

CMatrixHelper

添加了一个小型辅助类,以实现模拟的 CMatrix::operator[][]。我无耻地借鉴了 Alex Chirokov 的文章 具有 [][] 索引的二维矩阵容器。这是一种很好的做法。另请注意,您不应在自己的代码中创建此类型的任何对象。它仅用于此目的。

健壮性

在 DEBUG 模式下,代码编译时没有警告/错误,并且在整个过程中都有广泛的 ASSERTion 检查,因此它应该能够捕获您(或我)在代码中遇到的任何问题。大部分功能都经过了彻底检查,但我仍建议您检查结果,以防万一!

构造函数

您可以使用以下方法构造矩阵对象

  • CMatrix() 构造一个 1 * 1 的数组,这是默认构造函数。
  • CMatrix(CMatrix& other) 拷贝构造函数
  • CMatrix(nCols, nRows) 构造一个 nCols * nRows 维度的矩阵。所有数据均为 0。
  • CMatrix(size, diagonal) 构造一个带有或不带有对角线为 1 的方阵。
  • CMatrix(VARIANT) 从一个二维 SAFEARRAY 变体构造一个 CMatrix 对象。

注意,任何未初始化的矩阵元素在构造时都将设置为 0。

重载运算符

以下运算符已被重载

  • operator=(CMatrix) 用于标准赋值。

算术运算

  • operator+(CMatrix) 将两个矩阵相加,它们必须具有相同的大小
  • operator-(CMatrix) 从一个矩阵中减去另一个矩阵,它们必须具有相同的大小
  • operator*(CMatrix) 将两个矩阵相乘,两个内维必须相同,例如 3*2 乘以 2*3
  • operator+=(CMatrix) 将一个矩阵添加到当前矩阵,必须具有相同的维度。
  • operator-=(CMatrix) 从当前矩阵中减去一个矩阵,必须具有相同的维度。
  • operator*=(CMatrix) 将当前矩阵乘以另一个矩阵
  • operator*=(double) 将所有矩阵元素乘以给定值
  • operator*(CMatrix, double) 将所有元素乘以给定值,返回一个新矩阵

比较

  • operator==(CMatrix) 用于矩阵比较,如果相同则返回 true,否则返回 false

元素访问

  • operator[](int) 与类 CMatrixHelper 配合使用,模拟 operator[][]

获取/设置函数

提供了两个标准访问函数。

  • GetElement(nCol, nRow) 返回给定元素值
  • SetElement(nCol, nRow, value) 将给定元素设置为不同的值

其他矩阵函数

  • GetNumColumns() 返回矩阵的列维度
  • GetNumRows() 返回矩阵的行维度
  • SumColumn(column) 返回给定列中所有元素的总和
  • SumRow(row) 返回给定行中所有元素的总和
  • SumColumnSquared(column)SumColumn() 相同,但返回值是平方的
  • SumRowSquared(row)SumRow() 相同,但返回值是平方的
  • GetNumericRange(min, max) 返回矩阵中元素的最小值和最大值
  • GetSafeArray() 返回一个 VARIANT,其中包含 CMatrix 数据的副本,存储在 SAFEARRAY 中。请注意,除非您将 VARIANT 传递给不同的程序(例如 COM 组件/VB),否则应使用 VariantClear(var) 清除 VARIANT,因为那将成为它们的责任。
  • CopyToClipboard()CMatrix 数据以 CSV 文本形式放入剪贴板,调试等时使用
  • WriteAsCSVFile(filename) 将矩阵写入 CSV 文件
  • ReadFromCSVFile(const CString& filename) 从 CSV 文件创建一个新矩阵。
  • Dump() 将矩阵内容跟踪到调试流
  • AssertValid() 如果对象处于无效状态,则断言

转置

  • GetTransposed() 返回一个新的矩阵,它是被调用矩阵的转置
  • Transpose() 转置当前矩阵

求逆

  • GetInverted() 返回当前矩阵的逆矩阵
  • Invert() 逆转当前矩阵

协变 (A' * A)

  • Covariant() 返回当前矩阵的协方差

归一化

  • GetNormalised(min, max) 返回所有值介于 min 和 max 之间的矩阵
  • Normalise(min, max) 将矩阵中所有值归一化到 min 和 max 之间

串联

  • GetConcatinatedColumns(CMatrix) 返回一个新矩阵,其中包含附加在右侧的另一个矩阵
  • ConcatinateColumns(CMatrix) 将附加列连接到当前矩阵
  • GetConcatenatedRows(CMatrix) 返回一个新矩阵,其中包含附加在当前矩阵底部的另一个矩阵
  • ConcatinateRows(CMatrix) 将附加行连接到当前矩阵
  • AddColumn(double*) 向当前矩阵添加新列
  • AddRow(double*) 向当前矩阵添加新行

提取/替换

  • ExtractSubMatrix(x, y, x_size, y_size) 从大矩阵中提取子矩阵
  • SetSubMatrix(x, y, CMatrix) 用另一个矩阵的元素替换大矩阵的元素
  • ExtractDiagonal() 返回一个 x * 1 矩阵,其中包含对角线上的值 - 仅适用于方阵
  • GetSquareMatrix() 通过跳过行/列使矩阵变为方形,返回较小维度的一个方形矩阵
  • MakeSquare() 通过跳过行/列使当前矩阵变为方形

其他注意事项

所有处理矩阵数据分配/释放和引用计数的代码都没有在此类的接口中介绍,因为它们都是 private 函数。您可以在源代码注释中查看文档。(哇,注释……:-D)

如果您发现任何错误或对该类有任何增强功能,我将很高兴您能将它们传递给我,我将努力使该类在此处保持完全最新。

更新

2002年8月13日

  • 修复了在使用 operator[][] 进行元素读取访问时,CMatrixHelper 的一个小问题,通过将返回对象设为 const
  • 修复了 ExtractSubMatrix 中一个无效的 ASSERTion 错误。
  • CMatrixHelperoperator= 现在将所有成员变量复制到目标对象中。

2002年7月2日

  • 修复了 CMatrix::Invert() 中的一个小拼写错误。感谢 Jamie Plowman 发现它。
  • 正如建议的,我将 CMatrixHelper 类的构造函数设为 protected,并使 CMatrix 成为其 friend,这样只有 CMatrix 才能构造对象,用户不能。

尽情享用!

© . All rights reserved.