/// <summary> /// Strip leading zero coefficients from the given polynomial /// </summary> /// /// <param name="A">The polynomial</param> /// /// <returns>The reduced polynomial</returns> private static int[] NormalForm(int[] A) { int d = ComputeDegree(A); // if a is the zero polynomial if (d == -1) { return(new int[1]); } // if a already is in normal form if (A.Length == d + 1) { return(IntUtils.DeepCopy(A)); } // else, reduce a int[] result = new int[d + 1]; Array.Copy(A, 0, result, 0, d + 1); return(result); }
/// <summary> /// Adds another GF2Vector to this vector /// </summary> /// /// <param name="V">The GF2Vector to add</param> /// /// <returns>Returns <c>this + V</c></returns> public override Vector Add(Vector V) { if (!(V is GF2Vector)) { throw new ArithmeticException("GF2Vector: Vector is not defined over GF(2)!"); } GF2Vector otherVec = (GF2Vector)V; if (Length != otherVec.Length) { throw new ArithmeticException("GF2Vector: Length mismatch!"); } int[] vec = IntUtils.DeepCopy(((GF2Vector)V).m_elements); for (int i = vec.Length - 1; i >= 0; i--) { vec[i] ^= m_elements[i]; } return(new GF2Vector(Length, vec)); }
/// <summary> /// Compute the inverse of this matrix /// </summary> /// /// <returns>Returns the inverse of this matrix</returns> public override Matrix ComputeInverse() { if (RowCount != ColumnCount) { throw new ArithmeticException("GF2Matrix: Matrix is not invertible!"); } // clone this matrix int[][] tmpMatrix = ArrayUtils.CreateJagged <int[][]>(RowCount, _length); for (int i = RowCount - 1; i >= 0; i--) { tmpMatrix[i] = IntUtils.DeepCopy(_matrix[i]); } // initialize inverse matrix as unit matrix int[][] invMatrix = ArrayUtils.CreateJagged <int[][]>(RowCount, _length); for (int i = RowCount - 1; i >= 0; i--) { int q = i >> 5; int r = i & 0x1f; invMatrix[i][q] = 1 << r; } // simultaneously compute Gaussian reduction of tmpMatrix and unit matrix for (int i = 0; i < RowCount; i++) { int q = i >> 5; int bitMask = 1 << (i & 0x1f); // if diagonal element is zero if ((tmpMatrix[i][q] & bitMask) == 0) { bool foundNonZero = false; // find a non-zero element in the same column for (int j = i + 1; j < RowCount; j++) { if ((tmpMatrix[j][q] & bitMask) != 0) { // found it, swap rows ... foundNonZero = true; SwapRows(tmpMatrix, i, j); SwapRows(invMatrix, i, j); // ... and quit searching j = RowCount; continue; } } // if no non-zero element was found the matrix is not invertible if (!foundNonZero) { throw new ArithmeticException("GF2Matrix: Matrix is not invertible!"); } } // normalize all but i-th row for (int j = RowCount - 1; j >= 0; j--) { if ((j != i) && ((tmpMatrix[j][q] & bitMask) != 0)) { AddToRow(tmpMatrix[i], tmpMatrix[j], q); AddToRow(invMatrix[i], invMatrix[j], 0); } } } return(new GF2Matrix(ColumnCount, invMatrix)); }
/// <summary> /// Copy constructor /// </summary> /// /// <param name="G">The GF2Vector to copy</param> public GF2Vector(GF2Vector G) { this.Length = G.Length; this.m_elements = IntUtils.DeepCopy(G.m_elements); }
/// <summary> /// Compute the inverse of this matrix /// </summary> /// /// <returns>Returns the inverse of this matrix (newly created)</returns> public override Matrix ComputeInverse() { if (RowCount != ColumnCount) { throw new ArithmeticException("GF2mMatrix: Matrix is not invertible!"); } // clone this matrix int[][] tmpMatrix = ArrayUtils.CreateJagged <int[][]>(RowCount, RowCount); for (int i = RowCount - 1; i >= 0; i--) { tmpMatrix[i] = IntUtils.DeepCopy(MatrixN[i]); } // initialize inverse matrix as unit matrix int[][] invMatrix = ArrayUtils.CreateJagged <int[][]>(RowCount, RowCount); for (int i = RowCount - 1; i >= 0; i--) { invMatrix[i][i] = 1; } // simultaneously compute Gaussian reduction of tmpMatrix and unit // matrix for (int i = 0; i < RowCount; i++) { // if diagonal element is zero if (tmpMatrix[i][i] == 0) { bool foundNonZero = false; // find a non-zero element in the same column for (int j = i + 1; j < RowCount; j++) { if (tmpMatrix[j][i] != 0) { // found it, swap rows ... foundNonZero = true; SwapColumns(tmpMatrix, i, j); SwapColumns(invMatrix, i, j); // ... and quit searching j = RowCount; continue; } } // if no non-zero element was found the matrix is not invertible if (!foundNonZero) { throw new ArithmeticException("GF2mMatrix: Matrix is not invertible!"); } } // normalize i-th row int coef = tmpMatrix[i][i]; int invCoef = FieldG.Inverse(coef); MultRowWithElementThis(tmpMatrix[i], invCoef); MultRowWithElementThis(invMatrix[i], invCoef); // normalize all other rows for (int j = 0; j < RowCount; j++) { if (j != i) { coef = tmpMatrix[j][i]; if (coef != 0) { int[] tmpRow = MultRowWithElement(tmpMatrix[i], coef); int[] tmpInvRow = MultRowWithElement(invMatrix[i], coef); AddToRow(tmpRow, tmpMatrix[j]); AddToRow(tmpInvRow, invMatrix[j]); } } } } return(new GF2mMatrix(FieldG, invMatrix)); }
/// <summary> /// The copy constructor /// </summary> /// /// <param name="GF">The GF2mVector to copy</param> public GF2mVector(GF2mVector GF) { m_field = new GF2mField(GF.m_field); Length = GF.Length; m_vector = IntUtils.DeepCopy(GF.m_vector); }
/// <summary> /// The permutation vector <c>(perm(0),perm(1),...,perm(n-1))</c> /// </summary> /// /// <returns>The permutation vector</returns> public int[] GetVector() { return(IntUtils.DeepCopy(_perm)); }