public ZpMatrix Plus(ZpMatrix 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 ZpMatrix(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); }
public static ZpMatrix GetVandermondeMatrix(int rowNum, int colNum, int prime) { var A = new ZpMatrix(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] = Zp.Modulo(A.data[i - 1][j] * A.data[1][j], prime); } } return(A); }
/// <summary> /// Returns a Vandermonde matrix in the field (each element is modulu prime). /// </summary> public static ZpMatrix GetShamirRecombineMatrix(int matrixSize, int prime) { var A = new ZpMatrix(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] = Zp.Modulo(A.data[i][j - 1] * A.data[i][1], prime); } } return(A); }
public ZpMatrix Times(ZpMatrix 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 ZpMatrix(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); }
public static ZpMatrix GetConcatenationMatrix(ZpMatrix A, ZpMatrix 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 ZpMatrix(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); }
/* 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 ZpMatrix GetTruncationMatrix(int matrixSize, int truncToSize, int prime) { var I = new ZpMatrix(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 ZpMatrix GetIdentityMatrix(int matrixSize, int prime) { var I = new ZpMatrix(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 ZpMatrix GetRandomMatrix(int rowNum, int colNum, int prime) { var A = new ZpMatrix(rowNum, colNum, prime); for (int i = 0; i < rowNum; i++) { for (int j = 0; j < colNum; j++) { A.data[i][j] = Zp.Modulo((int)(StaticRandom.NextDouble() * (prime)), prime); } } return(A); }
/* r - Array of row indices, j0 - Initial column index, j1 - Final column index * return A(r(:),j0:j1) */ private ZpMatrix GetSubMatrix(int[] r, int j0, int j1) { var X = new ZpMatrix(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 ZpMatrix MulMatrixByScalarsVector(int[] scalarsVector) { if (RowCount != scalarsVector.Length) { throw new ArgumentException("incompatible vector length and matrix row number."); } var B = new ZpMatrix(this); for (int i = 0; i < RowCount; i++) { B.MulRowByscalar(i, scalarsVector[i]); } return(B); }
public ZpMatrix GetSubMatrix(int r0, int r1, int c0, int c1) { var x = new ZpMatrix(r1 - r0 + 1, c1 - c0 + 1, Prime); var B = x.data; for (int i = r0; i <= r1; i++) { for (int j = c0; j <= c1; j++) { B[i - r0][j - c0] = data[i][j]; } } return(x); }
private ZpMatrix SolveInv(ZpMatrix B, int[] piv, int[] fieldInv) { 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] * fieldInv[data[k][k]]); } 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 bool Eq(ZpMatrix B) { var A = this; if ((B.RowCount != A.RowCount) || (B.ColCount != A.ColCount) || (A.Prime != B.Prime)) { return(false); } for (int i = 0; i < RowCount; i++) { for (int j = 0; j < ColCount; j++) { if (A.data[i][j] != B.data[i][j]) { return(false); } } } return(true); }
public static ZpMatrix GetPrimitiveVandermondeMatrix(int rowNum, int colNum, int prime) { int primitive = NumTheoryUtils.GetFieldMinimumPrimitive(prime); if (primitive == 0) { throw new ArgumentException("Cannot create a primitive Vandermonde matrix from a non-prime number. "); } var A = new ZpMatrix(rowNum, colNum, prime); for (int j = 0; j < colNum; j++) { A.data[0][j] = 1; } if (rowNum == 1) { return(A); } /* This variable represents primitive^j for the j-th player*/ int primitive_j = 1; for (int j = 0; j < colNum; j++) { A.data[1][j] = primitive_j; primitive_j = Zp.Modulo(primitive_j * primitive, prime); } for (int j = 0; j < colNum; j++) { for (int i = 2; i < rowNum; i++) { A.data[i][j] = Zp.Modulo(A.data[i - 1][j] * A.data[1][j], prime); } } return(A); }
public static ZpMatrix GetVandermondeMatrix(int rowNum, IList <Zp> values, int prime) { int colNum = values.Count; var A = new ZpMatrix(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] = Zp.Modulo(A.data[i - 1][j] * values[j].Value, prime); } } return(A); }
public Zp[] Solve(Zp[] vector) { var vecMatrix = new ZpMatrix(vector, VectorType.Column); return(Inverse.Times(vecMatrix).ZpVector); }
/// <summary> /// Returns x = (A^-1) b, assuming A is square and has full rank (not singular). /// </summary> public ZpMatrix Solve(ZpMatrix vec) { var revA = Inverse; return(revA.Times(vec)); }
private ZpMatrix GetLUDecomposition(int[] pivot, int[] fieldInv) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. var LU = new ZpMatrix(this); int[][] LUArr = LU.data; int[] piv = pivot; for (int i = 0; i < RowCount; i++) { piv[i] = i; } int pivsign = 1; int[] LUrowi; var LUcolj = new int[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); int 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++) { int 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 ZpMatrix(ZpMatrix A) : this(A.data, A.Prime) { }