向量和索引的内积错误
Error in inner product of vectors and index
我在代码中发现了一个错误,无法找出错误。我尝试通过逐步显示每个变量的输出进行调试,但找不到错误。以下是我所拥有的和我想做的:
我有一个矩阵a:
0000
0101
1010
1111
我有一个矩阵B:
10000
21000
30100
41100
20010
21010
40110
41110
30001
41001
30101
41101
40011
41011
40111
41111
矩阵B有16行和5列。矩阵A具有4行和4列。现在我声明一个矩阵C,它有4行和16列。
我想做的是计算B的每一行与a的对应行的内积。我的意思是,B的第一列应该定义我要相乘的a的行。因此,B矩阵实际上也有四维向量,第一个元素对应于A的行。可以说,B的第一列是选择A的行的索引。因为C++从零开始计数,所以我的索引减去1。这是我的代码:
std::vector< std::vector<int> > C(4, std::vector<int>(16));
std::vector<int> index(4);
std::vector<int> vectorA(4);
std::vector<int> vectorB(4);
for( int y = 0; y < 16; y++)
{
for(int i=0; i<4; ++i){
vectorA[i] = A[ B[y][0]-1 ][i];
}
for( int x = 1; x < 4; x++)
{
vectorB[x -1] = B[y][x];
}
C[ B[y][0] -1][index[ B[y][0] -1] ] = inner_product(vectorA.begin(), vectorA.end(), vectorB.begin(), 0);
index[B[y][0]-1] += 1;
}
这导致了我的矩阵C:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
2 2 3 1 2 1 2 2 3 0 0 0 0 0 0 0
前两行是正确的,但第三行和第四行是错误的。正确的解决方案必须是(可能除了第3行和第4行的订购):
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0
4 3 3 2 3 2 3 2 2 0 0 0 0 0 0 0
我的问题在哪里?请帮忙,这让我疯了:(我试着一步一步地显示每个变量,但找不到为什么它是假的
谢谢和问候。
我不得不同意其他评论:您的代码有点令人困惑。您应该通过索引来简化对向量的访问。
您应该做的第一件简单的事情是将B的第一列更改为零。C++中的所有内容都是零基础的。采用它。不要在代码中通过减去一个来调整它。(这并没有获得太多的简单性,但对您的代码来说是症状。)
另一个混淆的来源是,你使用B的第一列作为A的索引。这可能是你想解决的问题的暗示,但它让事情变得不清楚:B的第一行有完全不同的含义,总是以对象按其含义分开的方式编码。
对我来说,最令人困惑的是,我真的不明白你在做什么。内积是指点积,对吧?您有两组向量要计算的点积。这应该会产生一组标量,一个1D向量,而不是2D矩阵。您可以用索引向量做一些特殊的事情,这使得结果成为2D矩阵。但你还没有解释它背后的目的/系统。为什么你需要一个向量作为索引,而不仅仅是一个标量??
Vectorindex是代码中最难看/最复杂的部分。在不知道你在做什么的情况下,我仍然猜测,当你开始在每次迭代中打印出完整的向量索引并检查它是否改变了你期望的方式时,你会发现哪里出了问题。
我不知道OP选择背后的理由是什么,所以我不能正确地评论所提供的代码的设计,但据我所知,示例输入也有一些错误。
给定如图所示的A和B矩阵,A的下一行与B中对应的矩阵的内积总是0:
B[1] { 2, 1, 0, 0, 0 },
row "2" or A[1] is { 0, 1, 0, 1 } <- B[4] { 2, 0, 0, 1, 0 },
B[5] { 2, 1, 0, 1, 0 },
下一行也是如此。只有交换后,才能获得预期的输出,我在代码中就是这样做的。
vectorA
和vectorB
以及相应的复制循环并不是真正必要的,并且可能是错误输出的原因:
for( int x = 1; x < 4; x++)
{ // ^^^^^ this should be <= to reach the last element
vectorB[x -1] = B[y][x];
}
我的代码,带有更新的输入和A和B的直接使用是:
#include <iostream>
#include <vector>
#include <numeric>
using vec_t = std::vector<int>; // I assume a C++11 compliant compiler
using mat_t = std::vector<vec_t>;
using std::cout;
int main() {
mat_t A{
{ 0, 0, 0, 0 },
{ 1, 0, 1, 0 }, // <-- those lines are swapped
{ 0, 1, 0, 1 }, // <--
{ 1, 1, 1, 1 }
};
mat_t B{
{ 1, 0, 0, 0, 0 },
{ 2, 1, 0, 0, 0 },
{ 3, 0, 1, 0, 0 },
{ 4, 1, 1, 0, 0 },
{ 2, 0, 0, 1, 0 },
{ 2, 1, 0, 1, 0 },
{ 4, 0, 1, 1, 0 },
{ 4, 1, 1, 1, 0 },
{ 3, 0, 0, 0, 1 },
{ 4, 1, 0, 0, 1 },
{ 3, 0, 1, 0, 1 },
{ 4, 1, 1, 0, 1 },
{ 4, 0, 0, 1, 1 },
{ 4, 1, 0, 1, 1 },
{ 4, 0, 1, 1, 1 },
{ 4, 1, 1, 1, 1 }
};
mat_t C(4, vec_t(16));
vec_t pos(4);
for ( int i = 0; i < 16; ++i )
{
int row = B[i][0] - 1;
int col = pos[row];
int prod = std::inner_product( A[row].begin(), A[row].end(),
++(B[i].begin()), 0 );
// ^^^ skip the first element
C[row][col] = prod;
if ( prod )
++pos[row];
}
for ( auto & r : C )
{
for ( int x : r ) {
cout << ' ' << x;
}
cout << 'n';
}
return 0;
}
输出为:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0
2 2 3 2 3 2 3 3 4 0 0 0 0 0 0 0
我不知道最后一行的排序是否如预期,但它模仿了OP代码的逻辑。
- 数组索引重载错误
- SIGSEGV, 分段错误. 而 printf() 数组索引的值
- 使用 glvertex4i 传递网格面索引时的顶点着色器错误
- 如何摆脱导入的 make 项目中的 Eclipse 索引器"Type std::... could not be resolved"错误
- 访问特定阵列位置/索引时出现分段错误
- 使用无序映射进行错误索引
- 当我在网格/面中实现索引时,为什么它会返回OpenGl错误
- R 包安装错误:重新定位 0 具有无效的符号索引 11
- 索引 2D 向量时'Reference to type const..'编译错误
- 片段着色器中的"错误:在 GLSL 1.30 及更高版本中禁止使用非常量表达式索引的采样器数组"
- 运行时错误:基0x000000000000溢出到0xffffffffffffffff的指针索引表达式 (basic_st
- 如果我将索引变量更改为零,并且合并函数中的k = 0,则获得合并排序的错误结果
- 队列验证层错误:队列族索引在 pCreateInfo->pQueueCreateInfos 数组中不是唯一的
- 向量下标出的范围错误.即使向量的索引大于访问数据的索引,也会发生误差
- G 4.8.5带负数组索引的循环优化错误
- 分段错误发生在索引离开C++数组边界之后
- 错误:使用索引寻址和 Clang 的指令的操作数无效
- 有没有一种简单的方法可以忽略 c++ 中的索引错误
- 分段错误:为什么这里的数组索引越界了
- 按行、列或随机从数组填充矩阵时出现错误索引问题