C ++ - 矩阵减法

时间:2014-02-20 00:06:53

标签: c++ matrix linear-algebra

我正在做一些非常基本的线性代数,我可能完全忽略了这一点。

假设我有以下矩阵:

v1 = [5, 8]
v2 = [3, 4]
v3 = [4, 4]
v4 = [2, 1]

预期产出:

M1 = [5 - 3, 8 - 4] = [2, 4] 
M2 = [4 - 2, 4 - 1] = [2, 3]

实际输出:

0 0 
0 0 
2 4 
-1 0 
2 3 

以下是代码:

std::vector<double> calculate(std::vector<double> values, std::vector<double> values2)
{
    std::vector<double> vel(2, 0);

    for(unsigned i=0; (i < values.size()); i++)
    {
        vel[i] = values[i] - values2[i];
    }

    return vel;
}



  std::vector<std::vector<double> > values = { {5,8}, {3, 4}, {4, 4}, {2, 1}};

    std::vector<std::vector<double> > v;

    v.resize(2);

    for(unsigned i=0; (i < values.size()-1); i++)
    {   
        v[i].resize(2);
        v.push_back(calculate(values[i], values[i + 1]));
        //v[i] = calculate(values[i], values[i + 1]);
    }

    for(unsigned i=0; (i < v.size()); i++)
    {
        for(unsigned j=0; (j < v[i].size()); j++)
        {
            std::cout << v[i][j] << " ";
        }
        std::cout << std::endl;
    }

问题在于,以下内容应迭代4次,计算4个矩阵,最终生成的2D向量应仅包含2个值。

我可能错过了一些愚蠢的事情。

4 个答案:

答案 0 :(得分:2)

v.resize(2); // now it contains `{{} {}}`.
for(unsigned i=0; (i < values.size()-1); i++) //for each input except the last (3 iterations)
                    //starting with {5,8} and {3,4}
    v[i].resize(2); //resize one of the vectors already in v to 2 
                    //now v contains {{0,0}, {}
    v.push_back(calculate(values[i], values[i + 1])); //push back the calculations
                    //now v contains {{0,0}, {}, {2,4}}
for(............. (i < values.size()-1); i++)
                    //next the middle pair of inputs  {3,4} and {4,4}
    v[i].resize(2); //resize one of the vectors already in v to 2 
                    //now v contains {{0,0}, {0,0}, {2,4}}
    v.push_back(calculate(values[i], values[i + 1])); //push back the calculations
                    //now v contains {{0,0}, {0,0}, {2,4}, {-1,0}}
for(............. (i < values.size()-1); i++)
                    //finally the last pair of inputs  {4,4} and {2,1}
    v[i].resize(2); //resize the {2,4} to 2, but it was already two
                    //now v contains {{0,0}, {0,0}, {2,4}, {-1,0}}
    v.push_back(calculate(values[i], values[i + 1])); //push back the calculations
                    //now v contains {{0,0}, {0,0}, {2,4}, {-1,0}, {2,3}}
for(............. (i < values.size()-1); ....) //done iterating

你有调试器吗?了解如何逐步执行此类代码,让某人向您展示或查找教程非常重要。在调试器中逐步执行此代码可以明显地发生了什么。

幸运的是,代码很容易修复:

std::vector<std::vector<double> > v;

for(unsigned i=0; i<values.size()-1; i+=2) //NOTE: i+=2!!!
{   
    v.push_back(calculate(values[i], values[i + 1]));
}

证明:http://coliru.stacked-crooked.com/a/827a0183f1e7c582

答案 1 :(得分:1)

for(unsigned i=0; (i < values.size()-1); i++)
{   
    v[i].resize(2);
    v.push_back(calculate(values[i], values[i + 1]));
    //v[i] = calculate(values[i], values[i + 1]);
}

此循环对values的两个元素进行操作,因此计数器每次迭代需要增加2。否则你会减去v1-v2v2-v3v3-v4等等。此外,不需要在push_back之前确定向量大小(实际上它很危险,因为索引在元素被推回之前可能超出了界限)。

for(unsigned i=0; (i < values.size()-1); i+=2)
{   
    //v[i].resize(2);
    v.push_back(calculate(values[i], values[i + 1]));
    //v[i] = calculate(values[i], values[i + 1]);
}

正如其他人所指出的那样v.resize(2);也不应该存在,因为它最初只添加了两个空元素,这是你不想要的。

答案 2 :(得分:1)

v.resize(2);

我不知道你对上述事情的期望是什么,但是这个(加上下面的代码)是前两行输出的原因。

for(unsigned i=0; (i < values.size()-1); i++)
{   
    v[i].resize(2);

我不知道你对上述事情的期望是什么,但是这个(加上上面的代码)是前两行输出的原因。

这是发生了什么:你的第一次调整大小(循环外的调整大小)用两个空向量填充v。前两个遍历循环填充v[0]v[1]作为双精度矢量,两个元素都为零。

    v.push_back(calculate(values[i], values[i + 1]));

这将最终为v增加三个元素,一个是{5,8} - {3,4} = {2,4},下一个是{3,4} - {4,4 } = { - 1,0},最后一个是{4,4} - {2,1} = {2,3}。所以你的输出应该是

0 0
0 0
2 4
-1 0
2 3

要删除前两行,只需删除对resize的两次调用。要摆脱倒数第二行(两个所需输出行之间的-1 0),将循环增量从一(i++)更改为两(i += 2)。

答案 3 :(得分:0)

此输出

    0 0 
    0 0 
    2 4 
   -1 0 
    2 3 

可以非常简单地解释

首先使用方法调整大小

v.resize(2);

你在向量v。

中添加了两个空的std :: vector

然后循环

for(unsigned i=0; (i < values.size()-1); i++)
{   
    v[i].resize(2);
    v.push_back(calculate(values[i], values[i + 1]));
    //v[i] = calculate(values[i], values[i + 1]);
}

你调整了每个人的大小。所以现在v [0]和v [1]是

0 0 
0 0 

然后你会减去

values[0] - values[1]
values[1] - values[2]
values[2] - values[3]

在该向量v后附加

    2 4 
   -1 0 
    2 3 
相关问题