2015-02-03 3 views
-2

У меня есть 4 вложенных цикла "for".Итерация вложенных «за» циклов только по «конкретным» индексам. C++

 for(int i=0; i<len1; i++) { 
     for(int j=0; j<len2; j++) { 
     for(int k=0; k<len1; k++) { 
     for(int l=0; l<len2; l++) { 
      //perform some calculations/operations. 
     } 
     } 
     } 
    } 

Дело в том, весь этот код будет работать над каждым и каждый индекс каждый «для» цикла от 0 до len1/len2. Я не хочу, чтобы это делалось. Вместо этого я хочу, чтобы эти циклы повторялись по определенным «конкретным» индексам и пропускали остальные (пропуская, я имею в виду TOTAL skipping, он не должен перебирать ненужные индексы).

Чтобы дать более подробное объяснение, вот как будут выполняться итерации, когда выполняется приведенный выше фрагмент кода.

i j k l 
0 0 0 0 
0 0 0 1 
0 0 0 2 
0 0 0 3 
. . . . 
. . . . 
. . . . 
len1 len2 len1 len2 

Но то, что я хочу, это следующее ...

0 0 0 63 
0 0 0 450 
0 0 0 569 
0 0 3 87 
0 0 78 999 
. . . . 
. . . . 
. . . . 
29 65 99 357 
29 66 21 222 
. . . . 

и так далее ... Во-первых это возможно с вложенными «для» петли?

Во-вторых, и самое главное, я хочу сделать это только с вложенными петлями «для». Никакой другой метод.

В-третьих, итерации по «конкретным» индексам, которые я хочу, НЕ случайны.

+0

'для (INT I = 0; л

+3

* "витки над "конкретными" индексами я хочу не случайно" * Тогда, как она определяется? – Radiodef

+0

Допустим, у меня есть что-то вроде {для определенного индекса «i» с конкретным индексом «j» с определенным индексом «k», итерацией только по этим индексам «l»} –

ответ

0

Если вы можете определить начальную точку внутреннего контура в терминах внешних контуров, обязательно. Пример:

for(int i=0; i<len1; i++) { 
    for(int j=0; j<len2; j++) { 
    for(int k=0; k<len1; k++) { 
    int lStart = DetermineBasedOn(i, j, k); 
    for(int l=lStart; l<len2; l++) { 
     //perform some calculations/operations. 
    } 
    } 
    } 
} 

Обратите внимание, что

DetermineBasedOn(i, j, k); 

не должен быть фактическим вызовом метода. Вы можете установить начальный индекс внутри тела вашего цикла.

Если вам нужно пробелы в регионе, которые вы перебирать, делать, как предложено @SamIAm в комментариях: указать функцию, чтобы определить следующий индекс (хотя, возможно, на основе нескольких переменных:

for(int l=lStart; l<len2; l = GetNextIndex(l, i, j, k)) { 

Вы можете использовать ту же технику, чтобы закончить внутреннюю петлю ранее (например, установка lEnd и использования, что вместо len2).

во-вторых, и самое главное, я хочу сделать это только с вложенными «для» петли. Нет другой способ.

do и while петли функционально эквивалентны for петель, и может (или не может) быть яснее и легче читать в этом случае. Я не уверен, почему смещение против других конструкций цикла, но вы можете, конечно, выполнить тот же результат с for, как с do или while.

+0

Мне нужно использовать «для» циклов, чтобы я может сделать его параллельным с помощью OpenMp или CUDA. –

+0

@MohammadSohaib: CUDA не может распараллелить другие конструкции цикла? Интересно, но не проблема, поскольку они функционально эквивалентны другим конструкциям цикла. –

+0

Но см. «For (int l = lStart; l

0

Поместите свои конкретные индексы в std::vector и переверните их, чтобы получить реальные индексы. С C++ 11 вы можете использовать следующий синтаксис для инициализации вектора.

std::vector myFavoriteIndices = {5,7, 11, 8} 

for(int i = 0; i < len1; i++) { 
    for(int j = 0; j < len2; j++) { 
     for(int k = 0; k < len1; k++) { 
      for(int l = 0; l < myFavoriteIndices.size(); l++) { 
       int trueIndex = myFavoriteIndices[l]; 
       // do something with trueIndex 
      } 
     } 
    } 
} 
0

Если я правильно понимаю, вы хотите, чтобы определенные индексы (у вас есть способ определения этого?) Повторялись.

Если вы можете предопределить желаемые индексы, вы можете использовать вектор индексов.

Что-то вроде:

vector<int> iIdx; 
vector<int> jIdx; 
vector<int> kIdx; 
vector<int> lIdx; 

// your inside algorithm section which determines what indexes are needed for each 
... 
lIdx.push_back(63); 
... 

// the new loop 
for (int i=0;i<iIdx.size();i++) 
    for (int j=0;j<jIdx.size();j++) 
    for (int k=0;k<kIdx.size();k++) 
     for (int l=0;l<lIdx.size();l++) 
     { 
      ii = iIdx[i]; 
      jj = jIdx[j]; 
      kk = kIdx[k]; 
      ll = lIdx[l]; 
      // use ii , jj ,kk and ll as you would use i,j,k,l on your original question 
     } 

Это работает, если у вас есть способ, чтобы определить эти показатели до начала четырехъядерного цикла.

В противном случае вы можете обрезать некоторые циклы с помощью этого подхода в точке, где вы можете генерировать индексы (например, если вам нужно знать i и j для генерации индексов k и l, то будут использоваться только kIdx и lIdx вышеуказанный метод).

EDIT:

Отмеченный в другой комментарий, который вы используете CUDA.

Вы можете вычислить массивы iIdx, jIdx, kIdx и lIdx на процессоре и создать петли for на графическом процессоре.

+0

Я не думаю, что это позволяет покрывать области неправильной формы матрицы. –

+0

На самом деле это не так. Но если это то, чего хочет OP, разве мы не отвечаем на проблему X Y? – MichaelCMS

Смежные вопросы