Changeset 10108
- Timestamp:
- 11/05/13 23:04:16 (11 years ago)
- Location:
- branches/HeuristicLab.Analysis.AlgorithmBehavior
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj
r10104 r10108 36 36 </PropertyGroup> 37 37 <ItemGroup> 38 <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 39 <SpecificVersion>False</SpecificVersion> 40 <HintPath>..\..\..\trunk\sources\bin\ALGLIB-3.7.0.dll</HintPath> 41 </Reference> 38 42 <Reference Include="HeuristicLab.Common-3.3"> 39 43 <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath> -
branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/DistanceMatrixToPointsTest.cs
r10078 r10108 22 22 using System; 23 23 using HeuristicLab.Analysis.AlgorithmBehavior.Analyzers; 24 using HeuristicLab.Common; 24 25 using Microsoft.VisualStudio.TestTools.UnitTesting; 25 26 … … 28 29 public class DistanceMatrixToPointsTest { 29 30 [TestMethod] 30 public void TestDistanceMatrixConversion () {31 int nrOfPoints = 4;31 public void TestDistanceMatrixConversionStatic() { 32 int nrOfPoints = 3; 32 33 int dim = 2; 33 34 double[][] orgPoints = new double[nrOfPoints][]; … … 36 37 double[][] newPoints = null; 37 38 38 39 39 AllocArray(orgPoints, dim); 40 40 AllocArray(orgDm, nrOfPoints); 41 41 AllocArray(newDm, nrOfPoints); 42 SamplePoints(orgPoints); 42 //SamplePoints(orgPoints); 43 StaticPoints(orgPoints); 43 44 CalculateDistanceMatrix(orgDm, orgPoints); 44 45 45 newPoints = DistanceMatrixToPoints. ConvertDistanceMatrixToPoints(orgDm);46 newPoints = DistanceMatrixToPoints.MetricMDS(orgDm); 46 47 47 48 CalculateDistanceMatrix(newDm, newPoints); 48 //TODO 49 Console.WriteLine("orgDm:"); 50 PrintDM(orgDm); 51 Console.WriteLine("newDm:"); 52 PrintDM(newDm); 49 53 54 for (int i = 0; i < orgDm.Length; i++) { 55 for (int j = 0; j < orgDm.Length; j++) { 56 double diff = orgDm[i][j] - newDm[i][j]; 57 Assert.IsTrue(diff.IsAlmost(0.0)); 58 } 59 } 60 } 61 62 private static void PrintDM(double[][] dm) { 63 for (int i = 0; i < dm.Length; i++) { 64 for (int j = 0; j < dm.Length; j++) { 65 Console.Write(dm[i][j] + " "); 66 } 67 Console.WriteLine(); 68 } 50 69 } 51 70 … … 60 79 } 61 80 81 private static void StaticPoints(double[][] points) { 82 points[0][0] = 2; 83 points[0][1] = 1; 84 85 points[1][0] = 5; 86 points[1][1] = 5; 87 88 points[2][0] = 3; 89 points[2][1] = 7; 90 } 91 62 92 private static void CalculateDistanceMatrix(double[][] dm, double[][] points) { 63 93 for (int i = 0; i < points.Length; i++) { 64 94 for (int j = 0; j < points.Length; j++) { 65 dm[i][j] = CalcEuclideanDistance(points[i],points[j]);95 dm[i][j] = points[i].EuclideanDistance(points[j]); 66 96 } 67 97 } 68 }69 70 private static double CalcEuclideanDistance(double[] p1, double[] p2) {71 double result = 0.0;72 for (int i = 0; i < p1.Length; i++) {73 result += Math.Pow(p1[i] - p2[i], 2);74 }75 return Math.Sqrt(result);76 98 } 77 99 -
branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/DistanceMatrixToPoints.cs
r10098 r10108 72 72 } 73 73 74 public static double[][] MetricMDS(double[][] dm) { 74 //based on R's cmdscale 75 public static double[][] MetricMDS(double[][] dm, int k = 2, bool add = false) { 75 76 double[][] points = new double[dm.Length][]; 76 double[,] a = new double[dm.Length, dm.Length];77 77 double[,] b = new double[dm.Length, dm.Length]; 78 double[] ai = new double[dm.Length]; 79 double[] aj = new double[dm.Length]; 80 double aavg = 0.0; 81 double[] q = new double[dm.Length]; 82 double[,] v = new double[dm.Length, dm.Length]; 78 double[] q; //eigenvalues 79 double[,] v; //eigenvectors 83 80 81 double[][] x = SquareMatrix(dm); 82 CenterMatrix(x); 83 ChangeSignAndHalve(x); 84 84 85 //TODO: optimize memory consumption 85 86 for (int i = 0; i < dm.Length; i++) { 86 87 for (int j = 0; j < dm.Length; j++) { 87 a[i, j] = -0.5 * Math.Pow(dm[i][j], 2); 88 aavg += a[i, j]; 88 b[i, j] = x[i][j]; 89 89 } 90 90 } 91 91 92 aavg /= dm.Length * dm.Length; 92 bool res = alglib.smatrixevd(b, dm.Length, 1, true, out q, out v); 93 if (!res) throw new Exception("Eigenvalue computation did not converge!"); 93 94 94 for (int i = 0; i < dm.Length; i++) { 95 ai[i] = dm[i].Average(); 96 } 97 98 for (int i = 0; i < dm.Length; i++) { 95 //TODO: this should also work without allocating memory for ev and evec 96 double[] ev = new double[k]; 97 double[][] evec = new double[dm.Length][]; 98 AllocArray(evec, k); 99 Array.Copy(q, q.Length - k, ev, 0, k); 100 for (int i = 0; i < k; i++) { 99 101 for (int j = 0; j < dm.Length; j++) { 100 aj[i] += dm[j][i]; 101 } 102 aj[i] /= dm.Length; 103 } 104 105 for (int i = 0; i < dm.Length; i++) { 106 for (int j = 0; j < dm.Length; j++) { 107 b[i, j] = a[i, j] - ai[i] - aj[j] + aavg; 102 evec[j][i] = v[j, i + (q.Length - k)]; 108 103 } 109 104 } 110 105 111 //TODO: check b for negative values and make it positiv 112 113 double[] tau; 114 double[,] r; 115 alglib.rmatrixqr(ref b, dm.Length, dm.Length, out tau); 116 alglib.rmatrixqrunpackr(b, dm.Length, dm.Length, out r); 117 118 bool res = alglib.smatrixevd(r, dm.Length, 1, true, out q, out v); 119 if (!res) throw new Exception("Eigenvalue computation did not converge!"); 120 121 int zeroCnt = q.Count(x => x.IsAlmost(0) || x < 0.0); 122 for (int i = 0; i < dm.Length; i++) { 123 points[i] = new double[dm.Length - zeroCnt]; 106 double k1 = SumIfLZero(ev); 107 if (k1 < k) { 108 throw new Exception("Zero-eigenvalues detected. This leads to a degenerate point set. Use constants. "); 109 //TODO: handling of this case; implement adding of constants 124 110 } 125 111 126 int pi = 0; 127 for (int i = 0; i < dm.Length; i++) { 128 if (!q[i].IsAlmost(0.0) && q[i] > 0.0) { 129 for (int j = 0; j < dm.Length; j++) { 130 points[j][pi] = Math.Sqrt(q[i]) * v[j, i]; 131 } 132 pi++; 112 AllocArray(points, k); 113 for (int i = 0; i < k; i++) { 114 for (int j = 0; j < dm.Length; j++) { 115 points[j][i] = Math.Sqrt(ev[i]) * evec[j][i]; 133 116 } 134 117 } 118 return points; 119 } 135 120 136 return points; 121 //TODO: refactor the following methods into something sane 122 private static double[][] SquareMatrix(double[][] a) { 123 int n = a.Length; 124 double[][] newA = new double[a.Length][]; 125 126 for (int i = 0; i < n; i++) { 127 newA[i] = new double[a.Length]; 128 for (int j = 0; j < n; j++) { 129 newA[i][j] = Math.Pow(a[i][j], 2.0); 130 } 131 } 132 return newA; 133 } 134 135 //based on R's DoubleCentre 136 private static void CenterMatrix(double[][] a) { 137 int n = a.Length; 138 139 //reduce lines by line avg 140 for (int i = 0; i < n; i++) { 141 double sum = 0; 142 for (int j = 0; j < n; j++) sum += a[i][j]; 143 sum /= n; 144 for (int j = 0; j < n; j++) a[i][j] -= sum; 145 } 146 147 //reduce cols by col avg 148 for (int j = 0; j < n; j++) { 149 double sum = 0; 150 for (int i = 0; i < n; i++) sum += a[i][j]; 151 sum /= n; 152 for (int i = 0; i < n; i++) a[i][j] -= sum; 153 } 154 } 155 156 private static void ChangeSignAndHalve(double[][] a) { 157 int n = a.Length; 158 159 for (int i = 0; i < n; i++) { 160 for (int j = 0; j < n; j++) { 161 a[i][j] = (-1.0 * a[i][j]) / 2; 162 } 163 } 164 } 165 166 private static double SumIfLZero(double[] a) { 167 return a.Where(x => x > 0.0 && !x.IsAlmost(0.0)).Sum(); 168 } 169 170 private static void AllocArray(double[][] arr, int size) { 171 for (int i = 0; i < arr.Length; i++) { 172 arr[i] = new double[size]; 173 } 137 174 } 138 175
Note: See TracChangeset
for help on using the changeset viewer.