Exemplo n.º 1
0
  //(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;
  }
Exemplo n.º 2
0
  //(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;
  }