C++列主序1D数组递归矩阵乘法结果顺序错误修复求助
修复列主序1D数组存储的递归矩阵乘法
问题分析
你的递归矩阵乘法结果元素顺序异常,核心原因是列主序存储下的子矩阵合并逻辑错误:
- 原
equals函数直接将子矩阵整体追加到结果中,不符合列主序“按列优先存储整个矩阵”的规则; - 递归函数中合并子矩阵的顺序(C11→C12→C21→C22)错误,正确的合并应按大矩阵的列组合,前m列由C11和C21的对应列拼接,后m列由C12和C22的对应列拼接。
经确认,matrix_partitioner函数的索引逻辑是正确的,能正确提取列主序存储的子矩阵。
修复方案
1. 替换合并函数,实现列主序子矩阵合并
新增merge_blocks函数,严格按列优先规则合并四个子矩阵:
vector<double> merge_blocks(int m, vector<double>& C11, vector<double>& C12, vector<double>& C21, vector<double>& C22) { int n = 2 * m; vector<double> C(n * n); // 合并前m列:C11的列 + C21的列 for (int col = 0; col < m; ++col) { // 填充C11的当前列到大矩阵对应列的上半部分 for (int i = 0; i < m; ++i) { C[i + col * n] = C11[i + col * m]; } // 填充C21的当前列到大矩阵对应列的下半部分 for (int i = 0; i < m; ++i) { C[m + i + col * n] = C21[i + col * m]; } } // 合并后m列:C12的列 + C22的列 for (int col = 0; col < m; ++col) { int big_col = m + col; // 填充C12的当前列到大矩阵对应列的上半部分 for (int i = 0; i < m; ++i) { C[i + big_col * n] = C12[i + col * m]; } // 填充C22的当前列到大矩阵对应列的下半部分 for (int i = 0; i < m; ++i) { C[m + i + big_col * n] = C22[i + col * m]; } } return C; }
2. 修改递归主函数,使用正确的合并逻辑
替换原equals的合并方式,调用merge_blocks组合子矩阵:
vector<double> recursive_mult(int n, vector<double> A, vector<double> B) { vector<double> C; if (n == 1) { C.push_back(A[0] * B[0]); } else { int m = n / 2; // 计算四个子矩阵乘积 auto C11 = recursive_mult(m, matrix_partitioner(m, 0, A), matrix_partitioner(m, 0, B)) + recursive_mult(m, matrix_partitioner(m, 1, A), matrix_partitioner(m, 2, B)); auto C12 = recursive_mult(m, matrix_partitioner(m, 0, A), matrix_partitioner(m, 1, B)) + recursive_mult(m, matrix_partitioner(m, 1, A), matrix_partitioner(m, 3, B)); auto C21 = recursive_mult(m, matrix_partitioner(m, 2, A), matrix_partitioner(m, 0, B)) + recursive_mult(m, matrix_partitioner(m, 3, A), matrix_partitioner(m, 2, B)); auto C22 = recursive_mult(m, matrix_partitioner(m, 2, A), matrix_partitioner(m, 1, B)) + recursive_mult(m, matrix_partitioner(m, 3, A), matrix_partitioner(m, 3, B)); // 按列主序合并子矩阵 C = merge_blocks(m, C11, C12, C21, C22); } return C; }
3. 确认矩阵加法重载正确性
确保重载的+运算符正确实现列主序矩阵的逐元素相加:
vector<double> operator+(vector<double> A, vector<double> B) { vector<double> C(A.size()); for (size_t i = 0; i < A.size(); ++i) { C[i] = A[i] + B[i]; } return C; }
验证结果
修复后,递归法计算结果将与迭代法完全一致:
Recursive | 250 260 270 280 | | 618 644 670 696 | | 986 1028 1070 1112 | | 1354 1412 1470 1528 |
内容的提问来源于stack exchange,提问作者Banthrall
相关产品推荐
相关产品推荐

