public static BigZpMatrix GetConcatenationMatrix(BigZpMatrix A, BigZpMatrix B) { if (A.RowCount != B.RowCount) { throw new ArgumentException("Illegal matrix dimensions - cannot perform concatenation."); } if (A.Prime != B.Prime) { throw new ArgumentException("Trying to concatenate Matrix from different fields."); } var C = new BigZpMatrix(A.RowCount, A.ColCount + B.ColCount, A.Prime); // Copy A for (int i = 0; i < A.RowCount; i++) { for (int j = 0; j < A.ColCount; j++) { C.data[i][j] = A.data[i][j]; } } // Copy B for (int i = 0; i < A.RowCount; i++) { for (int j = A.ColCount; j < A.ColCount + B.ColCount; j++) { C.data[i][j] = B.data[i][j - A.ColCount]; } } return(C); }
/* return C = A * B : matrix multiplication*/ public BigZpMatrix Times(BigZpMatrix B) { var A = this; if (A.ColCount != B.RowCount) { throw new ArgumentException("Illegal matrix dimensions."); } if (A.Prime != B.Prime) { throw new ArgumentException("Matrix from different fields."); } // create initialized matrix (zero value to all elements) var C = new BigZpMatrix(A.RowCount, B.ColCount, A.Prime); for (int i = 0; i < C.RowCount; i++) { for (int j = 0; j < C.ColCount; j++) { for (int k = 0; k < A.ColCount; k++) { C.data[i][j] = Modulo(C.data[i][j] + A.data[i][k] * B.data[k][j]); } } } return(C); }
/// <summary> /// Returns a Vandermonde matrix in the field (each element is modulu prime). /// </summary> public static BigZpMatrix GetShamirRecombineMatrix(int matrixSize, BigInteger prime) { var A = new BigZpMatrix(matrixSize, matrixSize, prime); if (matrixSize == 1) { A.data[0][0] = 1; return(A); } for (int i = 0; i < matrixSize; i++) { A.data[i][0] = 1; } for (int i = 0; i < matrixSize; i++) { A.data[i][1] = i + 1; } for (int i = 0; i < matrixSize; i++) { for (int j = 2; j < matrixSize; j++) { A.data[i][j] = BigZp.Modulo(A.data[i][j - 1] * A.data[i][1], prime); } } return(A); }
public static BigZpMatrix GetVandermondeMatrix(int rowNum, int colNum, BigInteger prime) { var A = new BigZpMatrix(rowNum, colNum, prime); for (int j = 0; j < colNum; j++) { A.data[0][j] = 1; } if (rowNum == 1) { return(A); } for (int j = 0; j < colNum; j++) { A.data[1][j] = j + 1; } for (int j = 0; j < colNum; j++) { for (int i = 2; i < rowNum; i++) { A.data[i][j] = BigZp.Modulo(A.data[i - 1][j] * A.data[1][j], prime); } } return(A); }
/* return C = A + B */ public BigZpMatrix Plus(BigZpMatrix B) { var A = this; if ((B.RowCount != A.RowCount) || (B.ColCount != A.ColCount)) { throw new ArgumentException("Illegal matrix dimensions."); } if (A.Prime != B.Prime) { throw new ArgumentException("Trying to add Matrix from different fields."); } var C = new BigZpMatrix(RowCount, ColCount, A.Prime); for (int i = 0; i < RowCount; i++) { for (int j = 0; j < ColCount; j++) { C.data[i][j] = Modulo(A.data[i][j] + B.data[i][j]); } } return(C); }
/* Create and return N-by-N matrix that its first "trucToSize" elements in * its diagonal is "1" and the rest of the matrix is "0"*/ public static BigZpMatrix GetTruncationMatrix(int matrixSize, int truncToSize, BigInteger prime) { var I = new BigZpMatrix(matrixSize, matrixSize, prime); for (int i = 0; i < truncToSize; i++) { I.data[i][i] = 1; } return(I); }
/// <summary> /// Create and return the N-by-N identity matrix. /// </summary> public static BigZpMatrix GetIdentityMatrix(int matrixSize, BigInteger prime) { var I = new BigZpMatrix(matrixSize, matrixSize, prime); for (int i = 0; i < matrixSize; i++) { I.data[i][i] = 1; } return(I); }
/// <summary> /// Creates and return a random rowNum-by-colNum matrix with values between '0' and 'prime-1'. /// </summary> public static BigZpMatrix GetRandomMatrix(int rowNum, int colNum, BigInteger prime) { var A = new BigZpMatrix(rowNum, colNum, prime); for (int i = 0; i < rowNum; i++) { for (int j = 0; j < colNum; j++) { A.data[i][j] = BigZp.Modulo(StaticRandom.Next(prime), prime); } } return(A); }
public static IList <BigZp> GetVandermondeInvColumn(BigInteger prime, int size) { Tuple <BigInteger, int> t = new Tuple <BigInteger, int>(prime, size); if (VandermondeInvCache.ContainsKey(t)) { return(VandermondeInvCache[t]); } var inv = BigZpMatrix.GetVandermondeMatrix(size, size, prime).Inverse.GetMatrixColumn(0); VandermondeInvCache[t] = inv; return(inv); }
private BigZpMatrix GetSubMatrix(int[] r, int j0, int j1) { var X = new BigZpMatrix(r.Length, j1 - j0 + 1, Prime); var B = X.data; for (int i = 0; i < r.Length; i++) { for (int j = j0; j <= j1; j++) { B[i][j - j0] = data[r[i]][j]; } } return(X); }
/// <summary> /// Multiplies each row by different scalar from the scalars vector. /// </summary> public BigZpMatrix MulMatrixByScalarsVector(int[] scalarsVector) { if (RowCount != scalarsVector.Length) { throw new ArgumentException("incompatible vector length and matrix row number."); } var B = new BigZpMatrix(this); for (int i = 0; i < RowCount; i++) { B.MulRowByscalar(i, scalarsVector[i]); } return(B); }
private BigZpMatrix SolveInv(BigZpMatrix B, int[] piv) { if (B.RowCount != RowCount) { throw new ArgumentException("Matrix row dimensions must agree."); } if (!Nonsingular) { throw new ArgumentException("Matrix is singular."); } // Copy right hand side with pivoting int nx = B.ColCount; var Xmat = B.GetSubMatrix(piv, 0, nx - 1); var X = Xmat.data; // Solve L*Y = B(piv,:) for (int k = 0; k < RowCount; k++) { for (int i = k + 1; i < RowCount; i++) { for (int j = 0; j < nx; j++) { X[i][j] = Modulo(X[i][j] - X[k][j] * data[i][k]); } } } // Solve U*X = Y; for (int k = RowCount - 1; k >= 0; k--) { for (int j = 0; j < nx; j++) { X[k][j] = Modulo(X[k][j] * NumTheoryUtils.CalcInverse(data[k][k], Prime)); } for (int i = 0; i < k; i++) { for (int j = 0; j < nx; j++) { X[i][j] = Modulo(X[i][j] - X[k][j] * data[i][k]); } } } return(Xmat); }
public static BigZpMatrix GetVandermondeMatrix(int rowNum, IList <BigZp> values, BigInteger prime) { int colNum = values.Count; var A = new BigZpMatrix(rowNum, colNum, prime); for (int j = 0; j < colNum; j++) { A.data[0][j] = 1; } if (rowNum == 1) { return(A); } for (int j = 0; j < colNum; j++) { for (int i = 1; i < rowNum; i++) { A.data[i][j] = BigZp.Modulo(A.data[i - 1][j] * values[j].Value, prime); } } return(A); }
private BigZpMatrix GetLUDecomposition(int[] pivot) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. var LU = new BigZpMatrix(this); BigInteger[][] LUArr = LU.data; int[] piv = pivot; for (int i = 0; i < RowCount; i++) { piv[i] = i; } int pivsign = 1; BigInteger[] LUrowi; var LUcolj = new BigInteger[RowCount]; // Outer loop. for (int j = 0; j < RowCount; j++) { // Make a copy of the j-th column to localize references. for (int i = 0; i < RowCount; i++) { LUcolj[i] = LUArr[i][j]; } // Apply previous transformations. for (int i = 0; i < RowCount; i++) { LUrowi = LUArr[i]; // Most of the time is spent in the following dot product. int kmax = Math.Min(i, j); BigInteger s = 0; for (int k = 0; k < kmax; k++) { s = Modulo(s + LUrowi[k] * LUcolj[k]); } LUrowi[j] = LUcolj[i] = Modulo(LUcolj[i] - s); } // Find pivot and exchange if necessary. int p = j; for (int i = j + 1; i < RowCount; i++) { if ((LUcolj[i]) > (LUcolj[p])) { p = i; } } if (p != j) { for (int k = 0; k < RowCount; k++) { BigInteger t = LUArr[p][k]; LUArr[p][k] = LUArr[j][k]; LUArr[j][k] = t; } int r = piv[p]; piv[p] = piv[j]; piv[j] = r; pivsign = -pivsign; } // Compute multipliers. if (j < RowCount & LUArr[j][j] != 0) { for (int i = j + 1; i < RowCount; i++) { //LUArr[i][j] = Modulo(LUArr[i][j] * fieldInv[Modulo(LUArr[j][j])]); LUArr[i][j] = Modulo(LUArr[i][j] * NumTheoryUtils.MultiplicativeInverse(Modulo(LUArr[j][j]), Prime)); } } } return(LU); }
private BigZpMatrix(BigZpMatrix A) : this(A.data, A.Prime) { }