/// <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 virtual Polynomial multiply(Polynomial p) { Debug.Assert(Degree > p.Degree && Coefficients.Count > 0); int prime = Coefficients[0].Prime; var coeffs = new SortedDictionary <int, Zp>(); for (int deg1 = 0; deg1 <= Degree; deg1++) { for (int deg2 = 0; deg2 <= p.Degree; deg2++) { int deg = deg1 + deg2; var curr = coeffs[deg]; var newValue = new Zp(prime, Coefficients[deg1].Value * p.Coefficients[deg2].Value); if (curr == null) { curr = newValue; } else { curr = new Zp(prime, curr.Value + newValue.Value); } coeffs[deg] = curr; } } return(new Polynomial(new List <Zp>(coeffs.Values))); }
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); }
public void SetMatrixCell(int rowNumber, int colNumber, Zp value) { if ((RowCount <= rowNumber) || (ColCount <= colNumber)) { throw new ArgumentException("Illegal matrix cell."); } data[rowNumber][colNumber] = value.Value; }
public virtual Polynomial divideWithRemainder(Polynomial p) { if (Coefficients.Count == 0 || p.Coefficients.Count == 0) { return(null); //null } var answer = new Polynomial[2]; int prime = Coefficients[0].Prime; int m = Degree; int n = p.Degree; if (m < n) { return(null); } var quotient = new Zp[m - n + 1]; var coeffs = new Zp[m + 1]; for (int k = 0; k <= m; k++) { coeffs[k] = new Zp(Coefficients[k]); } var norm = p.Coefficients[n].MultipInverse; for (int k = m - n; k >= 0; k--) { quotient[k] = new Zp(prime, coeffs[n + k].Value * norm.Value); for (int j = n + k - 1; j >= k; j--) { coeffs[j] = new Zp(prime, coeffs[j].Value - quotient[k].Value * p.Coefficients[j - k].Value); } } var remainder = new Zp[n]; for (int k = 0; k < n; k++) { remainder[k] = new Zp(coeffs[k]); } answer[0] = new Polynomial(quotient); answer[1] = new Polynomial(remainder); foreach (Zp zp in answer[1].Coefficients) { if (zp.Value != 0) { return(null); } } return(answer[0]); }
/// <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); }
/// <summary> /// TODO: Performance improvement: This is a naive soultion, find a better solution from the web </summary> /// <returns> the roots of the polynom (comparing the polynom to 0). </returns> public virtual List <Zp> GetRoots() { var SolutionsList = new List <Zp>(); /* BF - go over all the items in the field. and check if they solve the poly */ for (int i = 0; i < CoefficinesFieldSize; i++) { var CurrentSamplePoint = new Zp(CoefficinesFieldSize, i); if (this.Sample(CurrentSamplePoint).Value == 0) { SolutionsList.Add(CurrentSamplePoint); } } return(SolutionsList); }
public Zp[] SumMatrixRows() { var sum = new int[ColCount]; for (int i = 0; i < RowCount; i++) { for (int j = 0; j < ColCount; j++) { sum[j] += data[i][j]; } } var zpSum = new Zp[ColCount]; for (int j = 0; j < ColCount; j++) { zpSum[j] = new Zp(Prime, sum[j]); } return(zpSum); }
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); }
public int Determinant() { if ((RowCount == 1) && (ColCount == 1)) { return(data[0][0]); } var det = new Zp(Prime, 0); for (int i = 0; i < ColCount; i++) { int SubDet = RemoveRowFromMatrix(0).RemoveColFromMatrix(i).Determinant(); var SubDetAi = new Zp(Prime, SubDet * data[0][i]); if (i % 2 == 0) { det.Add(SubDetAi); } else { det.Sub(SubDetAi); } } return(det.Value); }
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); }
/* calculate i mod prime */ private int Modulo(int i) { return(Zp.Modulo(i, Prime)); }