예제 #1
0
        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);
        }
예제 #2
0
        /* 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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        /* 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);
        }
예제 #6
0
        /* 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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
 private BigZpMatrix(BigZpMatrix A)
     : this(A.data, A.Prime)
 {
 }