Marvin
Marvin

Reputation: 51

c++ vector not updating in nested for loop

So I create and initialize a vector (of size nmask+3) to 0, and I assign an initial value to one of the elements. I then make a for loop that goes through the first nmask elements of the vector and assigns to each element an average of 26 other elements in the vector (defined by the 4D int array voxt, which contains vector addresses).

My problem is that when I check the values of nonzero elements in my vector (phi) within the nested loop (the first cout), the values are fine and what I expect. However, when the loop finishes going through all nmask elements (for (int i= 0; i<nmask; i++) exits), I check the nonzero elements of phi again, and they are all lost (reset to 0) except for the last non-zero element (and element tvox which is manually set to 1).

I feel that since phi is initialized outside of all the loops, there should be no resetting of values going on, and that any updated elements within the nested loop should remain updated upon exit of the loop. Any ideas as to what is going on / how to fix this? Code is below; I tried to comment in a sense of the outputs I'm getting. Thanks in advance.

vector<double> phi(nmask+3, 0); //vector with nmask+3 elements all set to 0 (nmask = 13622)
    phi[tvox]= 1; //tvox is predefined address (7666)

    for (int n= 0; n<1; n++)
    {
        vector<double> tempPhi(phi); //copy phi to tempPhi

        for (int i= 0; i<nmask; i++)
        {
            for (int a= -1; a<=1; a++)
            {
                for (int b= -1; b<=1; b++)
                {
                    for (int c= -1; c<=1; c++)
                    {
                        if (!(a==0 && b==0 && c==0))
                        {
                            //oneD26 is just (double) 1/26
                            phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
                            if (phi[i]!=0)
                            {
                                //this gives expected results: 27 nonzero elements (including tvox)
                                cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl;
                            }
                        }
                    }
                }
            }
        }

        phi[svox]= 0; //svox = 7681
        phi[tvox]= 1;

        for (int q= 0; q<nmask; q++)
        {
            //this gives only 2 nonzero values: phi[tvox] and phi[9642], which was the last nonzero value from 1st cout
            if (phi[q]!=0)
                cout << q << " " << phi[q] << endl;
        }

    }

Upvotes: 0

Views: 1364

Answers (4)

sehe
sehe

Reputation: 392893

I do suggest to replace the meat of the loop with something like

const boost::irange domain(-1,2);
for (int i: boost::irange(0, nmask)) for (int a: domain) for (int b: domain) for (int c: domain)
{
    if (a==0 && b==0 && c==0)
        continue;
    //oneD26 is just (double) 1/26
    phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
    if (phi[i]!=0)
    {
        //this gives expected results: 27 nonzero elements (including tvox)
        cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl;
    }
}

Of course, for brevity I assume both boost/range.hpp and c++0x compiler. However, with trivial macro's you can achieve the same. That is without writing/using a proper combinations algorithm (why is that not in the standard, anyway).

Upvotes: 0

Bjarke H. Roune
Bjarke H. Roune

Reputation: 3727

phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];

The nested for-loops using a, b, and c run for a combined 9 iterations with the same value of i. Since you overwrite phi[i] to a new value every time, you only retain the value from the last iteration where a, and c are all 1. If that last iteration happens to produce zero values, then phi[i] will have lots of zeroes. Perhaps you meant to do something like phi[i] += ... instead of phi[i] = ...?

Upvotes: 1

antlersoft
antlersoft

Reputation: 14786

Difficult to tell just what is going on, but the easiest explanation is that after phi[i] gets set to non-zero and displayed to cout, it gets set to zero again in one of the later iterations through the inner loops.

Upvotes: 2

Karoly Horvath
Karoly Horvath

Reputation: 96258

If you do some tracing and check phi[i] just before updating you'll see that you often overwrite a non-zero element with zero.

Note: I have no idea what your code does, this is pure Sherlock Holmes reasoning.. if after the loops you find only 2 non-zero elements then the only logical consequence is that after updating something to non-zero later in the loop you update it to zero.

Upvotes: 1

Related Questions