简体   繁体   English

C ++-矩阵减法

[英]C++ - Matrix subtraction

I'm doing some very basic Linear Algebra and I'm probably missing the point completely here. 我正在做一些非常基本的线性代数,而我可能在这里完全没了重点。

Let's say I have the following matrices: 假设我有以下矩阵:

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

Expected output: 预期产量:

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

Actual output: 实际输出:

0 0 
0 0 
2 4 
-1 0 
2 3 

Here is the code: 这是代码:

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;
    }

The problem being is that, the following should iterate over 4 times, calculating the 4 matrices, and the final resulting 2D vector should only contain 2 values. 问题是,以下代码应迭代4次,计算4个矩阵,最终的2D向量应仅包含2个值。

I'm probably missing something stupid. 我可能想念一些愚蠢的东西。

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

Do you have a debugger? 你有调试器吗? It's really important to learn how to step through code like this, have someone show you, or find a tutorial. 学习如何逐步执行此类代码,请他人演示或查找教程非常重要。 Stepping through this code in a debugger would have made it obvious what was going on to you. 在调试器中单步执行此代码将使您显而易见。

Luckily, the code is REALLY easy to fix: 幸运的是,该代码非常易于修复:

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]));
}

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

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]);
}

This loop operates on two elements of values , so the counter needs to increase by 2 per iteration. 此循环对values两个元素进行操作,因此每次迭代计数器需要增加2。 otherwise you would subtract v1-v2 , v2-v3 , v3-v4 and so on. 否则,您将减去v1-v2v2-v3v3-v4等。 Also there is no need to determine the vector size prior to the push_back (and it actually dangerous, because the index is likely out-of-bounds before the element is pushed back). 同样,也无需在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]);
}

As pointed out by others v.resize(2); 正如其他人所指出的v.resize(2); shouldn't be there either because it just adds two empty elements initially, which you don't want. 也不应该在那里,因为它最初只是添加了两个不需要的空元素。

v.resize(2);

I don't know what you were expecting the above to do, but this (coupled with the code below) is what is responsible for those first two lines of output. 我不知道您期望上述操作是什么,但这(与下面的代码一起)是负责输出的前两行的原因。

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

I don't know what you were expecting the above to do, but this (coupled with the code above) is what is responsible for those first two lines of output. 我不知道您期望上述操作是什么,但这(与上面的代码一起)是负责输出的前两行的原因。

Here's what's happening: Your first resize (the resize outside the loop) populates v with two empty vectors. 这是发生了什么:您的第一个调整大小(循环外部的调整大小)用两个空向量填充v The first two passes through the loop populate v[0] and v[1] as vectors of doubles with two elements that are both zero. 前两个通过循环,将v[0]v[1]填充为具有两个均为零的元素的double的向量。

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

This will ultimately add three more elements to v , one being {5,8}-{3, 4}={2,4}, the next being {3,4}-{4,4}={-1,0}, and the last being {4,4}-{2,1}={2,3}. 最终,这将为v添加另外三个元素,一个元素为{5,8}-{3,4} = {2,4},另一个元素为{3,4}-{4,4} = {-1,0 },最后一个是{4,4}-{2,1} = {2,3}。 So your output should be 所以你的输出应该是

0 0
0 0
2 4
-1 0
2 3

To get rid of those first two lines, simply delete the two calls to resize . 要摆脱前两行,只需删除两个调用resize To get rid of the penultimate line (that -1 0 that is between the two desired lines of output), change your loop increment from one ( i++ ) to two ( i += 2 ). 要摆脱倒数第二行( -1 0在两条期望的输出行之间),请将循环增量从一( i++ )更改为两( i += 2 )。

This output 此输出

    0 0 
    0 0 
    2 4 
   -1 0 
    2 3 

can be explained very simply 可以很简单地解释

At first using method resize 首先使用方法调整大小

v.resize(2);

you added two empty std::vector in vector v. 您在向量v中添加了两个空的std :: vector。

Then in loop 然后循环

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]);
}

you resized each of them. 您调整了每一个的大小。 So now v[0] and v[1] are 所以现在v [0]和v [1]是

0 0 
0 0 

And then you get subtraction of 然后你减去

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

After that vector v was appended with 在向量v之后附加

    2 4 
   -1 0 
    2 3 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM