矩阵乘法算法
Matrix multiplication algorithm
本文关键字:算法 更新时间:2023-10-16
我有mat2,mat3和mat4类,分别表示2x2,3x3和4x4矩阵。我正在尝试通过重载*=
运算符来实现乘法算法。以 mat4 为例,下面是声明:
mat4& operator*=(const mat4 &m);
乘法算法将返回对调用对象的引用。这意味着它将返回对this
的引用。乘法算法的实现定义如下:
mat4& mat4::operator *=(const mat4& m)
{
for (uint i = 0; i < row(); i++)
{
for (uint j = 0; j < col(); j++)
{
for (uint k = 0; k < m.col(); k++)
{
data[i][j] += (data[i][k] * m.data[k][j]);
}
}
}
return *this;
}
其中uint
是unsigned int
的类型定义。因为运算符重载是一个类函数,所以不需要有一个 lhs 矩阵,而是提供一个我称之为 m
的 rhs 矩阵。在这种情况下,函数 row()
和 col()
将始终返回 4,因为它是一个 mat4x4;这些函数是 MAT4 类的一部分。属性data
是具有固定大小的浮点数的二维数组。问题是这个算法没有产生正确的结果。例如:
mat4 m1(1.0, 0.0, 0.0, 30.0,
0.0, 1.0, 0.0, 30.0,
0.0, 0.0, 1.0, 30.0,
0.0, 0.0, 0.0, 1.0);
mat4 m2(23.0, 21.0, 0.0, 1.0,
10.0, 9.0, 1.0, 0.0,
1.0, 2.0, 0.0, 0.0,
3.0, 2.0, 9.0, 9.0);
auto result = m1 * m2;
cout << result << endl;
正如您所知,我也重载了<<
运算符,以使矩阵的cout
成为可能且容易。正如您也知道的那样,我的矩阵是列主矩阵,因为我打算将它们与 OpenGL 一起使用。因此,像 m1.data[3][2]
这样的东西意味着第 4 列,第 3 行。结果几乎不是它应该的样子:
mat4 =
[
24 5040 5040 54
10 2110 2110 40
1 212 213 31
0 0 0 1
]
我的问题是乘法算法不起作用并产生正确的结果。如何更正算法,使其作为矩阵乘法的结果产生正确的结果?
我目前重载*
运算符,如下所示:
mat4 mat4::operator *(const mat4& m) const
{
mat4 result = *this;
result *= m;
return result;
}
这利用了*=
运算符过载。不幸的是,*
运算符过载也不起作用。
问题是你正在写入与你正在读取的相同的矩阵。这意味着您在计算中使用了结果矩阵中的某些值,而不是原始矩阵中的值。
要解决此问题,请创建一个临时的二维数组,您可以写入该数组:
mat4& mat4::operator *=(const mat4& m)
{
float buffer[4][4]; // Temporary matrix
for (uint i = 0; i < row(); i++)
{
for (uint j = 0; j < col(); j++)
{
// You might want to set the values in the buffer to 0 just in case:
buffer[i][j] = 0.0f;
for (uint k = 0; k < m.col(); k++)
{
buffer[i][j] += data[i][k] * m.data[k][j];
}
}
}
// Now that all the values of the new matrix have been calculated you can write to data
for (uint i = 0; i < row(); i++)
{
for (uint j = 0; j < col(); j++)
{
data[i][j] = buffer[i][j];
}
}
return *this;
}
你的问题是你在(*this)
的data
字段中弄乱了数据(你在计算过程中读取和写入同一个变量),所以你有错误的数据。
您需要使用临时矩阵,然后在计算后复制其数据:
mat2& operator*=(const mat2 &m)
{
// I set all the elements of the temp_data to 0. It is very important
array<array<int, 2>,2> temp_data = {{{0,0},{0,0}}};
for (uint i = 0; i < row(); i++)
{
for (uint j = 0; j < col(); j++)
{
for (uint k = 0; k < m.col(); k++)
{
temp_data[i][j] += (data[i][k] * m.data[k][j]);
}
}
}
this->data = temp_data;
return *this;
}
使用示例:
int main()
{
array<array<int, 2>,2> data1 = {{{1,0},{0,1}}};
array<array<int, 2>,2> data2 = {{{1,2},{3,4}}};
mat2 m1;
m1.data = data1;
mat2 m2;
m2.data = data2;
m1 *= m2;
for (auto el: m1.data) {
for (auto ele : el) {
cout << ele << " ";
}
cout << endl;
}
return 0;
}
输出:
1 2
3 4
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- KMP算法和LPS表构造的运行时间
- 为什么我的排序算法会更改数组值
- 求最大元素位置的分治算法
- 具有非整数边容量的最大流量的Dinic算法
- 到连接组件算法的问题(递归)
- STL算法函数在多个一维容器上的使用
- 读取最后一行代码算法 - c++ 时出现问题
- 括号更改 O(n) 算法
- std::unordered_map 搜索算法是如何实现的?
- 如何实现高效的算法来计算大型数据集的多个不同值?
- 如何在 Mac 上使用 c++17 并行标准库算法?