public int Gauss() { int[] invArr = NumTheoryUtils.GetFieldInverse(Prime); // Gaussian elimination with partial pivoting int i, j; i = j = 0; while ((i < RowCount) && (j < ColCount - 1)) { // find pivot row and swap int max = i; for (int k = i + 1; k < RowCount; k++) { if (data[k][j] > data[max][j]) { max = k; } } if (data[max][j] != 0) { SwapRows(i, max); int toMul = invArr[data[i][j]]; for (int k = 0; k < ColCount; k++) { data[i][k] = Modulo(data[i][k] * toMul); } for (int u = i + 1; u < RowCount; u++) { int m = Modulo(data[u][j]); for (int v = 0; v < ColCount; v++) { data[u][v] = Modulo(data[u][v] - data[i][v] * m); } data[u][j] = 0; } i++; } j++; } // Get number of lines differrent from zero int num = 0; for (int k = 0; k < RowCount; k++) { for (int v = 0; v < ColCount; v++) { if (data[k][v] != 0) { num++; break; } } } return(num); }
public static Zp EvalutePolynomialAtPoint(IList <Zp> polynomial, Zp point) { int evaluation = 0; for (int i = 0; i < polynomial.Count; i++) { evaluation += polynomial[i].Value * NumTheoryUtils.ModPow(point.Value, i, point.Prime); } return(new Zp(point.Prime, evaluation)); }
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 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); }
/// <param name="SamplePoint"> - the desired sampling point. </param> /// <returns> the result of the polynom when replacing variable ("x") with the sampling point </returns> public virtual Zp Sample(Zp SamplePoint) { if (Coefficients.Count == 0) { return(null); } /* The initialized sum is 0 */ var Sum = new Zp(CoefficinesFieldSize, 0); for (int i = 0; i < Coefficients.Count; i++) { /* replace each "Ai*x^i" with "Ai*SamplePoint^i" */ var Xi = new Zp(CoefficinesFieldSize, NumTheoryUtils.ModPow(SamplePoint.Value, i, CoefficinesFieldSize)); var Ai = new Zp(CoefficinesFieldSize, Coefficients[i].Value); var AiXi = Xi.Mul(Ai); /* Sum all these values(A0+A1X^1+...AnX^n) */ Sum = Sum.Add(AiXi); } return(Sum); }
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); }