блокировка матрицы дает ошибку сегментации

Я пытаюсь реализовать алгоритм Штрассена на С++. Я хочу разделить квадратную матрицу «hA» на 4 равных блока.

// Initialize matrices on the host
float hA[N][N],ha11[N / 2][N / 2], ha12[N / 2][N / 2], ha21[N / 2][N / 2],
        ha22[N / 2][N / 2];
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        hA[i][j] = i;
        //hB[i][j] = i;
    }
}
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        printf("\n%d,%d\n", i, j);
        if (i < N / 2 & j < N / 2) {
            ha11[i][j] = hA[i][j];
        } else if (i < N / 2 & j >= N / 2) {
            ha12[i][j] = hA[i][j];
        } else if (i >= N / 2 & j < N / 2) {
            ha21[i][j] = hA[i][j];
        } else if (i >= N / 2 & j >= N / 2) {
            ha22[i][j] = hA[i][j];    //faulty!
        }
    }
}

Я использовал описанный выше метод для разбиения, и он дает сбой, как показано в выводе ниже. Но он отлично работает, когда я удаляю последнее сравнение в лестнице «если еще». введите здесь описание изображения

Почему «i» имеет неправильное значение, которое даже находится за пределами условия цикла? Есть ли более удобный способ разбиения, чем этот?


person Maddy    schedule 22.11.2013    source источник


Ответы (2)


Ваши массивы должны быть N x N, а не N/2 x N/2.

Ваше использование побитового оператора & необычно, но работает. Я ошибочно подумал, что вместо этого вам нужно логическое и ( && ). Тем не менее, для удобства чтения я бы предложил &&. Вы тоже получаете короткое замыкание.

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            printf("\n%d,%d\n", i, j);
            if (i < N / 2 & j < N / 2) {
                ha11[i][j] = hA[i][j];
            } else if (i < N / 2 & j >= N / 2) {
                ha12[i][j] = hA[i][j];
            } else if (i >= N / 2 & j < N / 2) {
                ha21[i][j] = hA[i][j];
            } else if (i >= N / 2 & j >= N / 2) {
                ha22[i][j] = hA[i][j];    //faulty!
            }
        }
    }
person Charlie Burns    schedule 22.11.2013
comment
Я думаю, что вы правы в первую очередь. Я сделал действительно глупую ошибку, не сбросив i,j для секционированных матриц. Спасибо! Однако мы можем использовать & как логический оператор. - person Maddy; 22.11.2013
comment
Да, вы правы, вы можете использовать & в этом случае. Это необычно, и это то, что привлекло мое внимание, но вы правы. - person Charlie Burns; 22.11.2013
comment
Использование & вместо && может повысить производительность. CUDA: почему побитовые операторы иногда быстрее логических? - person Roger Dahl; 22.11.2013

Чтобы работать с написанным кодом, ваши подмассивы должны быть NxN каждый, а не N/2 на N/2, но я не думаю, что это на самом деле «ошибка».

Вы разрезаете массив на 4 равные части, поэтому они должны быть меньше оригинала. Остается два вопроса.

Ваши назначения неверны, h11 в порядке, но все h12, h21 и h22 нужно настроить следующим образом:

ha12[i-N/2][j-N/2] = hA[i][j];
ha21[i-N/2][j] = hA[i][j];
ha22[i-N/2][j-N/2] = hA[i][j];

вместо того, что у вас есть, (хотя держите их там, где они есть).

Кстати, это может быть легче читать, если вы полностью удалите операторы if, выполняя итерацию всего за один квартал, но выполняя 4 задания за квартал.

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

person RichardPlunkett    schedule 22.11.2013