/// <summary> /// Classical Multidimensional Scaling /// </summary> public MDS() { // creates distance matrix int size = CityDistance.GetLength(0); CvMat t = new CvMat(size, size, MatrixType.F64C1, CityDistance); // adds Torgerson's additive constant to t t += Torgerson(t); // squares all elements of t t.Mul(t, t); // centering matrix G CvMat g = CenteringMatrix(size); // calculates inner product matrix B CvMat b = g * t * g.T() * -0.5; // calculates eigenvalues and eigenvectors of B CvMat vectors = new CvMat(size, size, MatrixType.F64C1); CvMat values = new CvMat(size, 1, MatrixType.F64C1); Cv.EigenVV(b, vectors, values); for (int r = 0; r < values.Rows; r++) { if (values[r] < 0) { values[r] = 0; } } // multiplies sqrt(eigenvalue) by eigenvector CvMat result = vectors.GetRows(0, 2); for (int r = 0; r < result.Rows; r++) { for (int c = 0; c < result.Cols; c++) { result[r, c] *= Math.Sqrt(values[r]); } } // scaling Cv.Normalize(result, result, 0, 800, NormType.MinMax); //Console.WriteLine(vectors); //Console.WriteLine(values); //Console.WriteLine(result); // opens a window using (IplImage img = new IplImage(800, 600, BitDepth.U8, 3)) using (CvFont font = new CvFont(FontFace.HersheySimplex, 0.5f, 0.5f)) using (CvWindow window = new CvWindow("City Location Estimation")) { img.Zero(); for (int c = 0; c < size; c++) { double x = result[0, c]; double y = result[1, c]; x = x * 0.7 + img.Width * 0.1; y = y * 0.7 + img.Height * 0.1; img.Circle((int)x, (int)y, 5, CvColor.Red, -1); img.PutText(CityNames[c], new CvPoint((int)x + 5, (int)y + 10), font, CvColor.White); } window.Image = img; Cv.WaitKey(); } }