/// <summary>
        /// Procustes statistics which gives a (di)similiarity measure of two set of points, by removing translation, rotation and dilation(stretching) degrees of freedom.
        /// Zero as result means the two sets of points are basically the same after translation, rotation and dilation with the corresponding matrices.
        /// Reference: Modern Multidimensional Scaling, Theory and Applications, page 436, Procrustes Analysis
        /// </summary>
        /// <param name="A"></param>
        /// <param name="B"></param>
        /// <returns></returns>
        public static Tuple <String, double> ProcrustesStatistics(List <Point> A, List <Point> B)
        {
            int n = A.Count;
            //make A to be unitlength
            double minX = A.Min(p => p.X);
            double maxX = A.Max(p => p.X);
            double minY = A.Min(p => p.Y);
            double maxY = A.Max(p => p.Y);

            double deltaX = maxX - minX;
            double deltaY = maxY - minY;
            double scale  = Math.Max(deltaX, deltaY);


            A = A.Select(p => new Point(p.X / scale, p.Y / scale)).ToList();


            var centerA = new Point(A.Average(a => a.X), A.Average(a => a.Y));
            var centerB = new Point(B.Average(b => b.X), B.Average(b => b.Y));

            Matrix X = DenseMatrix.Create(n, 2, (i, j) => j == 0 ? A[i].X:A[i].Y);
            Matrix Y = DenseMatrix.Create(n, 2, (i, j) => j == 0 ? B[i].X:B[i].Y);

            Matrix Xc = DenseMatrix.Create(n, 2, (i, j) => j == 0 ? A[i].X - centerA.X : A[i].Y - centerA.Y);
            Matrix Yc = DenseMatrix.Create(n, 2, (i, j) => j == 0 ? B[i].X - centerB.X : B[i].Y - centerB.Y);

            //Reference: Modern Multidimensional Scaling, Theory and Applications, page 436, Procrustes Analysis
            DenseMatrix C = (DenseMatrix)(Xc.Transpose() * Y);

            Svd svd = new DenseSvd(C, true);
            //rotation
            Matrix <double> T = (svd.VT().Transpose()) * (svd.U().Transpose());
            //dilation
            double s = ((C * T).Trace()) / ((Yc.Transpose() * Y).Trace());
            //column Vector with n times 1
            Vector <double> vector1 = DenseVector.Create(n, i => 1);
            //translation vector
            Vector <double> t = (1.0 / n) * (X - s * Y * T).Transpose() * vector1;

            Matrix translationMatrix = DenseMatrix.Create(n, 2, (i, j) => t.At(j));

            Matrix <double> YPrime = s * Y * T + translationMatrix;
            Matrix <double> delta  = X - YPrime;

            double rSquare = 0;

            for (int i = 0; i < n; i++)
            {
                rSquare += delta.Row(i) * delta.Row(i);
            }
            return(Tuple.Create("ProcrustesStatistics", Math.Sqrt(rSquare)));
        }
        public void GenerateMatrix(List <UniqueWords> UniqueWordList)
        {
            double sum = 0;

            tfidfDocMatrix = new DenseMatrix(UniqueWordList.Count, DocumentInfo.TotalPages);
            //builds tf-idf document matrix
            for (int i = 0; i < UniqueWordList.Count; i++)
            {
                for (int j = 0; j < DocumentInfo.TotalPages; j++)
                {
                    if (UniqueWordList[i].PagenoWithFrequency.ContainsKey(j + 1))      //insert into matrix only if the key is present in the dictionary or else 0 is already initialised
                    {
                        int tf = UniqueWordList[i].PagenoWithFrequency[j + 1];

                        //calculating IDF
                        double idf = Math.Log10(Convert.ToDouble(DocumentInfo.TotalPages) / UniqueWordList[i].DocFrequency);
                        tfidfDocMatrix[i, j] = tf * idf;
                        //tfidfDocMatrix[i, j] = tfidfDocMatrix[i, j]/_eachPageWordCount[j];  //normalised TF.IDF matrix
                        tfidfDocMatrix[i, j] = Math.Round(tfidfDocMatrix[i, j], 2);
                    }
                }
            }


            //          WordnFrequencyTxtBox.AppendText(tfidfDocMatrix.ToMatrixString(UniqueWordList.Count, DocumentInfo.TotalPages));
            //for(int i=0;i<UniqueWordList.Count;i++)
            //{
            //    for (int j = 3; j < 4; j++)
            //    {
            //        sum += tfidfDocMatrix[i, j];
            //    }
            //}

            //WordnFrequencyTxtBox.AppendText(sum.ToString());
            // DenseMatrix dm=new DenseMatrix(tfidfDocMatrix);
            // Svd svd=new DenseSvd(dm,true);


            Svd svd = new DenseSvd(tfidfDocMatrix, true);
            //Matrix<double> s = svd.W();
            //Matrix<double> t = svd.U();
            //Matrix<double> d = svd.VT();
            //Matrix<double> tsd = t*s*d;
            //WordnFrequencyTxtBox.AppendText("\n" + "\n" + tfidfDocMatrix.ToString());
            //WordnFrequencyTxtBox.AppendText("\n"+"\n"+tsd.ToString());
            // WordnFrequencyTxtBox.AppendText("\n" + "\n" +s.ToString());



            Matrix <double> f = svd.U();

            Matrix <double> s = svd.W();

            Matrix <double> t   = svd.VT();
            Matrix <double> tc1 = t.Column(0).ToColumnMatrix();
            Matrix <double> tc2 = t.Column(1).ToColumnMatrix();
            //tc1.SetSubMatrix();

            Matrix <double> rorigi = f * s * t;

            // WordnFrequencyTxtBox.Clear();
            for (int i = 0; i < rorigi.RowCount; i++)
            {
                for (int j = 0; j < rorigi.ColumnCount; j++)
                {
                    int r;
                    if (rorigi[i, j].ToString().Contains("E"))      //insert into matrix only if the key is present in the dictionary or else 0 is already initialised
                    {
                        rorigi[i, j] = 0;
                    }
                }
            }
            //           WordnFrequencyTxtBox.AppendText("\n" + rorigi.ToString());
            //           WordnFrequencyTxtBox.AppendText("\n" + tfidfDocMatrix.ToString());
        }