/// <summary> /// Compute the product of this matrix and a permutation matrix which is generated from an n-permutation /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns GF2Matrix <c>this*P</c></returns> public override Matrix RightMultiply(Permutation P)//3 { int[] pVec = P.GetVector(); if (pVec.Length != ColumnCount) { throw new ArithmeticException("GF2Matrix: Length mismatch!"); } GF2Matrix result = new GF2Matrix(RowCount, ColumnCount); for (int i = ColumnCount - 1; i >= 0; i--) { int q = IntUtils.URShift(i, 5); int r = i & 0x1f; int pq = IntUtils.URShift(pVec[i], 5); int pr = pVec[i] & 0x1f; for (int j = RowCount - 1; j >= 0; j--) { result._matrix[j][q] |= ((IntUtils.URShift(_matrix[j][pq], pr)) & 1) << r; } } return(result); }
/// <summary> /// Multiply this vector with a permutation /// </summary> /// /// <param name="P">he permutation</param> /// /// <returns>Returns <c>this*p = p*this</c></returns> public override Vector Multiply(Permutation P) { int[] pVec = P.GetVector(); if (Length != pVec.Length) { throw new ArithmeticException("permutation size and vector size mismatch"); } int[] result = new int[Length]; for (int i = 0; i < pVec.Length; i++) { result[i] = _vector[pVec[i]]; } return(new GF2mVector(_field, result)); }
/// <summary> /// Compute the product of a permutation matrix (which is generated from an n-permutation) and this matrix. /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns GF2Matrix <c>P*this</c></returns> public Matrix LeftMultiply(Permutation P) { int[] pVec = P.GetVector(); if (pVec.Length != RowCount) { throw new ArithmeticException("GF2Matrix: length mismatch!"); } int[][] result = new int[RowCount][]; for (int i = RowCount - 1; i >= 0; i--) { result[i] = IntUtils.DeepCopy(_matrix[pVec[i]]); } return(new GF2Matrix(RowCount, result)); }
/// <summary> /// Create an nxn random regular matrix /// </summary> /// /// <param name="N">Number of rows (and columns)</param> /// <param name="SecRnd">Source of randomness</param> private void AssignRandomRegularMatrix(int N, IRandom SecRnd) { RowCount = N; ColumnCount = N; _length = IntUtils.URShift((N + 31), 5); _matrix = ArrayUtils.CreateJagged <int[][]>(RowCount, _length); GF2Matrix lm = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_LT, SecRnd); GF2Matrix um = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_UT, SecRnd); GF2Matrix rm = (GF2Matrix)lm.RightMultiply(um); Permutation perm = new Permutation(N, SecRnd); int[] p = perm.GetVector(); for (int i = 0; i < N; i++) { Array.Copy(rm._matrix[i], 0, _matrix[p[i]], 0, _length); } }
/// <summary> /// Multiply this vector with a permutation /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns <c>this*p = p*this</c></returns> public override Vector Multiply(Permutation P) { int[] pVec = P.GetVector(); if (Length != pVec.Length) { throw new ArithmeticException("GF2Vector: Length mismatch!"); } GF2Vector result = new GF2Vector(Length); for (int i = 0; i < pVec.Length; i++) { int e = _elements[pVec[i] >> 5] & (1 << (pVec[i] & 0x1f)); if (e != 0) { result._elements[i >> 5] |= 1 << (i & 0x1f); } } return(result); }
/// <summary> /// Multiply this vector with a permutation /// </summary> /// /// <param name="P">he permutation</param> /// /// <returns>Returns <c>this*p = p*this</c></returns> public override Vector Multiply(Permutation P) { int[] pVec = P.GetVector(); if (Length != pVec.Length) throw new ArithmeticException("permutation size and vector size mismatch"); int[] result = new int[Length]; for (int i = 0; i < pVec.Length; i++) result[i] = _vector[pVec[i]]; return new GF2mVector(_field, result); }
/// <summary> /// Create a nxn random regular matrix and its inverse /// </summary> /// /// <param name="N">Number of rows (and columns)</param> /// <param name="SecRnd">Source of randomness</param> /// <returns>The created random regular matrix and its inverse</returns> public static GF2Matrix[] CreateRandomRegularMatrixAndItsInverse(int N, IRandom SecRnd) { GF2Matrix[] result = new GF2Matrix[2]; // First part: create regular matrix int length = (N + 31) >> 5; GF2Matrix lm = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_LT, SecRnd); GF2Matrix um = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_UT, SecRnd); GF2Matrix rm = (GF2Matrix)lm.RightMultiply(um); Permutation p = new Permutation(N, SecRnd); int[] pVec = p.GetVector(); int[][] matrix = ArrayUtils.CreateJagged <int[][]>(N, length); for (int i = 0; i < N; i++) { Array.Copy(rm._matrix[pVec[i]], 0, matrix[i], 0, length); } result[0] = new GF2Matrix(N, matrix); // Second part: create inverse matrix // inverse to lm GF2Matrix invLm = new GF2Matrix(N, Matrix.MATRIX_TYPE_UNIT); for (int i = 0; i < N; i++) { int rest = i & 0x1f; int q = IntUtils.URShift(i, 5); int r = 1 << rest; for (int j = i + 1; j < N; j++) { int b = (lm._matrix[j][q]) & r; if (b != 0) { for (int k = 0; k <= q; k++) { invLm._matrix[j][k] ^= invLm._matrix[i][k]; } } } } // inverse to um GF2Matrix invUm = new GF2Matrix(N, Matrix.MATRIX_TYPE_UNIT); for (int i = N - 1; i >= 0; i--) { int rest = i & 0x1f; int q = IntUtils.URShift(i, 5); int r = 1 << rest; for (int j = i - 1; j >= 0; j--) { int b = (um._matrix[j][q]) & r; if (b != 0) { for (int k = q; k < length; k++) { invUm._matrix[j][k] ^= invUm._matrix[i][k]; } } } } // inverse matrix result[1] = (GF2Matrix)invUm.RightMultiply(invLm.RightMultiply(p)); return(result); }
//3 /// <summary> /// Compute the product of this matrix and a permutation matrix which is generated from an n-permutation /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns GF2Matrix <c>this*P</c></returns> public override Matrix RightMultiply(Permutation P) { int[] pVec = P.GetVector(); if (pVec.Length != ColumnCount) throw new ArithmeticException("GF2Matrix: Length mismatch!"); GF2Matrix result = new GF2Matrix(RowCount, ColumnCount); for (int i = ColumnCount - 1; i >= 0; i--) { int q = IntUtils.URShift(i, 5); int r = i & 0x1f; int pq = IntUtils.URShift(pVec[i], 5); int pr = pVec[i] & 0x1f; for (int j = RowCount - 1; j >= 0; j--) result._matrix[j][q] |= ((IntUtils.URShift(_matrix[j][pq], pr)) & 1) << r; } return result; }
/// <summary> /// Compute the product of a permutation matrix (which is generated from an n-permutation) and this matrix. /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns GF2Matrix <c>P*this</c></returns> public Matrix LeftMultiply(Permutation P) { int[] pVec = P.GetVector(); if (pVec.Length != RowCount) throw new ArithmeticException("GF2Matrix: length mismatch!"); int[][] result = new int[RowCount][]; for (int i = RowCount - 1; i >= 0; i--) result[i] = IntUtils.DeepCopy(_matrix[pVec[i]]); return new GF2Matrix(RowCount, result); }
/// <summary> /// Create a nxn random regular matrix and its inverse /// </summary> /// /// <param name="N">Number of rows (and columns)</param> /// <param name="SecRnd">Source of randomness</param> /// <returns>The created random regular matrix and its inverse</returns> public static GF2Matrix[] CreateRandomRegularMatrixAndItsInverse(int N, IRandom SecRnd) { GF2Matrix[] result = new GF2Matrix[2]; // First part: create regular matrix int length = (N + 31) >> 5; GF2Matrix lm = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_LT, SecRnd); GF2Matrix um = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_UT, SecRnd); GF2Matrix rm = (GF2Matrix)lm.RightMultiply(um); Permutation p = new Permutation(N, SecRnd); int[] pVec = p.GetVector(); int[][] matrix = ArrayUtils.CreateJagged<int[][]>(N, length); for (int i = 0; i < N; i++) Array.Copy(rm._matrix[pVec[i]], 0, matrix[i], 0, length); result[0] = new GF2Matrix(N, matrix); // Second part: create inverse matrix // inverse to lm GF2Matrix invLm = new GF2Matrix(N, Matrix.MATRIX_TYPE_UNIT); for (int i = 0; i < N; i++) { int rest = i & 0x1f; int q = IntUtils.URShift(i, 5); int r = 1 << rest; for (int j = i + 1; j < N; j++) { int b = (lm._matrix[j][q]) & r; if (b != 0) { for (int k = 0; k <= q; k++) invLm._matrix[j][k] ^= invLm._matrix[i][k]; } } } // inverse to um GF2Matrix invUm = new GF2Matrix(N, Matrix.MATRIX_TYPE_UNIT); for (int i = N - 1; i >= 0; i--) { int rest = i & 0x1f; int q = IntUtils.URShift(i, 5); int r = 1 << rest; for (int j = i - 1; j >= 0; j--) { int b = (um._matrix[j][q]) & r; if (b != 0) { for (int k = q; k < length; k++) invUm._matrix[j][k] ^= invUm._matrix[i][k]; } } } // inverse matrix result[1] = (GF2Matrix)invUm.RightMultiply(invLm.RightMultiply(p)); return result; }
/// <summary> /// Create an nxn random regular matrix /// </summary> /// /// <param name="N">Number of rows (and columns)</param> /// <param name="SecRnd">Source of randomness</param> private void AssignRandomRegularMatrix(int N, IRandom SecRnd) { RowCount = N; ColumnCount = N; _length = IntUtils.URShift((N + 31), 5); _matrix = ArrayUtils.CreateJagged<int[][]>(RowCount, _length); GF2Matrix lm = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_LT, SecRnd); GF2Matrix um = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_UT, SecRnd); GF2Matrix rm = (GF2Matrix)lm.RightMultiply(um); Permutation perm = new Permutation(N, SecRnd); int[] p = perm.GetVector(); for (int i = 0; i < N; i++) Array.Copy(rm._matrix[i], 0, _matrix[p[i]], 0, _length); }
/// <summary> /// Multiply this vector with a permutation /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns <c>this*p = p*this</c></returns> public override Vector Multiply(Permutation P) { int[] pVec = P.GetVector(); if (Length != pVec.Length) throw new ArithmeticException("GF2Vector: Length mismatch!"); GF2Vector result = new GF2Vector(Length); for (int i = 0; i < pVec.Length; i++) { int e = _elements[pVec[i] >> 5] & (1 << (pVec[i] & 0x1f)); if (e != 0) result._elements[i >> 5] |= 1 << (i & 0x1f); } return result; }