Implements some number-theoretic utility functions.
Beispiel #1
0
        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);
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        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);
        }