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






4.53/5 (15投票s)
一个派生自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*3operator+=(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 错误。 CMatrixHelper
的operator=
现在将所有成员变量复制到目标对象中。
2002年7月2日
- 修复了
CMatrix::Invert()
中的一个小拼写错误。感谢 Jamie Plowman 发现它。 - 正如建议的,我将
CMatrixHelper
类的构造函数设为protected
,并使CMatrix
成为其friend
,这样只有CMatrix
才能构造对象,用户不能。
尽情享用!