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






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


