вектор c ++ не обновляется во вложенном цикле - PullRequest
0 голосов
/ 01 июля 2011

Итак, я создаю и инициализирую вектор (размером nmask + 3) в 0 и назначаю начальное значение одному из элементов. Затем я создаю цикл for, который проходит через первые nmask-элементы вектора и присваивает каждому элементу в среднем 26 других элементов в векторе (определяемых массивом 4D int voxt, который содержит векторные адреса).

Моя проблема в том, что когда я проверяю значения ненулевых элементов в моем векторе (phi) внутри вложенного цикла (первый cout), значения в порядке и то, что я ожидаю. Однако, когда цикл завершает прохождение всех элементов nmask (for (int i= 0; i<nmask; i++) выходы), я снова проверяю ненулевые элементы phi, и все они теряются (сбрасываются в 0), за исключением последнего ненулевого элемента (и элемента tvox, который устанавливается вручную на 1).

Я чувствую, что, поскольку phi инициализируется вне всех циклов, не должно происходить сброса значений, и что любые обновленные элементы во вложенном цикле должны оставаться обновленными после выхода из цикла. Любые идеи относительно того, что происходит / как это исправить? Код ниже; Я попытался прокомментировать некоторые из полученных результатов. Заранее спасибо.

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

    }

Ответы [ 4 ]

2 голосов
/ 01 июля 2011

Трудно сказать, что происходит, но самое простое объяснение состоит в том, что после того, как phi [i] установлен в ненулевое значение и отображается как cout, он снова устанавливается в ноль в одной из последующих итераций через внутренние циклы.

1 голос
/ 01 июля 2011
phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];

Вложенные циклы for, использующие a, b и c, выполняются для комбинированных 9 итераций с одинаковым значением i. Поскольку вы каждый раз перезаписываете phi [i] на новое значение, вы сохраняете значение только из последней итерации, где a и c равны 1. Если на последней итерации будет получено нулевое значение, то phi [i] будет иметь много нулей. Возможно, вы хотели сделать что-то вроде phi [i] + = ... вместо phi [i] = ...?

1 голос
/ 01 июля 2011

Если вы выполните некоторую трассировку и проверите phi[i] непосредственно перед обновлением, вы увидите, что вы часто перезаписываете ненулевой элемент нулем.

Примечание: я понятия не имею, что делает ваш код, эточисто рассуждения Шерлока Холмса ... если после циклов вы найдете только 2 ненулевых элемента, то единственное логическое следствие состоит в том, что после обновления чего-либо до ненулевого значения позже в цикле вы обновляете его до нуля.

0 голосов
/ 01 июля 2011

Я предлагаю заменить мясо цикла чем-то вроде

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

Конечно, для краткости я предполагаю компилятор boost/range.hpp и c ++ 0x.Тем не менее, с помощью простых макросов вы можете достичь того же.Это без написания / использования правильного combinations алгоритма ( почему это не в стандарте, во всяком случае ).

...