//(c) Chernysheva, TEST(Matrix, mulMatrixToVec) //------->>>>>>>>>----------------- // умножение матрицы на вектор-столбец Polynom mulMatrixToVec(const Polynom& plA, const Matrix& mtB) { Polynom vec; if (mtB.CodeWord == Matrix::ON_LINE) { if (mtB.ColCount >= plA.getNumberBits()) { for (uint j = 0; j < mtB.RowCount; j++) { uint sum = 0, elem; for (uint i = 0; i < mtB.getColCountMatrixByte(); i++) { elem = mtB.plMatrix[j]->getDigit(i) & plA.getDigit(i); sum = sum ^ elem; } vec.setDigit(j, sum); } Polynom res; uint s = 0; for (uint j = 0; j < vec.getNumberDigits(); j++) { bool bit = 0; for (uint i = 0; i < vec.getDigitSizeInBits(); i++) { bit = bit ^ vec.getBit(s); s++; } res.setBit(j, bit); } return res; } } vec = plA; return vec; }
//(c) Chernysheva, TEST(Matrix, RightTrian) //------->>>>>>>>>----------------- // приведение матрицы к треугольному виду алгоритмом Коновальцева, // внутри применяется бинарный алгоритм Гаусса // на выходе получаем верхнетреугольную матрицу справа-налево Matrix& Matrix::konovalcevRightTrianBits() { if ((this->getCoding() == ON_LINE)&&(this->getTrianType() == NONE)) { //int r = (log(n)/log(P)) - 3*(log(log(n)/log(P))/log(P)); // длина кортежа int r = 3; uint activeRow = 0, activeCol = this->ColCount - 1;; Polynom *cortege = new Polynom, *nul = new Polynom; while ((activeRow < this->RowCount)&&(activeCol >= 0)) { uint aRow = activeRow, aCol = activeCol, notNulCortegeRow = 0; bool allCortegeNul = false; uint NumNotNulCortege = 0; // работа с кортежами while ((aRow < this->RowCount)&&(!allCortegeNul)) { // ищем первый ненулевой кортеж for (uint i = aRow; i < this->RowCount; i++) { // прохождение по кортежу uint rc = 0; for (uint ri = aCol + 1 - r; ri < aCol + 1; ri++) { bool bit = this->getBit(i, ri); cortege->setBit(rc, bit); rc++; } if (*cortege != *nul) { notNulCortegeRow = i; NumNotNulCortege++; break; } } // все кортежи нулевые if (*cortege == *nul) allCortegeNul = true; else { Polynom *buf = new Polynom, *curCortege = new Polynom; // меняем местами активную строку со строкой с ненулевым кортежем if (notNulCortegeRow != aRow) { *buf = *this->plMatrix[notNulCortegeRow]; *this->plMatrix[notNulCortegeRow] = *this->plMatrix[aRow]; *this->plMatrix[aRow] = *buf; } // удаление одинаковых с активным кортежей for (uint i = aRow + 1; i < this->RowCount; i++) { uint rc = 0; for (uint ri = aCol + 1 - r; ri < aCol + 1; ri++) { bool bit = this->getBit(i, ri); curCortege->setBit(rc, bit); rc++; } uint t = 0; for (uint rc = 0; rc < r; rc++) { bool y = (cortege->getBit(rc) == curCortege->getBit(rc)); if (y) t++; } if (t == r) { *this->plMatrix[i] = *this->plMatrix[i] - *this->plMatrix[aRow]; } } aRow++; } } aRow = activeRow, aCol = activeCol; // метод Гаусса для приведения к треугольному виду while ((aRow < activeRow + NumNotNulCortege)&&(aCol >= 0)) { bool bitActiveRow = this->getBit(aRow, aCol); if (bitActiveRow) { bool bit; for (uint i = aRow + 1; i < this->RowCount; i++) { bit = this->getBit(i, aCol); if (bit) this->plMatrix[i]->Xor(*this->plMatrix[i], *this->plMatrix[aRow]); } aCol--; aRow++; } else { bool bit; // так как мы уже знаем, что бит, находящийся на пересечении // activeRow и activeCol равен 0, то мы можем воспользоваться этим uint firstTrueBit = activeRow; for (uint i = aRow + 1; i < this->RowCount; i++) { bit = this->getBit(i, aCol); if (bit) { firstTrueBit = i; break; } } // не состоит ли весь столбец из нулей if (firstTrueBit != activeRow) this->plMatrix[aRow]->Xor(*this->plMatrix[aRow], *this->plMatrix[firstTrueBit]); else aCol--; } } activeCol -= r; activeRow += r; } this->setTrianType(RIGHT); } return *this; }